]> git.tdb.fi Git - libs/gl.git/blob - demos/forestpond/data/water.glsl
Shader fixes in the forest pond demo
[libs/gl.git] / demos / forestpond / data / water.glsl
1 import msp_interface;
2 import lighting;
3
4 uniform Tessellation
5 {
6         float tessellation_level;
7 };
8
9 uniform Region
10 {
11         vec2 scale;
12         vec2 offset;
13         float amplitude;
14 } region;
15
16 uniform sampler2D bottom;
17 uniform sampler2D surface;
18 uniform sampler2D normals;
19 uniform sampler2D variance;
20
21 #pragma MSP stage(vertex)
22 void main()
23 {
24         gl_Position = world_obj_matrix*vertex;
25 }
26
27 #pragma MSP stage(tess_control)
28 layout(vertices=4) out;
29
30 void main()
31 {
32         gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
33
34         gl_TessLevelInner[0] = tessellation_level;
35         gl_TessLevelInner[1] = tessellation_level;
36         for(int i=0; i<4; ++i)
37                 gl_TessLevelOuter[i] = tessellation_level;
38 }
39
40 #pragma MSP stage(tess_eval)
41 layout(quads) in;
42
43 void main()
44 {
45         float w0 = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y);
46         float w1 = gl_TessCoord.x*(1.0-gl_TessCoord.y);
47         float w2 = gl_TessCoord.x*gl_TessCoord.y;
48         float w3 = (1.0-gl_TessCoord.x)*gl_TessCoord.y;
49         vec4 pos = w0*gl_in[0].gl_Position+w1*gl_in[1].gl_Position+w2*gl_in[2].gl_Position+w3*gl_in[3].gl_Position;
50         out vec2 texcoord = pos.xy*region.scale+region.offset;
51         pos.z = textureLod(surface, texcoord, 0).x*region.amplitude-0.01;
52         out vec3 world_look = pos.xyz-world_eye_matrix[3].xyz;
53         gl_Position = clip_eye_matrix*eye_world_matrix*pos;
54 }
55
56 #pragma MSP stage(fragment)
57 layout(location=0) out vec4 frag_color;
58
59 float shadowing(vec3 dir, vec3 normal, float slope_var)
60 {
61         float d_dot_n = dot(dir, normal);
62         float a = d_dot_n/sqrt(2*slope_var*(1-d_dot_n*d_dot_n));
63         return exp(-a*a)/(a*3.544908);
64 }
65
66 void main()
67 {
68         vec3 offset = vec3(fwidth(texcoord)/2.0, 0.0);
69         float level = texture(surface, texcoord).x;
70         float depth = level-texture(bottom, texcoord).x;
71         if(depth<0.5)
72                 discard;
73
74         vec2 normal_xy = texture(normals, texcoord).xy*2.0-1.0;
75         vec3 normal = normalize(vec3(normal_xy, sqrt(max(1-dot(normal_xy, normal_xy), 0.0))));
76         float slope_var = texture(variance, texcoord).x;
77
78         vec3 light = normalize(light_sources[0].position.xyz);
79         vec3 look = normalize(world_look);
80         vec3 halfway = normalize(light-look);
81
82         float fresnel_d = 0.02+0.98*pow(1.0-dot(halfway, light), 5.0);
83         vec2 half_slope = halfway.xy/dot(halfway, normal);
84         float sdist = 1.0/(6.2831853*slope_var)*exp(-dot(half_slope, half_slope)/(slope_var*2.0));
85         float geom = 1.0/(1.0+shadowing(light, normal, slope_var)+shadowing(-look, normal, slope_var));
86         float h_dot_n = dot(halfway, normal);
87         float h_dot_n_sq = h_dot_n*h_dot_n;
88
89         vec3 color = light_sources[0].color*fresnel_d*sdist*geom/(4*h_dot_n_sq*h_dot_n_sq*dot(-look, normal));
90
91         float std_dev = sqrt(slope_var);
92         float fresnel_e = 0.02+0.98*pow(1.0+dot(look, normal), 5.0*exp(-2.69*std_dev))/(1+22.7*pow(std_dev, 1.5));
93         vec3 reflect_dir = reflect(look, normal);
94         vec3 env_color = (reflect_dir.z>0 ? vec3(0.34, 0.54, 0.9) : vec3(0.0));
95
96         color += env_color*fresnel_e;
97
98         frag_color = vec4(color, 1.0);
99 }