You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

112 lines
3.3 KiB

#ifndef WORLEY_UTILITIES_H
#define WORLEY_UTILITIES_H
// Implementation inspired from https://www.shadertoy.com/view/3dVXDc
// Hash by David_Hoskins
#define UI0 1597334673U
#define UI1 3812015801U
#define UI2 uint2(UI0, UI1)
#define UI3 uint3(UI0, UI1, 2798796415U)
#define UIF (1.0 / float(0xffffffffU))
float3 hash33(float3 p)
{
uint3 q = uint3(int3(p)) * UI3;
q = (q.x ^ q.y ^ q.z) * UI3;
return -1. + 2. * float3(q) * UIF;
}
// Density remapping function
float remap(float x, float a, float b, float c, float d)
{
return (((x - a) / (b - a)) * (d - c)) + c;
}
// Gradient noise by iq (modified to be tileable)
float GradientNoise(float3 x, float freq)
{
// grid
float3 p = floor(x);
float3 w = frac(x);
// quintic interpolant
float3 u = w * w * w * (w * (w * 6. - 15.) + 10.);
// gradients
float3 ga = hash33(fmod(p + float3(0., 0., 0.), freq));
float3 gb = hash33(fmod(p + float3(1., 0., 0.), freq));
float3 gc = hash33(fmod(p + float3(0., 1., 0.), freq));
float3 gd = hash33(fmod(p + float3(1., 1., 0.), freq));
float3 ge = hash33(fmod(p + float3(0., 0., 1.), freq));
float3 gf = hash33(fmod(p + float3(1., 0., 1.), freq));
float3 gg = hash33(fmod(p + float3(0., 1., 1.), freq));
float3 gh = hash33(fmod(p + float3(1., 1., 1.), freq));
// projections
float va = dot(ga, w - float3(0., 0., 0.));
float vb = dot(gb, w - float3(1., 0., 0.));
float vc = dot(gc, w - float3(0., 1., 0.));
float vd = dot(gd, w - float3(1., 1., 0.));
float ve = dot(ge, w - float3(0., 0., 1.));
float vf = dot(gf, w - float3(1., 0., 1.));
float vg = dot(gg, w - float3(0., 1., 1.));
float vh = dot(gh, w - float3(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);
}
// There is a difference between the original implementation's mod and hlsl's fmod, so we mimic the glsl version for the algorithm
#define Modulo(x,y) (x-y*floor(x/y))
// Tileable 3D worley noise
float WorleyNoise(float3 uv, float freq)
{
float3 id = floor(uv);
float3 p = frac(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)
{
float3 offset = float3(x, y, z);
float3 idOffset = id + offset;
float3 h = hash33(Modulo(idOffset.xyz, freq)) * .5 + .5;
h += offset;
float3 d = p - h;
minDist = min(minDist, dot(d, d));
}
}
}
return minDist;
}
float EvaluatePerlinFractalBrownianMotion(float3 position, float initialFrequence, int numOctaves)
{
const float G = exp2(-0.85);
// Accumulation values
float amplitude = 1.0;
float frequence = initialFrequence;
float result = 0.0;
for (int i = 0; i < numOctaves; ++i)
{
result += amplitude * GradientNoise(position * frequence, frequence);
frequence *= 2.0;
amplitude *= G;
}
return result;
}
#endif // WORLEY_UTILITIES_H