DYT/Tool/osgOcean/bin/resources/shaders/osgOcean_ocean_surface.vert

136 lines
4.0 KiB
GLSL
Raw Normal View History

2024-11-22 15:19:31 +00:00
uniform mat4 osg_ViewMatrixInverse;
uniform vec3 osgOcean_Eye;
uniform vec3 osgOcean_NoiseCoords0;
uniform vec3 osgOcean_NoiseCoords1;
uniform vec4 osgOcean_WaveTop;
uniform vec4 osgOcean_WaveBot;
uniform float osgOcean_FoamScale;
uniform float osgOcean_FrameTime;
// Used to blend the waves into a sinus curve near the shore
uniform sampler2D osgOcean_Heightmap;
uniform bool osgOcean_EnableHeightmap;
uniform bool osgOcean_EnableUnderwaterScattering;
uniform float osgOcean_WaterHeight;
uniform vec3 osgOcean_UnderwaterAttenuation;
uniform vec4 osgOcean_UnderwaterDiffuse;
varying vec4 vVertex;
varying vec4 vWorldVertex;
varying vec3 vNormal;
varying vec3 vViewerDir;
varying vec3 vLightDir;
varying vec3 vExtinction;
varying vec3 vInScattering;
varying vec3 vWorldViewDir;
varying vec3 vWorldNormal;
varying float height;
mat3 get3x3Matrix( mat4 m )
{
mat3 result;
result[0][0] = m[0][0];
result[0][1] = m[0][1];
result[0][2] = m[0][2];
result[1][0] = m[1][0];
result[1][1] = m[1][1];
result[1][2] = m[1][2];
result[2][0] = m[2][0];
result[2][1] = m[2][1];
result[2][2] = m[2][2];
return result;
}
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
{
float viewDist = length(eye-worldVertex);
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
// Need to compute accurate kd constant.
// const vec3 kd = vec3(0.001, 0.001, 0.001);
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
}
// -------------------------------
// Main Program
// -------------------------------
void main( void )
{
// Transform the vertex
vec4 inputVertex = gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
// Blend the wave into a sinus curve near the shore
// note that this requires a vertex shader texture lookup
// vertex has to be transformed a second time with the new z-value
if (osgOcean_EnableHeightmap)
{
vec2 screenCoords = gl_Position.xy / gl_Position.w;
height = pow(clamp(1.0 - texture2D(osgOcean_Heightmap, clamp(screenCoords * 0.5 + 0.5, 0.0, 1.0)).x, 0.0, 1.0), 32.0);
inputVertex = vec4(gl_Vertex.x,
gl_Vertex.y,
mix(gl_Vertex.z, sin(osgOcean_FrameTime), height),
gl_Vertex.w);
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
}
// -----------------------------------------------------------
// In object space
vVertex = inputVertex;
vLightDir = normalize( vec3( gl_ModelViewMatrixInverse * ( gl_LightSource[osgOcean_LightID].position ) ) );
vViewerDir = gl_ModelViewMatrixInverse[3].xyz - inputVertex.xyz;
vNormal = normalize(gl_Normal);
vec4 waveColorDiff = osgOcean_WaveTop - osgOcean_WaveBot;
gl_FrontColor = waveColorDiff *
clamp((gl_Vertex.z + osgOcean_Eye.z) * 0.1111111 + vNormal.z - 0.4666667, 0.0, 1.0) + osgOcean_WaveBot;
// -------------------------------------------------------------
mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
mat3 modelMatrix3x3 = get3x3Matrix( modelMatrix );
// world space
vWorldVertex = modelMatrix * gl_Vertex;
vWorldNormal = modelMatrix3x3 * gl_Normal;
vWorldViewDir = vWorldVertex.xyz - osgOcean_Eye.xyz;
// ------------- Texture Coords ---------------------------------
// Normal Map Coords
gl_TexCoord[0].xy = ( gl_Vertex.xy * osgOcean_NoiseCoords0.z + osgOcean_NoiseCoords0.xy );
gl_TexCoord[0].zw = ( gl_Vertex.xy * osgOcean_NoiseCoords1.z + osgOcean_NoiseCoords1.xy );
gl_TexCoord[0].y = -gl_TexCoord[0].y;
gl_TexCoord[0].w = -gl_TexCoord[0].w;
// Foam coords
gl_TexCoord[1].st = gl_Vertex.xy * osgOcean_FoamScale;
// Fog coords
gl_FogFragCoord = gl_Position.z;
if (osgOcean_EnableUnderwaterScattering)
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering);
}