X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=demos%2Fforestpond%2Fdata%2Fwater.glsl;fp=demos%2Fforestpond%2Fdata%2Fwater.glsl;h=08ba393e3ee854ec36d153d4e3aa97f28978eff4;hp=0000000000000000000000000000000000000000;hb=7efe2d35f5d53c0f086a1b85b7d3dea6a6c709ab;hpb=813301f2b342cd166461b2d266023d0292ba0f87 diff --git a/demos/forestpond/data/water.glsl b/demos/forestpond/data/water.glsl new file mode 100644 index 00000000..08ba393e --- /dev/null +++ b/demos/forestpond/data/water.glsl @@ -0,0 +1,98 @@ +import msp_interface; + +uniform Tessellation +{ + float tessellation_level; +}; + +uniform Region +{ + vec2 scale; + vec2 offset; + float amplitude; +} region; + +uniform sampler2D bottom; +uniform sampler2D surface; +uniform sampler2D normals; +uniform sampler2D variance; + +#pragma MSP stage(vertex) +void main() +{ + gl_Position = world_obj_matrix*vertex; +} + +#pragma MSP stage(tess_control) +layout(vertices=4) out; + +void main() +{ + gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; + + gl_TessLevelInner[0] = tessellation_level; + gl_TessLevelInner[1] = tessellation_level; + for(int i=0; i<4; ++i) + gl_TessLevelOuter[i] = tessellation_level; +} + +#pragma MSP stage(tess_eval) +layout(quads) in; + +void main() +{ + float w0 = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y); + float w1 = gl_TessCoord.x*(1.0-gl_TessCoord.y); + float w2 = gl_TessCoord.x*gl_TessCoord.y; + float w3 = (1.0-gl_TessCoord.x)*gl_TessCoord.y; + 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; + out vec2 texcoord = pos.xy*region.scale+region.offset; + pos.z = textureLod(surface, texcoord, 0).x*region.amplitude-0.01; + out vec3 world_look = pos.xyz-world_eye_matrix[3].xyz; + gl_Position = clip_eye_matrix*eye_world_matrix*pos; +} + +#pragma MSP stage(fragment) +layout(location=0) out vec4 frag_color; + +float shadowing(vec3 dir, vec3 normal, float slope_var) +{ + float d_dot_n = dot(dir, normal); + float a = d_dot_n/sqrt(2*slope_var*(1-d_dot_n*d_dot_n)); + return exp(-a*a)/(a*3.544908); +} + +void main() +{ + vec3 offset = vec3(fwidth(texcoord)/2.0, 0.0); + float level = texture(surface, texcoord).x; + float depth = level-texture(bottom, texcoord).x; + if(depth<0.5) + discard; + + vec2 normal_xy = texture(normals, texcoord).xy*2.0-1.0; + vec3 normal = normalize(vec3(normal_xy, sqrt(max(1-dot(normal_xy, normal_xy), 0.0)))); + float slope_var = texture(variance, texcoord).x; + + vec3 light = normalize(light_sources[0].position.xyz); + vec3 look = normalize(world_look); + vec3 halfway = normalize(light-look); + + float fresnel_d = 0.02+0.98*pow(1.0-dot(halfway, light), 5.0); + vec2 half_slope = halfway.xy/dot(halfway, normal); + float sdist = 1.0/(6.2831853*slope_var)*exp(-dot(half_slope, half_slope)/(slope_var*2.0)); + float geom = 1.0/(1.0+shadowing(light, normal, slope_var)+shadowing(-look, normal, slope_var)); + float h_dot_n = dot(halfway, normal); + float h_dot_n_sq = h_dot_n*h_dot_n; + + vec3 color = light_sources[0].color*fresnel_d*sdist*geom/(4*h_dot_n_sq*h_dot_n_sq*dot(-look, normal)); + + float std_dev = sqrt(slope_var); + 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)); + vec3 reflect_dir = reflect(look, normal); + vec3 env_color = (reflect_dir.z>0 ? vec3(0.34, 0.54, 0.9) : vec3(0.0)); + + color += env_color*fresnel_e; + + frag_color = vec4(color, 1.0); +}