LumixEngine/data/pipelines/clouds_noise.shd
2020-09-09 15:54:50 +02:00

173 lines
No EOL
4.4 KiB
Text

include "pipelines/common.glsl"
compute_shader [[
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout (rgba32f, binding = 0) uniform writeonly image3D u_output;
#define UI0 1597334673U
#define UI1 3812015801U
#define UI2 uvec2(UI0, UI1)
#define UI3 uvec3(UI0, UI1, 2798796415U)
#define UIF (1.0 / float(0xffffffffU))
vec3 hash33(vec3 p)
{
uvec3 q = uvec3(ivec3(p)) * UI3;
q = (q.x ^ q.y ^ q.z)*UI3;
return -1. + 2. * vec3(q) * UIF;
}
float remap( float value, float inMin, float inMax, float outMin, float outMax )
{
float mappedValue = value;
if ( ( inMax - inMin ) == 0.0f )
{
mappedValue = ( outMax + outMin ) * 0.5f;
}
else
{
mappedValue = outMin + ( ( ( mappedValue - inMin ) / ( inMax - inMin ) ) * ( outMax - outMin ) );
}
return mappedValue;
}
float perlin(vec3 p)
{
vec3 pi = floor(p);
vec3 pf = p - pi;
vec3 w = pf * pf * (3.0 - 2.0 * pf);
return mix(
mix(
mix(dot(pf - vec3(0, 0, 0), hash33(pi + vec3(0, 0, 0))),
dot(pf - vec3(1, 0, 0), hash33(pi + vec3(1, 0, 0))),
w.x),
mix(dot(pf - vec3(0, 0, 1), hash33(pi + vec3(0, 0, 1))),
dot(pf - vec3(1, 0, 1), hash33(pi + vec3(1, 0, 1))),
w.x),
w.z),
mix(
mix(dot(pf - vec3(0, 1, 0), hash33(pi + vec3(0, 1, 0))),
dot(pf - vec3(1, 1, 0), hash33(pi + vec3(1, 1, 0))),
w.x),
mix(dot(pf - vec3(0, 1, 1), hash33(pi + vec3(0, 1, 1))),
dot(pf - vec3(1, 1, 1), hash33(pi + vec3(1, 1, 1))),
w.x),
w.z),
w.y);
}
float worley(vec3 uv)
{
vec3 id = floor(uv);
vec3 p = fract(uv);
float minDist = 10000.;
for (float x = -1.; x <= 1.; ++x)
{
for(float y = -1.; y <= 1.; ++y)
{
for(float z = -1.; z <= 1.; ++z)
{
vec3 offset = vec3(x, y, z);
vec3 h = hash33(id + offset) * .5 + .5;
h += offset;
vec3 d = p - h;
minDist = min(minDist, dot(d, d));
}
}
}
// inverted worley noise
return 1. - minDist;
}
float gradientNoise(vec3 x, float freq)
{
// grid
vec3 p = floor(x);
vec3 w = fract(x);
// quintic interpolant
vec3 u = w * w * w * (w * (w * 6. - 15.) + 10.);
// gradients
vec3 ga = hash33(mod(p + vec3(0., 0., 0.), freq));
vec3 gb = hash33(mod(p + vec3(1., 0., 0.), freq));
vec3 gc = hash33(mod(p + vec3(0., 1., 0.), freq));
vec3 gd = hash33(mod(p + vec3(1., 1., 0.), freq));
vec3 ge = hash33(mod(p + vec3(0., 0., 1.), freq));
vec3 gf = hash33(mod(p + vec3(1., 0., 1.), freq));
vec3 gg = hash33(mod(p + vec3(0., 1., 1.), freq));
vec3 gh = hash33(mod(p + vec3(1., 1., 1.), freq));
// projections
float va = dot(ga, w - vec3(0., 0., 0.));
float vb = dot(gb, w - vec3(1., 0., 0.));
float vc = dot(gc, w - vec3(0., 1., 0.));
float vd = dot(gd, w - vec3(1., 1., 0.));
float ve = dot(ge, w - vec3(0., 0., 1.));
float vf = dot(gf, w - vec3(1., 0., 1.));
float vg = dot(gg, w - vec3(0., 1., 1.));
float vh = dot(gh, w - vec3(1., 1., 1.));
// interpolation
return va +
u.x * (vb - va) +
u.y * (vc - va) +
u.z * (ve - va) +
u.x * u.y * (va - vb - vc + vd) +
u.y * u.z * (va - vc - ve + vg) +
u.z * u.x * (va - vb - ve + vf) +
u.x * u.y * u.z * (-va + vb + vc - vd + ve - vf - vg + vh);
}
float perlinFbm(vec3 p, float freq, int octaves)
{
float G = exp2(-.85);
float amp = 1.;
float noise = 0.;
for (int i = 0; i < octaves; ++i)
{
noise += amp * gradientNoise(p * freq, freq);
freq *= 2.;
amp *= G;
}
return noise;
}
void main() {
vec3 p = vec3(gl_GlobalInvocationID) / 128.0;
float pfbm = 0.5 + 0.5 * perlinFbm(p, 4, 7);
//pfbm = abs(pfbm * 2 - 1);
float pw;
{
float w0 = worley(p * 2);
float w1 = worley(p * 8);
float w2 = worley(p * 14);
float wfbm = w0 * 0.625 + w1 * 0.25 + w2 * 0.125;
pw = remap(pfbm, 0, 1.0, wfbm, 1.0); // perlin-worley
}
float w0 = worley(p * 2);
float w1 = worley(p * 4);
float w2 = worley(p * 8);
float w3 = worley(p * 16);
float w4 = worley(p * 32);
float w0fbm = w0 * 0.625 + w1 * 0.25 + w2 * 0.125;
float w1fbm = w1 * 0.625 + w2 * 0.25 + w3 * 0.125;
float w2fbm = w2 * 0.625 + w3 * 0.25 + w4 * 0.125;
imageStore(u_output, ivec3(gl_GlobalInvocationID.xyz), vec4(pw, w0fbm, w1fbm, w2fbm));
}
]]