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

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

tutorial: optimise Perlin noise shader and reduce its complexity.

File size: 3.9 KB
Line 
1-- GLSL.Vert --
2
3#version 120
4
5attribute vec2 in_Position;
6
7void main(void)
8{
9    gl_Position = vec4(in_Position, 0.0, 1.0);
10}
11
12-- GLSL.Frag --
13
14#version 120
15
16uniform float u_Time;
17
18vec4 noise3d(vec3 p1, vec3 p2, vec3 p3, vec3 p4)
19{
20    vec3 q = vec3(12.3453, -54.3353432, 34.3490432);
21    vec4 s = vec4(dot(p1, q), dot(p2, q), dot(p3, q), dot(p4, q));
22    return fract(sin(54.343909 + s) * 8433.235443);
23}
24
25float perlin3d(vec3 p)
26{
27    mat3 r = mat3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
28    p = r * p;
29
30    vec3 a = floor(p);
31    vec3 d = p - a;
32    d = d * d * (3.0 - 2.0 * d);
33
34    vec4 o1 = noise3d(a,
35                      a + vec3(0.0, 1.0, 0.0),
36                      a + vec3(0.0, 0.0, 1.0),
37                      a + vec3(0.0, 1.0, 1.0));
38    vec4 o2 = noise3d(a + vec3(1.0, 0.0, 0.0),
39                      a + vec3(1.0, 1.0, 0.0),
40                      a + vec3(1.0, 0.0, 1.0),
41                      a + vec3(1.0, 1.0, 1.0));
42
43    vec4 o3 = o2 * d.x + o1 * (1.0 - d.x);
44    vec2 o4 = o3.yw * d.y + o3.xz * (1.0 - d.y);
45
46    return o4.y * d.z + o4.x * (1.0 - d.z);
47}
48
49void main(void)
50{
51    vec2 xy = gl_FragCoord.xy * 2.0;
52    xy.y -= u_Time * 400.0;
53    float z = u_Time * 2.0;
54
55    float p = perlin3d(vec3(xy / 80.0, z + 1.5)) / 2.0
56            + perlin3d(vec3(xy / 40.0, z + 0.3)) / 4.0
57            + perlin3d(vec3(xy / 20.0, z + 3.3)) / 8.0
58            + perlin3d(vec3(xy / 10.0, z + 2.0)) / 16.0;
59
60    /* Scroll by adding [-.5,.5] */
61    p -= gl_FragCoord.y / 720.0 - 0.5;
62    p = max(p, 0.0);
63    p = min(p, 1.0);
64
65    float q = p * p * (3.0 - 2.0 * p);
66    float r = q * q * (3.0 - 2.0 * q);
67    gl_FragColor = vec4(min(q * 2.0, 1.0),
68                        max(r * 1.5 - 0.5, 0.0),
69                        max(q * 8.0 - 7.3, 0.0),
70                        1.0);
71}
72
73-- HLSL.Vert --
74
75void main(float2 in_Position : POSITION,
76          uniform float2 u_WinSize,
77          out float4 out_Position : POSITION,
78          out float2 pass_Position : TEXCOORD0)
79{
80    //pass_Position = in_Position * u_WinSize;
81    pass_Position = in_Position * float2(1280.0, 720.0);
82    out_Position = float4(in_Position, 0.0, 1.0);
83}
84
85-- HLSL.Frag --
86
87float4 noise3d(float3 p1, float3 p2, float3 p3, float3 p4)
88{
89    float3 q = float3(12.3453, -54.3353432, 34.3490432);
90    float4 s = float4(dot(p1, q), dot(p2, q), dot(p3, q), dot(p4, q));
91    return frac(sin(54.343909 + s) * 8433.235443);
92}
93
94float perlin3d(float3 p)
95{
96    float3x3 r = float3x3(0.36, 0.48, -0.8, -0.8, 0.60, 0.0, 0.48, 0.64, 0.60);
97    p = mul(r, p);
98
99    float3 a = floor(p);
100    float3 d = p - a;
101    d = d * d * (3.0 - 2.0 * d);
102
103    float4 o1 = noise3d(a,
104                        a + float3(0.0, 1.0, 0.0),
105                        a + float3(0.0, 0.0, 1.0),
106                        a + float3(0.0, 1.0, 1.0));
107    float4 o2 = noise3d(a + float3(1.0, 0.0, 0.0),
108                        a + float3(1.0, 1.0, 0.0),
109                        a + float3(1.0, 0.0, 1.0),
110                        a + float3(1.0, 1.0, 1.0));
111
112    float4 o3 = o2 * d.x + o1 * (1.0 - d.x);
113    float2 o4 = o3.yw * d.y + o3.xz * (1.0 - d.y);
114
115    return o4.y * d.z + o4.x * (1.0 - d.z);
116}
117
118void main(in float2 pass_Position : TEXCOORD0,
119          uniform float u_Time,
120          out float4 out_FragColor : COLOR)
121{
122    float2 xy = pass_Position;
123    xy.y -= u_Time * 400.0;
124    float z = u_Time * 2.0;
125
126    float p = perlin3d(float3(xy / 80.0, z + 1.5)) / 2.0
127            + perlin3d(float3(xy / 40.0, z + 0.3)) / 4.0
128            + perlin3d(float3(xy / 20.0, z + 3.3)) / 8.0
129            + perlin3d(float3(xy / 10.0, z + 2.0)) / 16.0;
130
131    /* Scroll by adding [-.5,.5] */
132    p -= pass_Position.y / 1440.0;
133    p = max(p, 0.0);
134    p = min(p, 1.0);
135
136    float q = p * p * (3.0 - 2.0 * p);
137    float r = q * q * (3.0 - 2.0 * q);
138    out_FragColor = float4(min(q * 2.0, 1.0),
139                           max(r * 1.5 - 0.5, 0.0),
140                           max(q * 8.0 - 7.3, 0.0),
141                           1.0);
142}
Note: See TracBrowser for help on using the repository browser.