// ============================================================================= // Noises.hlsl – Unity URP/HDRP Custom Function Noise Library // All noise functions return values in [0, 1] // Usage: #include "Noises.hlsl" // ============================================================================= #ifndef NOISES_HLSL #define NOISES_HLSL // ============================================================================= // INTERNAL UTILITIES // ============================================================================= // --- Hash (PCG – integer bit mixing, no periodicity) ------------------------- // Converts float cell coords to uint, runs PCG rounds, outputs [0, 1] uint PcgHash(uint v) { v = v * 747796405u + 2891336453u; v = ((v >> ((v >> 28u) + 4u)) ^ v) * 277803737u; return (v >> 22u) ^ v; } float Hash1From2D(float2 p) { uint2 u = uint2(int2(p)); uint h = PcgHash(u.x ^ PcgHash(u.y)); return float(h) * (1.0 / 4294967296.0); } float2 Hash2D(float2 p) { uint2 u = uint2(int2(p)); uint hx = PcgHash(u.x ^ PcgHash(u.y)); uint hy = PcgHash(u.y ^ PcgHash(u.x + 1u)); return float2(hx, hy) * (1.0 / 4294967296.0); } float Hash1From3D(float3 p) { uint3 u = uint3(int3(p)); uint h = PcgHash(u.x ^ PcgHash(u.y ^ PcgHash(u.z))); return float(h) * (1.0 / 4294967296.0); } float3 Hash3D(float3 p) { uint3 u = uint3(int3(p)); uint hx = PcgHash(u.x ^ PcgHash(u.y ^ PcgHash(u.z))); uint hy = PcgHash(u.y ^ PcgHash(u.z ^ PcgHash(u.x + 1u))); uint hz = PcgHash(u.z ^ PcgHash(u.x ^ PcgHash(u.y + 1u))); return float3(hx, hy, hz) * (1.0 / 4294967296.0); } // --- Interpolation ----------------------------------------------------------- float2 SmootherStep2D(float2 t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); } float3 SmootherStep3D(float3 t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); } // --- Gradient ---------------------------------------------------------------- float Grad2D(float2 hash, float2 delta) { return dot(hash * 2.0 - 1.0, delta); } float Grad3D(float3 hash, float3 delta) { return dot(hash * 2.0 - 1.0, delta); } // --- LOD blend --------------------------------------------------------------- // Shared logic for all 3D LOD variants. // Returns scale0/scale1 to sample and w0/w1 weights (w0 + w1 == 1). void LODBlend(float3 PositionWS, float Scale, float LODRatio, out float scale0, out float scale1, out float w0, out float w1) { float logStep = log(LODRatio); float dist = max(distance(_WorldSpaceCameraPos.xyz, PositionWS), 0.0001); float t = log(dist / 1.0) / logStep; float tFloor = floor(t); float u = t - tFloor; scale0 = Scale * pow(LODRatio, -tFloor); scale1 = Scale * pow(LODRatio, -(tFloor + 1.0)); w1 = u * u * u * (u * (u * 6.0 - 15.0) + 10.0); w0 = 1.0 - w1; } // ============================================================================= // WHITE NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float WhiteNoise2D( float2 UV) // Input UV coordinates { return Hash1From2D(UV); } void WhiteNoise2D_float(float2 UV, out float Out) { Out = WhiteNoise2D(UV); } // --- 3D ---------------------------------------------------------------------- float WhiteNoise3D( float3 Position) // Input position in object space { return Hash1From3D(Position); } void WhiteNoise3D_float(float3 Position, out float Out) { Out = WhiteNoise3D(Position); } // ============================================================================= // VALUE NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float ValueNoise2D( float2 UV, // Input UV coordinates float Scale) // Noise frequency { float2 p = UV * Scale; float2 cell = floor(p); float2 local = frac(p); float2 smooth = SmootherStep2D(local); float v00 = Hash1From2D(cell + float2(0, 0)); float v10 = Hash1From2D(cell + float2(1, 0)); float v01 = Hash1From2D(cell + float2(0, 1)); float v11 = Hash1From2D(cell + float2(1, 1)); return lerp(lerp(v00, v10, smooth.x), lerp(v01, v11, smooth.x), smooth.y); } void ValueNoise2D_float(float2 UV, float Scale, out float Out) { Out = ValueNoise2D(UV, Scale); } // --- 3D ---------------------------------------------------------------------- float ValueNoise3D( float3 Position, // Input position in object space float Scale) // Noise frequency { float3 p = Position * Scale; float3 cell = floor(p); float3 local = frac(p); float3 smooth = SmootherStep3D(local); float v000 = Hash1From3D(cell + float3(0, 0, 0)); float v100 = Hash1From3D(cell + float3(1, 0, 0)); float v010 = Hash1From3D(cell + float3(0, 1, 0)); float v110 = Hash1From3D(cell + float3(1, 1, 0)); float v001 = Hash1From3D(cell + float3(0, 0, 1)); float v101 = Hash1From3D(cell + float3(1, 0, 1)); float v011 = Hash1From3D(cell + float3(0, 1, 1)); float v111 = Hash1From3D(cell + float3(1, 1, 1)); float x0 = lerp(v000, v100, smooth.x); float x1 = lerp(v010, v110, smooth.x); float x2 = lerp(v001, v101, smooth.x); float x3 = lerp(v011, v111, smooth.x); return lerp(lerp(x0, x1, smooth.y), lerp(x2, x3, smooth.y), smooth.z); } void ValueNoise3D_float(float3 Position, float Scale, out float Out) { Out = ValueNoise3D(Position, Scale); } // --- 3D LOD ------------------------------------------------------------------ float ValueNoise3DLOD( float3 PositionWS, // Surface position in world space float3 PositionOS, // Surface position in world space float Scale, // Noise frequency at reference distance float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return ValueNoise3D(PositionOS, scale0) * w0 + ValueNoise3D(PositionOS, scale1) * w1; } void ValueNoise3DLOD_float(float3 PositionWS, float Scale, float LODRatio, out float Out) { Out = ValueNoise3DLOD(PositionWS, PositionWS, Scale, LODRatio); } // ============================================================================= // PERLIN NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float PerlinNoise2D( float2 UV, // Input UV coordinates float Scale) // Noise frequency { float2 p = UV * Scale; float2 cell = floor(p); float2 local = frac(p); float2 smooth = SmootherStep2D(local); float g00 = Grad2D(Hash2D(cell + float2(0, 0)), local - float2(0, 0)); float g10 = Grad2D(Hash2D(cell + float2(1, 0)), local - float2(1, 0)); float g01 = Grad2D(Hash2D(cell + float2(0, 1)), local - float2(0, 1)); float g11 = Grad2D(Hash2D(cell + float2(1, 1)), local - float2(1, 1)); float result = lerp(lerp(g00, g10, smooth.x), lerp(g01, g11, smooth.x), smooth.y); return result * 0.5 + 0.5; } void PerlinNoise2D_float(float2 UV, float Scale, out float Out) { Out = PerlinNoise2D(UV, Scale); } // --- 3D ---------------------------------------------------------------------- float PerlinNoise3D( float3 Position, // Input position in object space float Scale) // Noise frequency { float3 p = Position * Scale; float3 cell = floor(p); float3 local = frac(p); float3 smooth = SmootherStep3D(local); float g000 = Grad3D(Hash3D(cell + float3(0,0,0)), local - float3(0,0,0)); float g100 = Grad3D(Hash3D(cell + float3(1,0,0)), local - float3(1,0,0)); float g010 = Grad3D(Hash3D(cell + float3(0,1,0)), local - float3(0,1,0)); float g110 = Grad3D(Hash3D(cell + float3(1,1,0)), local - float3(1,1,0)); float g001 = Grad3D(Hash3D(cell + float3(0,0,1)), local - float3(0,0,1)); float g101 = Grad3D(Hash3D(cell + float3(1,0,1)), local - float3(1,0,1)); float g011 = Grad3D(Hash3D(cell + float3(0,1,1)), local - float3(0,1,1)); float g111 = Grad3D(Hash3D(cell + float3(1,1,1)), local - float3(1,1,1)); float x0 = lerp(g000, g100, smooth.x); float x1 = lerp(g010, g110, smooth.x); float x2 = lerp(g001, g101, smooth.x); float x3 = lerp(g011, g111, smooth.x); float result = lerp(lerp(x0, x1, smooth.y), lerp(x2, x3, smooth.y), smooth.z); return result * 0.5 + 0.5; } void PerlinNoise3D_float(float3 Position, float Scale, out float Out) { Out = PerlinNoise3D(Position, Scale); } // --- 3D Direction ------------------------------------------------------------ float3 PerlinColor3D( float3 Position, // Input position in object space float Scale) // Noise frequency { return float3( PerlinNoise3D(Position, Scale), PerlinNoise3D(Position + float3(127.1, 311.7, 74.7), Scale), PerlinNoise3D(Position + float3(269.5, 183.3, 246.1), Scale) ); } void PerlinColor3D_float(float3 Position, float Scale, out float3 Out) { Out = PerlinColor3D(Position, Scale); } // --- 3D LOD ------------------------------------------------------------------ float PerlinNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Noise frequency at reference distance float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return PerlinNoise3D(PositionWS, scale0) * w0 + PerlinNoise3D(PositionWS, scale1) * w1; } void PerlinNoise3DLOD_float(float3 PositionWS, float Scale, float LODRatio, out float Out) { Out = PerlinNoise3DLOD(PositionWS, Scale, LODRatio); } // ============================================================================= // SIMPLEX NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float SimplexNoise2D( float2 UV, // Input UV coordinates float Scale) // Noise frequency { const float F2 = 0.366025403; // (sqrt(3) - 1) / 2 const float G2 = 0.211324865; // (3 - sqrt(3)) / 6 float2 p = UV * Scale; float s = (p.x + p.y) * F2; float2 i = floor(p + s); float t = (i.x + i.y) * G2; float2 x0 = p - (i - t); float2 i1 = (x0.x > x0.y) ? float2(1, 0) : float2(0, 1); float2 x1 = x0 - i1 + G2; float2 x2 = x0 - 1.0 + 2.0 * G2; float3 m = max(0.5 - float3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0); m = m * m * m * m; float3 gx = float3(Grad2D(Hash2D(i), x0), Grad2D(Hash2D(i + i1), x1), Grad2D(Hash2D(i + float2(1,1)), x2)); return dot(m, gx) * 70.0 * 0.5 + 0.5; } void SimplexNoise2D_float(float2 UV, float Scale, out float Out) { Out = SimplexNoise2D(UV, Scale); } // --- 3D ---------------------------------------------------------------------- float SimplexNoise3D( float3 Position, // Input position in object space float Scale) // Noise frequency { const float F3 = 0.333333333; const float G3 = 0.166666667; float3 p = Position * Scale; float s = (p.x + p.y + p.z) * F3; float3 i = floor(p + s); float t = (i.x + i.y + i.z) * G3; float3 x0 = p - (i - t); float3 i1, i2; if (x0.x >= x0.y) { if (x0.y >= x0.z) { i1 = float3(1,0,0); i2 = float3(1,1,0); } else if (x0.x >= x0.z) { i1 = float3(1,0,0); i2 = float3(1,0,1); } else { i1 = float3(0,0,1); i2 = float3(1,0,1); } } else { if (x0.y < x0.z) { i1 = float3(0,0,1); i2 = float3(0,1,1); } else if (x0.x < x0.z) { i1 = float3(0,1,0); i2 = float3(0,1,1); } else { i1 = float3(0,1,0); i2 = float3(1,1,0); } } float3 x1 = x0 - i1 + G3; float3 x2 = x0 - i2 + 2.0 * G3; float3 x3 = x0 - 1.0 + 3.0 * G3; float4 m = max(0.6 - float4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m * m * m; float4 gx = float4(Grad3D(Hash3D(i), x0), Grad3D(Hash3D(i + i1), x1), Grad3D(Hash3D(i + i2), x2), Grad3D(Hash3D(i + float3(1,1,1)), x3)); return dot(m, gx) * 32.0 * 0.5 + 0.5; } void SimplexNoise3D_float(float3 Position, float Scale, out float Out) { Out = SimplexNoise3D(Position, Scale); } // --- 3D LOD ------------------------------------------------------------------ float SimplexNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Noise frequency at reference distance float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return SimplexNoise3D(PositionWS, scale0) * w0 + SimplexNoise3D(PositionWS, scale1) * w1; } void SimplexNoise3DLOD_float(float3 PositionWS, float Scale, float LODRatio, out float Out) { Out = SimplexNoise3DLOD(PositionWS, Scale, LODRatio); } // ============================================================================= // WORLEY / CELLULAR NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float WorleyNoise2D( float2 UV, // Input UV coordinates float Scale, // Noise frequency float Jitter) // Feature point randomness [0 = grid, 1 = random] { float2 p = UV * Scale; float2 cell = floor(p); float minD = 8.0; for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { float2 neighbor = cell + float2(x, y); float2 offset = neighbor + Hash2D(neighbor) * Jitter; minD = min(minD, distance(p, offset)); } return saturate(minD); } void WorleyNoise2D_float(float2 UV, float Scale, float Jitter, out float Out) { Out = WorleyNoise2D(UV, Scale, Jitter); } // --- 3D ---------------------------------------------------------------------- float WorleyNoise3D( float3 Position, // Input position in object space float Scale, // Noise frequency float Jitter) // Feature point randomness [0 = grid, 1 = random] { float3 p = Position * Scale; float3 cell = floor(p); float minD = 8.0; for (int z = -1; z <= 1; z++) for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { float3 neighbor = cell + float3(x, y, z); float3 offset = neighbor + Hash3D(neighbor) * Jitter; minD = min(minD, distance(p, offset)); } return saturate(minD); } void WorleyNoise3D_float(float3 Position, float Scale, float Jitter, out float Out) { Out = WorleyNoise3D(Position, Scale, Jitter); } // --- 3D LOD ------------------------------------------------------------------ float WorleyNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Noise frequency at reference distance float Jitter, // Feature point randomness [0 = grid, 1 = random] float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return WorleyNoise3D(PositionWS, scale0, Jitter) * w0 + WorleyNoise3D(PositionWS, scale1, Jitter) * w1; } void WorleyNoise3DLOD_float(float3 PositionWS, float Scale, float Jitter, float LODRatio, out float Out) { Out = WorleyNoise3DLOD(PositionWS, Scale, Jitter, LODRatio); } // ============================================================================= // VORONOI NOISE // ============================================================================= // --- 2D ---------------------------------------------------------------------- float VoronoiNoise2D( float2 UV, // Input UV coordinates float Scale, // Noise frequency float Jitter, // Feature point randomness [0 = grid, 1 = random] float CellBlend, // 0 = F1 distance, 1 = F2-F1 (border emphasis) out float CellID) // Unique ID of the nearest cell [0, 1] { float2 p = UV * Scale; float2 cell = floor(p); float minF1 = 8.0, minF2 = 8.0; float2 minCell = 0; for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { float2 neighbor = cell + float2(x, y); float2 offset = neighbor + Hash2D(neighbor) * Jitter; float d = distance(p, offset); if (d < minF1) { minF2 = minF1; minF1 = d; minCell = neighbor; } else if (d < minF2) { minF2 = d; } } CellID = Hash1From2D(minCell); return saturate(lerp(minF1, minF2 - minF1, CellBlend)); } void VoronoiNoise2D_float(float2 UV, float Scale, float Jitter, float CellBlend, out float Out, out float CellID) { Out = VoronoiNoise2D(UV, Scale, Jitter, CellBlend, CellID); } // --- 3D ---------------------------------------------------------------------- float VoronoiNoise3D( float3 Position, // Input position in object space float Scale, // Noise frequency float Jitter, // Feature point randomness [0 = grid, 1 = random] float CellBlend, // 0 = F1 distance, 1 = F2-F1 (border emphasis) out float CellID) // Unique ID of the nearest cell [0, 1] { float3 p = Position * Scale; float3 cell = floor(p); float minF1 = 8.0, minF2 = 8.0; float3 minCell = 0; for (int z = -1; z <= 1; z++) for (int y = -1; y <= 1; y++) for (int x = -1; x <= 1; x++) { float3 neighbor = cell + float3(x, y, z); float3 offset = neighbor + Hash3D(neighbor) * Jitter; float d = distance(p, offset); if (d < minF1) { minF2 = minF1; minF1 = d; minCell = neighbor; } else if (d < minF2) { minF2 = d; } } CellID = Hash1From3D(minCell); return saturate(lerp(minF1, minF2 - minF1, CellBlend)); } void VoronoiNoise3D_float(float3 Position, float Scale, float Jitter, float CellBlend, out float Out, out float CellID) { Out = VoronoiNoise3D(Position, Scale, Jitter, CellBlend, CellID); } // --- 3D LOD ------------------------------------------------------------------ // CellID is blended as a weighted average – loses sharp cell identity // across the transition zone, which is an acceptable tradeoff for LOD. float VoronoiNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Noise frequency at reference distance float Jitter, // Feature point randomness [0 = grid, 1 = random] float CellBlend, // 0 = F1 distance, 1 = F2-F1 (border emphasis) float LODRatio, // Scale ratio between layers (4 = wide transition) out float CellID) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); float cellID0, cellID1; float v0 = VoronoiNoise3D(PositionWS, scale0, Jitter, CellBlend, cellID0); float v1 = VoronoiNoise3D(PositionWS, scale1, Jitter, CellBlend, cellID1); CellID = cellID0 * w0 + cellID1 * w1; return v0 * w0 + v1 * w1; } void VoronoiNoise3DLOD_float(float3 PositionWS, float Scale, float Jitter, float CellBlend, float LODRatio, out float Out, out float CellID) { Out = VoronoiNoise3DLOD(PositionWS, Scale, Jitter, CellBlend, LODRatio, CellID); } // ============================================================================= // FBM (Fractal Brownian Motion) – built on Perlin // ============================================================================= // --- 2D ---------------------------------------------------------------------- float FBMNoise2D( float2 UV, // Input UV coordinates float Scale, // Base noise frequency int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain) // Amplitude multiplier per octave (typically 0.5) { float value = 0.0; float amplitude = 0.5; float frequency = Scale; float maxValue = 0.0; for (int i = 0; i < Octaves; i++) { value += PerlinNoise2D(UV, frequency) * amplitude; maxValue += amplitude; amplitude *= Gain; frequency *= Lacunarity; } return value / maxValue; } void FBMNoise2D_float(float2 UV, float Scale, float Octaves, float Lacunarity, float Gain, out float Out) { Out = FBMNoise2D(UV, Scale, (int)Octaves, Lacunarity, Gain); } // --- 3D ---------------------------------------------------------------------- float FBMNoise3D( float3 Position, // Input position in object space float Scale, // Base noise frequency int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain) // Amplitude multiplier per octave (typically 0.5) { float value = 0.0; float amplitude = 0.5; float frequency = Scale; float maxValue = 0.0; for (int i = 0; i < Octaves; i++) { value += PerlinNoise3D(Position, frequency) * amplitude; maxValue += amplitude; amplitude *= Gain; frequency *= Lacunarity; } return value / maxValue; } void FBMNoise3D_float(float3 Position, float Scale, float Octaves, float Lacunarity, float Gain, out float Out) { Out = FBMNoise3D(Position, Scale, (int)Octaves, Lacunarity, Gain); } // --- 3D LOD ------------------------------------------------------------------ float FBMNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Base noise frequency at reference distance int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain, // Amplitude multiplier per octave (typically 0.5) float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return FBMNoise3D(PositionWS, scale0, Octaves, Lacunarity, Gain) * w0 + FBMNoise3D(PositionWS, scale1, Octaves, Lacunarity, Gain) * w1; } void FBMNoise3DLOD_float(float3 PositionWS, float Scale, float Octaves, float Lacunarity, float Gain, float LODRatio, out float Out) { Out = FBMNoise3DLOD(PositionWS, Scale, (int)Octaves, Lacunarity, Gain, LODRatio); } // ============================================================================= // RIDGED NOISE – |FBM| folded to produce sharp ridges // ============================================================================= // --- 2D ---------------------------------------------------------------------- float RidgedNoise2D( float2 UV, // Input UV coordinates float Scale, // Base noise frequency int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain) // Amplitude multiplier per octave (typically 0.5) { float value = 0.0; float amplitude = 0.5; float frequency = Scale; float maxValue = 0.0; for (int i = 0; i < Octaves; i++) { float n = 1.0 - abs(PerlinNoise2D(UV, frequency) * 2.0 - 1.0); value += n * n * amplitude; maxValue += amplitude; amplitude *= Gain; frequency *= Lacunarity; } return value / maxValue; } void RidgedNoise2D_float(float2 UV, float Scale, float Octaves, float Lacunarity, float Gain, out float Out) { Out = RidgedNoise2D(UV, Scale, (int)Octaves, Lacunarity, Gain); } // --- 3D ---------------------------------------------------------------------- float RidgedNoise3D( float3 Position, // Input position in object space float Scale, // Base noise frequency int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain) // Amplitude multiplier per octave (typically 0.5) { float value = 0.0; float amplitude = 0.5; float frequency = Scale; float maxValue = 0.0; for (int i = 0; i < Octaves; i++) { float n = 1.0 - abs(PerlinNoise3D(Position, frequency) * 2.0 - 1.0); value += n * n * amplitude; maxValue += amplitude; amplitude *= Gain; frequency *= Lacunarity; } return value / maxValue; } void RidgedNoise3D_float(float3 Position, float Scale, float Octaves, float Lacunarity, float Gain, out float Out) { Out = RidgedNoise3D(Position, Scale, (int)Octaves, Lacunarity, Gain); } // --- 3D LOD ------------------------------------------------------------------ float RidgedNoise3DLOD( float3 PositionWS, // Surface position in world space float Scale, // Base noise frequency at reference distance int Octaves, // Number of noise layers float Lacunarity, // Frequency multiplier per octave (typically 2.0) float Gain, // Amplitude multiplier per octave (typically 0.5) float LODRatio) // Scale ratio between layers (4 = wide transition) { float scale0, scale1, w0, w1; LODBlend(PositionWS, Scale, LODRatio, scale0, scale1, w0, w1); return RidgedNoise3D(PositionWS, scale0, Octaves, Lacunarity, Gain) * w0 + RidgedNoise3D(PositionWS, scale1, Octaves, Lacunarity, Gain) * w1; } void RidgedNoise3DLOD_float(float3 PositionWS, float Scale, float Octaves, float Lacunarity, float Gain, float LODRatio, out float Out) { Out = RidgedNoise3DLOD(PositionWS, Scale, (int)Octaves, Lacunarity, Gain, LODRatio); } #endif