DYTSrouce/resources/shaders/osgOcean_ocean_scene.frag
2025-01-04 12:12:51 +08:00

125 lines
3.3 KiB
GLSL

// 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;
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[osgOcean_LightID].ambient * colormap;
vec3 N = normalize(vNormal);
vec3 L = normalize(vLightDir);
float lambertTerm = dot(N,L);
if(lambertTerm > 0.0)
{
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(-L, N);
float specular = pow( max(dot(R, E), 0.0), 2.0 );
final_color += gl_LightSource[osgOcean_LightID].specular * specular;
}
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;
}
}