// osgOcean Uniforms // ----------------- uniform float osgOcean_DOF_Near; uniform float osgOcean_DOF_Focus; uniform float osgOcean_DOF_Far; uniform float osgOcean_DOF_Clamp; uniform float osgOcean_UnderwaterFogDensity; uniform float osgOcean_AboveWaterFogDensity; uniform vec4 osgOcean_UnderwaterFogColor; uniform vec4 osgOcean_AboveWaterFogColor; uniform float osgOcean_WaterHeight; uniform bool osgOcean_EnableGlare; uniform bool osgOcean_EnableDOF; uniform bool osgOcean_EyeUnderwater; uniform bool osgOcean_EnableUnderwaterScattering; // ------------------- uniform sampler2D uTextureMap; varying vec3 vExtinction; varying vec3 vInScattering; varying vec3 vNormal; varying vec3 vLightDir; varying vec3 vEyeVec; varying float vWorldHeight; uniform sampler2DShadow shadowTexture; float computeDepthBlur(float depth, float focus, float near, float far, float clampval ) { float f; if (depth < focus){ f = (depth - focus)/(focus - near); } else{ f = (depth - focus)/(far - focus); f = clamp(f, 0.0, clampval); } return f * 0.5 + 0.5; } vec4 lighting( vec4 colormap ) { vec4 final_color = gl_LightSource[0].ambient * colormap; float light = shadow2DProj( shadowTexture, gl_TexCoord[7] ).r; vec3 N = normalize(vNormal); vec3 L = normalize(vLightDir); float lambertTerm = dot(N,L); if(lambertTerm > 0.0) { final_color += gl_LightSource[0].diffuse * lambertTerm * colormap * light; vec3 E = normalize(vEyeVec); vec3 R = reflect(-L, N); float specular = pow( max(dot(R, E), 0.0), 2.0 ); final_color += gl_LightSource[0].specular * specular * light; } return final_color; } float computeFogFactor( float density, float fogCoord ) { return exp2(density * fogCoord * fogCoord ); } void main(void) { vec4 final_color; vec4 textureColor = texture2D( uTextureMap, gl_TexCoord[0].st ); // Underwater // +2 tweak here as waves peak above average wave height, // and surface fog becomes visible. if(osgOcean_EyeUnderwater && vWorldHeight < osgOcean_WaterHeight+2.0 ) { final_color = lighting( textureColor ); // mix in underwater light if(osgOcean_EnableUnderwaterScattering) { final_color.rgb = final_color.rgb * vExtinction + vInScattering; } float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord ); // write to depth buffer (actually a GL_LUMINANCE) if(osgOcean_EnableDOF) { float depth = computeDepthBlur(gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp); gl_FragData[1] = vec4(depth); } // color buffer gl_FragData[0] = mix( osgOcean_UnderwaterFogColor, final_color, fogFactor ); } // Above water else { final_color = lighting( textureColor ); float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord ); final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor ); // write to luminance buffer // might not need the IF here, glsl compiler doesn't complain if // you try and write to a FragData index that doesn't exist. But since // Mac GLSL support seems so fussy I'll leave it in. if(osgOcean_EnableGlare) { gl_FragData[1] = vec4(0.0); } // write to color buffer gl_FragData[0] = final_color; } }