source: trunk/tutorial/03_noise.lolfx @ 1928

Last change on this file since 1928 was 1928, checked in by sam, 8 years ago

lolfx: use square brackets to indicate shader sections.

File size: 6.9 KB
Line 
1[vert.glsl]
2
3#version 120
4
5uniform float u_Time;
6
7attribute vec2 in_Position;
8
9varying vec4 pass_Position;
10varying vec3 water[4];
11varying vec3 fire[4];
12
13float mod289(float x)
14{
15    return x - floor(x * (1.0 / 289.0)) * 289.0;
16}
17
18void main(void)
19{
20    mat3 r = mat3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
21    vec3 p_pos = r * vec3(in_Position * vec2(16.0, 9.0), 0.0);
22    vec3 p_time = r * vec3(0.0, 0.0, u_Time * 2.0);
23
24    /* Noise sampling points for water */
25    water[0] = p_pos / 2.0 + p_time;
26    water[1] = p_pos / 4.0 + p_time;
27    water[2] = p_pos / 8.0 + p_time;
28    water[3] = p_pos / 16.0 + p_time;
29
30    /* Noise sampling points for fire */
31    p_pos = 16.0 * p_pos - r * vec3(0.0, mod289(u_Time) * 128.0, 0.0);
32    fire[0] = p_pos / 2.0 + p_time * 2.0;
33    fire[1] = p_pos / 4.0 + p_time * 1.5;
34    fire[2] = p_pos / 8.0 + p_time;
35    fire[3] = p_pos / 16.0 + p_time;
36
37    /* Pass rotated screen coordinates */
38    pass_Position.xy = in_Position;
39    mat2 rot = mat2(cos(u_Time), sin(u_Time), -sin(u_Time), cos(u_Time));
40    pass_Position.zw = rot * in_Position;
41
42    gl_Position = vec4(in_Position, 0.0, 1.0);
43}
44
45[frag.glsl]
46
47#version 120
48
49uniform float u_Time;
50
51varying vec4 pass_Position;
52varying vec3 water[4];
53varying vec3 fire[4];
54
55vec4 mod289(vec4 x)
56{
57    return x - floor(x * (1.0 / 289.0)) * 289.0;
58}
59
60vec4 perm(vec4 x)
61{
62    return mod289(((x * 34.0) + 1.0) * x);
63}
64
65float noise3d(vec3 p)
66{
67    vec3 a = floor(p);
68    vec3 d = p - a;
69    d = d * d * (3.0 - 2.0 * d);
70
71    vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
72    vec4 k1 = perm(b.xyxy);
73    vec4 k2 = perm(k1.xyxy + b.zzww);
74
75    vec4 c = k2 + a.zzzz;
76    vec4 k3 = perm(c);
77    vec4 k4 = perm(c + 1.0);
78
79    vec4 o1 = fract(k3 * (1.0 / 41.0));
80    vec4 o2 = fract(k4 * (1.0 / 41.0));
81
82    vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
83    vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
84
85    return o4.y * d.y + o4.x * (1.0 - d.y);
86}
87
88void main(void)
89{
90    /* Dither the transition between water and fire */
91    float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time);
92    vec2 d = vec2(16.0, 9.0) * pass_Position.xy;
93    test += 0.5 * (length(fract(d) - 0.5) - length(fract(d + 0.5) - 0.5));
94
95    /* Compute 4 octaves of noise */
96    vec3 points[4] = (test > 0.0) ? fire : water;
97    vec4 n = vec4(noise3d(points[0]),
98                  noise3d(points[1]),
99                  noise3d(points[2]),
100                  noise3d(points[3]));
101
102    vec4 color;
103
104    if (test > 0.0)
105    {
106        /* Use noise results for fire */
107        float p = dot(n, vec4(0.125, 0.125, 0.25, 0.5));
108
109        /* Fade to black on top of screen */
110        p -= pass_Position.y * 0.8 + 0.25;
111        p = max(p, 0.0);
112        p = min(p, 1.0);
113
114        float q = p * p * (3.0 - 2.0 * p);
115        float r = q * q * (3.0 - 2.0 * q);
116        color = vec4(min(q * 2.0, 1.0),
117                     max(r * 1.5 - 0.5, 0.0),
118                     max(q * 8.0 - 7.3, 0.0),
119                     1.0);
120    }
121    else
122    {
123        /* Use noise results for water */
124        float p = dot(abs(2.0 * n - 1.0),
125                      vec4(0.5, 0.25, 0.125, 0.125));
126        float q = sqrt(p);
127
128        color = vec4(1.0 - q,
129                     1.0 - 0.5 * q,
130                     1.0,
131                     1.0);
132    }
133
134    gl_FragColor = color;
135}
136
137[vert.hlsl]
138
139float mod289(float x)
140{
141    return x - floor(x * (1.0 / 289.0)) * 289.0;
142}
143
144void main(float2 in_Position : POSITION,
145          uniform float u_Time,
146          out float4 out_Position : POSITION,
147          out float4 pass_Position : TEXCOORD0,
148          out float3 water[4] : TEXCOORD1,
149          out float3 fire[4] : TEXCOORD5)
150{
151    float3x3 r = float3x3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
152    float3 p_pos = mul(r, float3(in_Position * float2(16.0, 9.0), 0.0));
153    float3 p_time = mul(r, float3(0.0, 0.0, u_Time * 2.0));
154
155    /* Noise sampling points for water */
156    water[0] = p_pos / 2.0 + p_time;
157    water[1] = p_pos / 4.0 + p_time;
158    water[2] = p_pos / 8.0 + p_time;
159    water[3] = p_pos / 16.0 + p_time;
160
161    /* Noise sampling points for fire */
162    p_pos = 16.0 * p_pos - mul(r, float3(0.0, mod289(u_Time) * 128.0, 0.0));
163    fire[0] = p_pos / 2.0 + p_time * 2.0;
164    fire[1] = p_pos / 4.0 + p_time * 1.5;
165    fire[2] = p_pos / 8.0 + p_time;
166    fire[3] = p_pos / 16.0 + p_time;
167
168    /* Pass rotated screen coordinates */
169    pass_Position.xy = in_Position;
170    float2x2 rot = float2x2(cos(u_Time), sin(u_Time), -sin(u_Time), cos(u_Time));
171    pass_Position.zw = mul(rot, in_Position);
172
173    out_Position = float4(in_Position, 0.0, 1.0);
174}
175
176[frag.hlsl]
177
178float4 mod289(float4 x)
179{
180    return x - floor(x * (1.0 / 289.0)) * 289.0;
181}
182
183float4 perm(float4 x)
184{
185    return mod289(((x * 34.0) + 1.0) * x);
186}
187
188float noise3d(float3 p)
189{
190    float3 a = floor(p);
191    float3 d = p - a;
192    d = d * d * (3.0 - 2.0 * d);
193
194    float4 b = a.xxyy + float4(0.0, 1.0, 0.0, 1.0);
195    float4 k1 = perm(b.xyxy);
196    float4 k2 = perm(k1.xyxy + b.zzww);
197
198    float4 c = k2 + a.zzzz;
199    float4 k3 = perm(c);
200    float4 k4 = perm(c + 1.0);
201
202    float4 o1 = frac(k3 * (1.0 / 41.0));
203    float4 o2 = frac(k4 * (1.0 / 41.0));
204
205    float4 o3 = o2 * d.z + o1 * (1.0 - d.z);
206    float2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
207
208    return o4.y * d.y + o4.x * (1.0 - d.y);
209}
210
211void main(in float4 pass_Position : TEXCOORD0,
212          in float3 water[4] : TEXCOORD1,
213          in float3 fire[4] : TEXCOORD5,
214          uniform float u_Time,
215          out float4 out_FragColor : COLOR)
216{
217    /* Dither the transition between water and fire */
218    float test = pass_Position.z * pass_Position.w + 1.5 * sin(u_Time);
219    float2 d = float2(16.0, 9.0) * pass_Position.xy;
220    test += 0.5 * (length(frac(d) - 0.5) - length(frac(d + 0.5) - 0.5));
221
222    float3 points[4];
223    points[0] = (test > 0.0) ? fire[0] : water[0];
224    points[1] = (test > 0.0) ? fire[1] : water[1];
225    points[2] = (test > 0.0) ? fire[2] : water[2];
226    points[3] = (test > 0.0) ? fire[3] : water[3];
227
228    /* Compute 4 octaves of noise */
229    float4 n = float4(noise3d(points[0]),
230                      noise3d(points[1]),
231                      noise3d(points[2]),
232                      noise3d(points[3]));
233
234    float4 color;
235
236    if (test > 0.0)
237    {
238        /* Use noise results for fire */
239        float p = dot(n, float4(0.125, 0.125, 0.25, 0.5));
240
241        /* Fade to black on top of screen */
242        p -= pass_Position.y * 0.8 + 0.25;
243        p = max(p, 0.0);
244        p = min(p, 1.0);
245
246        float q = p * p * (3.0 - 2.0 * p);
247        float r = q * q * (3.0 - 2.0 * q);
248        color = float4(min(q * 2.0, 1.0),
249                       max(r * 1.5 - 0.5, 0.0),
250                       max(q * 8.0 - 7.3, 0.0),
251                       1.0);
252    }
253    else
254    {
255        /* Use noise results for water */
256        float p = dot(abs(2.0 * n - 1.0),
257                      float4(0.5, 0.25, 0.125, 0.125));
258        float q = sqrt(p);
259
260        color = float4(1.0 - q,
261                       1.0 - 0.5 * q,
262                       1.0,
263                       1.0);
264    }
265
266    out_FragColor = color;
267}
Note: See TracBrowser for help on using the repository browser.