136 lines
4.0 KiB
GLSL
136 lines
4.0 KiB
GLSL
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);
|
|
} |