diff --git a/Source/Engine/Utilities/Noise.cpp b/Source/Engine/Utilities/Noise.cpp index 5d94a2a07..93ed69d21 100644 --- a/Source/Engine/Utilities/Noise.cpp +++ b/Source/Engine/Utilities/Noise.cpp @@ -71,88 +71,61 @@ namespace rand2dTo1d(value, Float2(39.346f, 11.135f)) ); } + + float PerlinNoiseImpl(const Float2& p, const Float2* rep) + { + Float4 Pxy(p.X, p.Y, p.X, p.Y); + Float4 Pi = Float4::Floor(Pxy) + Float4(0.0, 0.0, 1.0, 1.0); + Float4 Pf = Float4::Frac(Pxy) - Float4(0.0, 0.0, 1.0, 1.0); + if (rep) + { + Float4 Repxy(rep->X, rep->Y, rep->X, rep->Y); + Pi = Float4::Mod(Pi, Repxy); + } + Pi = Mod289(Pi); + Float4 ix(Pi.X, Pi.Z, Pi.X, Pi.Z); + Float4 iy(Pi.Y, Pi.Y, Pi.W, Pi.W); + Float4 fx(Pf.X, Pf.Z, Pf.X, Pf.Z); + Float4 fy(Pf.Y, Pf.Y, Pf.W, Pf.W); + + Float4 i = Permute(Permute(ix) + iy); + + Float4 gx = Float4::Frac(i * (1.0 / 41.0)) * 2.0 - 1.0; + Float4 gy = Float4::Abs(gx) - 0.5; + Float4 tx = Float4::Floor(gx + 0.5); + gx = gx - tx; + + Float2 g00(gx.X, gy.X); + Float2 g10(gx.Y, gy.Y); + Float2 g01(gx.Z, gy.Z); + Float2 g11(gx.W, gy.W); + + Float4 norm = TaylorInvSqrt(Float4(Float2::Dot(g00, g00), Float2::Dot(g01, g01), Float2::Dot(g10, g10), Float2::Dot(g11, g11))); + g00 *= norm.X; + g01 *= norm.Y; + g10 *= norm.Z; + g11 *= norm.W; + + float n00 = Float2::Dot(g00, Float2(fx.X, fy.X)); + float n10 = Float2::Dot(g10, Float2(fx.Y, fy.Y)); + float n01 = Float2::Dot(g01, Float2(fx.Z, fy.Z)); + float n11 = Float2::Dot(g11, Float2(fx.W, fy.W)); + + Float2 fade_xy = PerlinNoiseFade(Float2(Pf)); + Float2 n_x = Float2::Lerp(Float2(n00, n01), Float2(n10, n11), fade_xy.X); + float n_xy = Math::Lerp(n_x.X, n_x.Y, fade_xy.Y); + return Math::Saturate(2.3f * n_xy); + } } float Noise::PerlinNoise(const Float2& p) { - Float4 Pxy(p.X, p.Y, p.X, p.Y); - Float4 Pi = Float4::Floor(Pxy) + Float4(0.0, 0.0, 1.0, 1.0); - Float4 Pf = Float4::Frac(Pxy) - Float4(0.0, 0.0, 1.0, 1.0); - Pi = Mod289(Pi); - Float4 ix(Pi.X, Pi.Z, Pi.X, Pi.Z); - Float4 iy(Pi.Y, Pi.Y, Pi.W, Pi.W); - Float4 fx(Pf.X, Pf.Z, Pf.X, Pf.Z); - Float4 fy(Pf.Y, Pf.Y, Pf.W, Pf.W); - - Float4 i = Permute(Permute(ix) + iy); - - Float4 gx = Float4::Frac(i * (1.0 / 41.0)) * 2.0 - 1.0; - Float4 gy = Float4::Abs(gx) - 0.5; - Float4 tx = Float4::Floor(gx + 0.5); - gx = gx - tx; - - Float2 g00(gx.X, gy.X); - Float2 g10(gx.Y, gy.Y); - Float2 g01(gx.Z, gy.Z); - Float2 g11(gx.W, gy.W); - - Float4 norm = TaylorInvSqrt(Float4(Float2::Dot(g00, g00), Float2::Dot(g01, g01), Float2::Dot(g10, g10), Float2::Dot(g11, g11))); - g00 *= norm.X; - g01 *= norm.Y; - g10 *= norm.Z; - g11 *= norm.W; - - float n00 = Float2::Dot(g00, Float2(fx.X, fy.X)); - float n10 = Float2::Dot(g10, Float2(fx.Y, fy.Y)); - float n01 = Float2::Dot(g01, Float2(fx.Z, fy.Z)); - float n11 = Float2::Dot(g11, Float2(fx.W, fy.W)); - - Float2 fade_xy = PerlinNoiseFade(Float2(Pf)); - Float2 n_x = Float2::Lerp(Float2(n00, n01), Float2(n10, n11), fade_xy.X); - float n_xy = Math::Lerp(n_x.X, n_x.Y, fade_xy.Y); - return Math::Saturate(2.3f * n_xy); + return PerlinNoiseImpl(p, nullptr); } float Noise::PerlinNoise(const Float2& p, const Float2& rep) { - Float4 Pxy(p.X, p.Y, p.X, p.Y); - Float4 Repxy(rep.X, rep.Y, rep.X, rep.Y); - Float4 Pi = Float4::Floor(Pxy) + Float4(0.0, 0.0, 1.0, 1.0); - Float4 Pf = Float4::Frac(Pxy) - Float4(0.0, 0.0, 1.0, 1.0); - Pi = Float4::Mod(Pi, Repxy); - Pi = Mod289(Pi); - Float4 ix(Pi.X, Pi.Z, Pi.X, Pi.Z); - Float4 iy(Pi.Y, Pi.Y, Pi.W, Pi.W); - Float4 fx(Pf.X, Pf.Z, Pf.X, Pf.Z); - Float4 fy(Pf.Y, Pf.Y, Pf.W, Pf.W); - - Float4 i = Permute(Permute(ix) + iy); - - Float4 gx = Float4::Frac(i * (1.0 / 41.0)) * 2.0 - 1.0; - Float4 gy = Float4::Abs(gx) - 0.5; - Float4 tx = Float4::Floor(gx + 0.5); - gx = gx - tx; - - Float2 g00(gx.X, gy.X); - Float2 g10(gx.Y, gy.Y); - Float2 g01(gx.Z, gy.Z); - Float2 g11(gx.W, gy.W); - - Float4 norm = TaylorInvSqrt(Float4(Float2::Dot(g00, g00), Float2::Dot(g01, g01), Float2::Dot(g10, g10), Float2::Dot(g11, g11))); - g00 *= norm.X; - g01 *= norm.Y; - g10 *= norm.Z; - g11 *= norm.W; - - float n00 = Float2::Dot(g00, Float2(fx.X, fy.X)); - float n10 = Float2::Dot(g10, Float2(fx.Y, fy.Y)); - float n01 = Float2::Dot(g01, Float2(fx.Z, fy.Z)); - float n11 = Float2::Dot(g11, Float2(fx.W, fy.W)); - - Float2 fade_xy = PerlinNoiseFade(Float2(Pf)); - Float2 n_x = Float2::Lerp(Float2(n00, n01), Float2(n10, n11), fade_xy.X); - float n_xy = Math::Lerp(n_x.X, n_x.Y, fade_xy.Y); - return Math::Saturate(2.3f * n_xy); + return PerlinNoiseImpl(p, &rep); } float Noise::SimplexNoise(const Float2& p) diff --git a/Source/Shaders/Noise.hlsl b/Source/Shaders/Noise.hlsl index 1375ecd6e..514dc29c2 100644 --- a/Source/Shaders/Noise.hlsl +++ b/Source/Shaders/Noise.hlsl @@ -89,11 +89,9 @@ float3 rand3dTo3d(float3 value) ); } -// Classic Perlin noise -float PerlinNoise(float2 p) + +float PerlinNoiseImpl(float4 Pi, float4 Pf) { - float4 Pi = floor(p.xyxy) + float4(0.0, 0.0, 1.0, 1.0); - float4 Pf = frac(p.xyxy) - float4(0.0, 0.0, 1.0, 1.0); Pi = Mod289(Pi); float4 ix = Pi.xzxz; float4 iy = Pi.yyww; @@ -129,45 +127,21 @@ float PerlinNoise(float2 p) return saturate(2.3 * n_xy); } +// Classic Perlin noise +float PerlinNoise(float2 p) +{ + float4 Pi = floor(p.xyxy) + float4(0.0, 0.0, 1.0, 1.0); + float4 Pf = frac(p.xyxy) - float4(0.0, 0.0, 1.0, 1.0); + return PerlinNoiseImpl(Pi, Pf); +} + // Classic Perlin noise with periodic variant float PerlinNoise(float2 p, float2 rep) { float4 Pi = floor(p.xyxy) + float4(0.0, 0.0, 1.0, 1.0); float4 Pf = frac(p.xyxy) - float4(0.0, 0.0, 1.0, 1.0); Pi = fmod(Pi, rep.xyxy); - Pi = Mod289(Pi); - float4 ix = Pi.xzxz; - float4 iy = Pi.yyww; - float4 fx = Pf.xzxz; - float4 fy = Pf.yyww; - - float4 i = Permute(Permute(ix) + iy); - - float4 gx = frac(i * (1.0 / 41.0)) * 2.0 - 1.0; - float4 gy = abs(gx) - 0.5; - float4 tx = floor(gx + 0.5); - gx = gx - tx; - - float2 g00 = float2(gx.x, gy.x); - float2 g10 = float2(gx.y, gy.y); - float2 g01 = float2(gx.z, gy.z); - float2 g11 = float2(gx.w, gy.w); - - float4 norm = TaylorInvSqrt(float4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11))); - g00 *= norm.x; - g01 *= norm.y; - g10 *= norm.z; - g11 *= norm.w; - - float n00 = dot(g00, float2(fx.x, fy.x)); - float n10 = dot(g10, float2(fx.y, fy.y)); - float n01 = dot(g01, float2(fx.z, fy.z)); - float n11 = dot(g11, float2(fx.w, fy.w)); - - float2 fade_xy = PerlinNoiseFade(Pf.xy); - float2 n_x = lerp(float2(n00, n01), float2(n10, n11), fade_xy.x); - float n_xy = lerp(n_x.x, n_x.y, fade_xy.y); - return saturate(2.3 * n_xy); + return PerlinNoiseImpl(Pi, Pf); } // Simplex noise