// Based on IQ's gradient noise formula. private float Noise2D3G(float2 p) { float2 i = Hlsl.Floor(p); p -= i; float4 v = default; v.X = Hlsl.Dot(Hash22(i), p); v.Y = Hlsl.Dot(Hash22(i + float2.UnitX), p - float2.UnitX); v.Z = Hlsl.Dot(Hash22(i + float2.UnitY), p - float2.UnitY); v.W = Hlsl.Dot(Hash22(i + 1.0f), p - 1.0f); p = p * p * p * (p * (p * 6.0f - 15.0f) + 10.0f); return(Hlsl.Lerp(Hlsl.Lerp(v.X, v.Y, p.X), Hlsl.Lerp(v.Z, v.W, p.X), p.Y)); }
// Smooth 2D noise private static float Noise2D(float2 p) { float2 i = Hlsl.Floor(p); p -= i; float4 v = default; v.X = Hlsl.Dot(Hash22B(i), p); v.Y = Hlsl.Dot(Hash22B(i + float2.UnitX), p - float2.UnitX); v.Z = Hlsl.Dot(Hash22B(i + float2.UnitY), p - float2.UnitY); v.W = Hlsl.Dot(Hash22B(i + 1.0f), p - 1.0f); p = p * p * (3.0f - 2.0f * p); return(Hlsl.Lerp(Hlsl.Lerp(v.X, v.Y, p.X), Hlsl.Lerp(v.Z, v.W, p.X), p.Y)); }
/// <inheritdoc/> public float4 Execute() { float2 uv = (ThreadIds.XY - (float2)DispatchSize.XY * 0.5f) / DispatchSize.Y; float3 col = 0; float t = time * 0.3f; for (float i = 0.0f; i <= 1.0f; i += 1.0f / NumberOfLayers) { float d = Hlsl.Frac(i + t); float s = Hlsl.Lerp(5.0f, 0.5f, d); float f = d * Hlsl.SmoothStep(1.0f, 0.9f, d); col += Tex(new float3(uv.X * s, uv.Y * s, i * 4.0f)).XYZ *f; } col /= NumberOfLayers; col *= new float3(2, 1.0f, 2.0f); col = Hlsl.Pow(col, 0.5f); return(new(col.X, col.Y, col.Z, 1.0f)); }