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