Browse Source

tutorial: sync HLSL version of the water/fire effect with the GLSL one.

legacy
Sam Hocevar sam 12 years ago
parent
commit
a233173fc7
1 changed files with 59 additions and 28 deletions
  1. +59
    -28
      tutorial/03_noise.lolfx

+ 59
- 28
tutorial/03_noise.lolfx View File

@@ -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);
}


Loading…
Cancel
Save