MF_PerlinNoise_3D
- Exposure: public
- UE Version: 5.7
define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
define final(a, b, c) \
{ \ c ^= b; \ c -= rot(b, 14); \ a ^= c; \ a -= rot(c, 11); \ b ^= a; \ b -= rot(a, 25); \ c ^= b; \ c -= rot(b, 16); \ a ^= c; \ a -= rot(c, 4); \ b ^= a; \ b -= rot(a, 14); \ c ^= b; \ c -= rot(b, 24); \ }
define FLOORFRAC(x, x_int, x_fract) { float x_floor = floor(x); x_int = int(x_floor); x_fract = x - x_floor; }
struct MathBaseLib { float3 compatibleMod(float3 a, float b) { float3 result; result.x = compatibleMod(a.x, b); result.y = compatibleMod(a.y, b); result.z = compatibleMod(a.z, b); return result; } float compatibleMod(float a, float b) { if (b != 0.0f) { int N = (int)(a / b); return a - N * b; } else return 0.0f; } };
struct NoiseFunction { MathBaseLib mbl; float triMix(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float x, float y, float z) { float x1 = 1.0 - x; float y1 = 1.0 - y; float z1 = 1.0 - z; return z1 (y1 (v0 x1 + v1 x) + y (v2 x1 + v3 x)) + z (y1 (v4 x1 + v5 x) + y (v6 x1 + v7 x)); } float fade(float t) { return t t t (t (t * 6.0 - 15.0) + 10.0); } float negateIf(float value, uint condition) { return (condition != 0u) ? -value : value; } float noiseGrad(uint hash, float x, float y, float z) { uint h = hash & 15u; float u = h < 8u ? x : y; float vt = ((h ==12u) || (h == 14u)) ? x : z; float v = h < 4u ? y : vt; return negateIf(u, h & 1u) + negateIf(v, h & 2u); } float noisePerlin(float3 vec) { int X, Y, Z; float fx, fy, fz;
FLOORFRAC(vec.x, X, fx);
FLOORFRAC(vec.y, Y, fy);
FLOORFRAC(vec.z, Z, fz);
float u = fade(fx);
float v = fade(fy);
float w = fade(fz);
float r = triMix(noiseGrad(hashInt3(X, Y, Z), fx, fy, fz), noiseGrad(hashInt3(X + 1, Y, Z), fx - 1, fy, fz),
noiseGrad(hashInt3(X, Y + 1, Z), fx, fy - 1, fz), noiseGrad(hashInt3(X + 1, Y + 1, Z), fx - 1, fy - 1, fz),
noiseGrad(hashInt3(X, Y , Z + 1), fx, fy, fz - 1), noiseGrad(hashInt3(X + 1, Y, Z + 1), fx - 1, fy, fz - 1),
noiseGrad(hashInt3(X, Y + 1, Z +1), fx, fy - 1, fz - 1), noiseGrad(hashInt3(X + 1, Y + 1, Z +1), fx - 1, fy - 1, fz - 1),
u, v, w);
return r;
} float noiseScale3(float result) { return 0.9820f result; } float snoise(float3 p) { float3 precisionCorrection = 0.5 float3((float)(abs(p.x) >= 1000000.0), (float)(abs(p.y) >= 1000000.0), (float)(abs(p.z) >= 1000000.0));
p = mbl.compatibleMod(p, 100000.0) + precisionCorrection;
return noiseScale3(noisePerlin(p));
} float safeSnoise(float3 co) { float3 precisionCorrection = 0.5 * float3((float)(abs(co.x) >= 1000000.0), (float)(abs(co.y) >= 1000000.0), (float)(abs(co.z) >= 1000000.0)); float3 p = fmod(co, 100000.0) + precisionCorrection; return snoise(p); } uint hashUint2(uint kx, uint ky) { uint a,b,c; a = b = c = 0xdeadbeff + (4 << 2) + 13;
a += ky;
b += kx;
final(a, b, c);
return c;
} uint hashUint3(uint kx, uint ky, uint kz) { uint a, b, c; a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
c += kz; b += ky; a += kx; final(a, b, c);
return c; } uint hashInt3(int kx, int ky, int kz) { return hashUint3((uint)kx, (uint)ky, (uint)kz); } float hashUint2ToFloat(uint kx, uint ky) { return float(hashUint2(kx, ky) / float(0xFFFFFFFFu)); } float hashVec2ToFloat(float2 k) { return hashUint2ToFloat(asuint(k.x), asuint(k.y)); } float3 randomVector3Offset(float seed) { return float3(100 + hashVec2ToFloat(float2(seed, 0)) 100, 100 + hashVec2ToFloat(float2(seed, 1)) 100,100 + hashVec2ToFloat(float2(seed, 2)) * 100); } float noiseFbm(float3 co, float detail, float roughness, float lacunarity, int useNormalize) { float3 p = co; float fscale = 1.0; float amp = 1.0; float maxamp = 0.0; float sum = 0.0;
for (int i = 0; i <= (int)detail; i++)
{
float t = safeSnoise(fscale * p);
sum += t * amp;
maxamp += amp;
amp *= roughness;
fscale *= lacunarity;
}
float rmd = frac(detail);
if (rmd != 0)
{
float t = safeSnoise(fscale * p);
float sum2 = sum + t * amp;
return (useNormalize == 1) ? lerp(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) : lerp(sum, sum2, rmd);
}
else
return (useNormalize == 1) ? (0.5 * sum / maxamp + 0.5) : sum;
} };
//main NoiseFunction nf; float3 color = 0; color.r = nf.noiseFbm(coord, detail, roughness, lacunarity, normalize); color.g = nf.noiseFbm(coord + nf.randomVector3Offset(3.0), detail, roughness, lacunarity, normalize); color.b = nf.noiseFbm(coord + nf.randomVector3Offset(4.0), detail, roughness, lacunarity, normalize); Color = color; return color.r;
ctrl + v
1 comment
-
define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
define final(a, b, c) \
{ \ c ^= b; \ c -= rot(b, 14); \ a ^= c; \ a -= rot(c, 11); \ b ^= a; \ b -= rot(a, 25); \ c ^= b; \ c -= rot(b, 16); \ a ^= c; \ a -= rot(c, 4); \ b ^= a; \ b -= rot(a, 14); \ c ^= b; \ c -= rot(b, 24); \ }
define FLOORFRAC(x, x_int, x_fract) { float x_floor = floor(x); x_int = int(x_floor); x_fract = x - x_floor; }
struct MathBaseLib { float3 compatibleMod(float3 a, float b) { float3 result; result.x = compatibleMod(a.x, b); result.y = compatibleMod(a.y, b); result.z = compatibleMod(a.z, b); return result; } float compatibleMod(float a, float b) { if (b != 0.0f) { int N = (int)(a / b); return a - N * b; } else return 0.0f; } };
struct NoiseFunction { MathBaseLib mbl; float triMix(float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float x, float y, float z) { float x1 = 1.0 - x; float y1 = 1.0 - y; float z1 = 1.0 - z; return z1 (y1 (v0 x1 + v1 x) + y (v2 x1 + v3 x)) + z (y1 (v4 x1 + v5 x) + y (v6 x1 + v7 x)); } float fade(float t) { return t t t (t (t * 6.0 - 15.0) + 10.0); } float negateIf(float value, uint condition) { return (condition != 0u) ? -value : value; } float noiseGrad(uint hash, float x, float y, float z) { uint h = hash & 15u; float u = h < 8u ? x : y; float vt = ((h ==12u) || (h == 14u)) ? x : z; float v = h < 4u ? y : vt; return negateIf(u, h & 1u) + negateIf(v, h & 2u); } float noisePerlin(float3 vec) { int X, Y, Z; float fx, fy, fz;
FLOORFRAC(vec.x, X, fx); FLOORFRAC(vec.y, Y, fy); FLOORFRAC(vec.z, Z, fz); float u = fade(fx); float v = fade(fy); float w = fade(fz); float r = triMix(noiseGrad(hashInt3(X, Y, Z), fx, fy, fz), noiseGrad(hashInt3(X + 1, Y, Z), fx - 1, fy, fz), noiseGrad(hashInt3(X, Y + 1, Z), fx, fy - 1, fz), noiseGrad(hashInt3(X + 1, Y + 1, Z), fx - 1, fy - 1, fz), noiseGrad(hashInt3(X, Y , Z + 1), fx, fy, fz - 1), noiseGrad(hashInt3(X + 1, Y, Z + 1), fx - 1, fy, fz - 1), noiseGrad(hashInt3(X, Y + 1, Z +1), fx, fy - 1, fz - 1), noiseGrad(hashInt3(X + 1, Y + 1, Z +1), fx - 1, fy - 1, fz - 1), u, v, w); return r;} float noiseScale3(float result) { return 0.9820f result; } float snoise(float3 p) { float3 precisionCorrection = 0.5 float3((float)(abs(p.x) >= 1000000.0), (float)(abs(p.y) >= 1000000.0), (float)(abs(p.z) >= 1000000.0));
p = mbl.compatibleMod(p, 100000.0) + precisionCorrection; return noiseScale3(noisePerlin(p));} float safeSnoise(float3 co) { float3 precisionCorrection = 0.5 * float3((float)(abs(co.x) >= 1000000.0), (float)(abs(co.y) >= 1000000.0), (float)(abs(co.z) >= 1000000.0)); float3 p = fmod(co, 100000.0) + precisionCorrection; return snoise(p); } uint hashUint2(uint kx, uint ky) { uint a,b,c; a = b = c = 0xdeadbeff + (4 << 2) + 13;
a += ky; b += kx; final(a, b, c); return c;} uint hashUint3(uint kx, uint ky, uint kz) { uint a, b, c; a = b = c = 0xdeadbeefu + (3u << 2u) + 13u;
c += kz; b += ky; a += kx; final(a, b, c);
return c; } uint hashInt3(int kx, int ky, int kz) { return hashUint3((uint)kx, (uint)ky, (uint)kz); } float hashUint2ToFloat(uint kx, uint ky) { return float(hashUint2(kx, ky) / float(0xFFFFFFFFu)); } float hashVec2ToFloat(float2 k) { return hashUint2ToFloat(asuint(k.x), asuint(k.y)); } float3 randomVector3Offset(float seed) { return float3(100 + hashVec2ToFloat(float2(seed, 0)) 100, 100 + hashVec2ToFloat(float2(seed, 1)) 100,100 + hashVec2ToFloat(float2(seed, 2)) * 100); } float noiseFbm(float3 co, float detail, float roughness, float lacunarity, int useNormalize) { float3 p = co; float fscale = 1.0; float amp = 1.0; float maxamp = 0.0; float sum = 0.0;
for (int i = 0; i <= (int)detail; i++) { float t = safeSnoise(fscale * p); sum += t * amp; maxamp += amp; amp *= roughness; fscale *= lacunarity; } float rmd = frac(detail); if (rmd != 0) { float t = safeSnoise(fscale * p); float sum2 = sum + t * amp; return (useNormalize == 1) ? lerp(0.5 * sum / maxamp + 0.5, 0.5 * sum2 / (maxamp + amp) + 0.5, rmd) : lerp(sum, sum2, rmd); } else return (useNormalize == 1) ? (0.5 * sum / maxamp + 0.5) : sum;} };
//main NoiseFunction nf; float3 color = 0; color.r = nf.noiseFbm(coord, detail, roughness, lacunarity, normalize); color.g = nf.noiseFbm(coord + nf.randomVector3Offset(3.0), detail, roughness, lacunarity, normalize); color.b = nf.noiseFbm(coord + nf.randomVector3Offset(4.0), detail, roughness, lacunarity, normalize); Color = color; return color.r;
XavierPan
December 14, 2025, 2:02 pm