diff --git a/tutorial/03_noise.lolfx b/tutorial/03_noise.lolfx index de81f956..091fd371 100644 --- a/tutorial/03_noise.lolfx +++ b/tutorial/03_noise.lolfx @@ -88,7 +88,7 @@ float noise3d(vec3 p) void main(void) { /* Dither the transition between water and fire */ - float test = pass_Position.z * pass_Position.w + sin(2.0 * u_Time); + float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time); vec2 d = vec2(16.0, 9.0) * pass_Position.xy; test += 0.5 * (length(fract(d) - 0.5) - length(fract(d + 0.5) - 0.5)); @@ -136,13 +136,40 @@ void main(void) -- HLSL.Vert -- +float mod289(float x) +{ + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + void main(float2 in_Position : POSITION, - uniform float2 u_WinSize, + uniform float u_Time, out float4 out_Position : POSITION, - out float2 pass_Position : TEXCOORD0) + out float4 pass_Position : TEXCOORD0, + out float3 water[4] : TEXCOORD1, + out float3 fire[4] : TEXCOORD5) { - //pass_Position = in_Position * u_WinSize; - pass_Position = in_Position * float2(1280.0, 720.0); + float3x3 r = float3x3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60); + float3 p_pos = mul(r, float3(in_Position * float2(16.0, 9.0), 0.0)); + float3 p_time = mul(r, float3(0.0, 0.0, u_Time * 2.0)); + + /* Noise sampling points for water */ + water[0] = p_pos / 2.0 + p_time; + water[1] = p_pos / 4.0 + p_time; + water[2] = p_pos / 8.0 + p_time; + water[3] = p_pos / 16.0 + p_time; + + /* Noise sampling points for fire */ + p_pos = 16.0 * p_pos - mul(r, float3(0.0, mod289(u_Time) * 128.0, 0.0)); + fire[0] = p_pos / 2.0 + p_time * 2.0; + fire[1] = p_pos / 4.0 + p_time * 1.5; + fire[2] = p_pos / 8.0 + p_time; + fire[3] = p_pos / 16.0 + p_time; + + /* Pass rotated screen coordinates */ + pass_Position.xy = in_Position; + float2x2 rot = float2x2(cos(u_Time), sin(u_Time), -sin(u_Time), cos(u_Time)); + pass_Position.zw = mul(rot, in_Position); + out_Position = float4(in_Position, 0.0, 1.0); } @@ -160,9 +187,6 @@ float4 perm(float4 x) float noise3d(float3 p) { - float3x3 r = float3x3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60); - p = mul(r, p); - float3 a = floor(p); float3 d = p - a; d = d * d * (3.0 - 2.0 * d); @@ -184,32 +208,38 @@ float noise3d(float3 p) return o4.y * d.y + o4.x * (1.0 - d.y); } -void main(in float2 pass_Position : TEXCOORD0, +void main(in float4 pass_Position : TEXCOORD0, + in float3 water[4] : TEXCOORD1, + in float3 fire[4] : TEXCOORD5, uniform float u_Time, out float4 out_FragColor : COLOR) { - float2 xy = pass_Position; - float z = u_Time * 2.0; - - float tx = pass_Position.x * cos(u_Time) - pass_Position.y * sin(u_Time); - float ty = pass_Position.x * sin(u_Time) + pass_Position.y * cos(u_Time); + /* Dither the transition between water and fire */ + float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time); + float2 d = float2(16.0, 9.0) * pass_Position.xy; + test += 0.5 * (length(frac(d) - 0.5) - length(frac(d + 0.5) - 0.5)); - if (tx * ty > 0.0) - xy.y -= z * 200.0; + float3 points[4]; + points[0] = (test > 0.0) ? fire[0] : water[0]; + points[1] = (test > 0.0) ? fire[1] : water[1]; + points[2] = (test > 0.0) ? fire[2] : water[2]; + points[3] = (test > 0.0) ? fire[3] : water[3]; - float p1 = noise3d(float3(xy / 80.0, z)); - float p2 = noise3d(float3(xy / 40.0, z)); - float p3 = noise3d(float3(xy / 20.0, z)); - float p4 = noise3d(float3(xy / 10.0, z)); + /* Compute 4 octaves of noise */ + float4 n = float4(noise3d(points[0]), + noise3d(points[1]), + noise3d(points[2]), + noise3d(points[3])); float4 color; - if (tx * ty > 0.0) + if (test > 0.0) { - float p = 0.5 * p1 + 0.25 * p2 + 0.125 * (p3 + p4); + /* Use noise results for fire */ + float p = dot(n, float4(0.125, 0.125, 0.25, 0.5)); - /* Scroll by adding [-.5,.5] */ - p -= pass_Position.y / 1440.0; + /* Fade to black on top of screen */ + p -= pass_Position.y * 0.8 + 0.25; p = max(p, 0.0); p = min(p, 1.0); @@ -222,12 +252,13 @@ void main(in float2 pass_Position : TEXCOORD0, } else { - float p = 0.5 * p1 + 0.25 * p2 + 0.125 * (p3 + p4); + /* Use noise results for water */ + float p = dot(abs(2.0 * n - 1.0), + float4(0.5, 0.25, 0.125, 0.125)); + float q = sqrt(p); - float q = p * p * (3.0 - 2.0 * p); - float r = q * q * (3.0 - 2.0 * q); color = float4(1.0 - q, - 1.0 - 0.5 * r, + 1.0 - 0.5 * q, 1.0, 1.0); }