Changes to GLSL files for OpenGL

This commit is contained in:
LuisAntonRebollo 2014-04-13 19:48:51 +02:00
parent 2142d452d4
commit 6aea37b407
98 changed files with 3366 additions and 2686 deletions

View file

@ -31,7 +31,7 @@
#define FRESNEL_BIAS miscParams[0]
#define FRESNEL_POWER miscParams[1]
#define CLARITY miscParams[2]
#define ISRIVER miscParams[3]
#define ISRIVER miscParams[3]
// reflectParams
#define REFLECT_PLANE_Z reflectParams[0]
@ -45,40 +45,49 @@
#define DISTORT_FULL_DEPTH distortionParams[2]
// ConnectData.misc
#define LIGHT_VEC misc.xyz
#define WORLD_Z objPos.w
#define LIGHT_VEC IN_misc.xyz
#define WORLD_Z IN_objPos.w
// specularParams
#define SPEC_POWER specularParams[3]
#define SPEC_COLOR specularParams.xyz
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
varying vec4 rippleTexCoord01;
in vec4 rippleTexCoord01;
#define IN_rippleTexCoord01 rippleTexCoord01
// TexCoord 2 for ripple texture lookup
varying vec2 rippleTexCoord2;
in vec2 rippleTexCoord2;
#define IN_rippleTexCoord2 rippleTexCoord2
// Screenspace vert position BEFORE wave transformation
varying vec4 posPreWave;
in vec4 posPreWave;
#define IN_posPreWave posPreWave
// Screenspace vert position AFTER wave transformation
varying vec4 posPostWave;
in vec4 posPostWave;
#define IN_posPostWave posPostWave
// Worldspace unit distance/depth of this vertex/pixel
varying float pixelDist;
// Objectspace vert position BEFORE wave transformation
// w coord is world space z position.
varying vec4 objPos;
in float pixelDist;
#define IN_pixelDist pixelDist
varying vec3 misc;
in vec4 objPos;
#define IN_objPos objPos
in vec3 misc;
#define IN_misc misc
//-----------------------------------------------------------------------------
// approximate Fresnel function
//-----------------------------------------------------------------------------
float fresnel(float NdotV, float bias, float power)
{
return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0.0)), power);
return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
}
//-----------------------------------------------------------------------------
@ -89,7 +98,7 @@ uniform sampler2D bumpMap;
uniform sampler2D reflectMap;
uniform sampler2D refractBuff;
uniform samplerCube skyMap;
//uniform sampler foamMap;
//uniform sampler2D foamMap;
uniform vec4 baseColor;
uniform vec4 miscParams;
uniform vec4 reflectParams;
@ -98,8 +107,9 @@ uniform vec3 eyePos;
uniform vec3 distortionParams;
uniform vec3 fogData;
uniform vec4 fogColor;
uniform vec3 rippleMagnitude;
uniform vec4 rippleMagnitude;
uniform vec4 specularParams;
uniform mat4 modelMat;
//-----------------------------------------------------------------------------
// Main
@ -107,31 +117,35 @@ uniform vec4 specularParams;
void main()
{
// Modulate baseColor by the ambientColor.
vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1.0 );
vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 );
// Get the bumpNorm...
vec3 bumpNorm = ( texture2D( bumpMap, rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
bumpNorm += ( texture2D( bumpMap, rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
bumpNorm += ( texture2D( bumpMap, rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
bumpNorm = normalize( bumpNorm );
bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w );
// We subtract a little from it so that we don't
// distort where the water surface intersects the
// camera near plane.
float distortAmt = saturate( pixelDist / 1.0 ) * 0.8;
float distortAmt = saturate( IN_pixelDist / 1.0 ) * 0.8;
vec4 distortPos = posPostWave;
vec4 distortPos = IN_posPostWave;
distortPos.xy += bumpNorm.xy * distortAmt;
#ifdef UNDERWATER
gl_FragColor = texture2DProj( refractBuff, distortPos.xyz );
OUT_FragColor0 = hdrEncode( textureProj( refractBuff, distortPos ) );
#else
vec3 eyeVec = objPos.xyz - eyePos;
vec3 reflectionVec = reflect( eyeVec, normalize(bumpNorm) );
vec3 eyeVec = IN_objPos.xyz - eyePos;
eyeVec = tMul( mat3(modelMat), eyeVec );
vec3 reflectionVec = reflect( eyeVec, bumpNorm );
// Color that replaces the reflection color when we do not
// have one that is appropriate.
vec4 fakeColor = vec4(ambientColor,1.0);
vec4 fakeColor = vec4(ambientColor,1);
// Use fakeColor for ripple-normals that are angled towards the camera
eyeVec = -eyeVec;
@ -140,58 +154,61 @@ void main()
float fakeColorAmt = ang;
// Get reflection map color
vec4 refMapColor = texture2DProj( reflectMap, distortPos );
vec4 refMapColor = hdrDecode( textureProj( reflectMap, distortPos ) );
// If we do not have a reflection texture then we use the cubemap.
refMapColor = mix( refMapColor, textureCube( skyMap, -reflectionVec ), NO_REFLECT );
refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT );
// Combine reflection color and fakeColor.
vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt );
//return refMapColor;
// Get refract color
vec4 refractColor = texture2DProj( refractBuff, distortPos.xyz );
vec4 refractColor = hdrDecode( textureProj( refractBuff, distortPos ) );
// calc "diffuse" color by lerping from the water color
// to refraction image based on the water clarity.
vec4 diffuseColor = mix( refractColor, waterBaseColor, 1.0 - CLARITY );
vec4 diffuseColor = mix( refractColor, waterBaseColor, 1.0f - CLARITY );
// fresnel calculation
float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
//return vec4( fresnelTerm.rrr, 1 );
// Also scale the frensel by our distance to the
// water surface. This removes the hard reflection
// when really close to the water surface.
fresnelTerm *= saturate( pixelDist - 0.1 );
fresnelTerm *= saturate( IN_pixelDist - 0.1 );
// Combine the diffuse color and reflection image via the
// fresnel term and set out output color.
gl_FragColor = mix( diffuseColor, reflectColor, fresnelTerm );
vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm );
#ifdef WATER_SPEC
// Get some specular reflection.
vec3 newbump = bumpNorm;
newbump.xy *= 3.5;
newbump = normalize( bumpNorm );
vec3 halfAng = normalize( eyeVec + -LIGHT_VEC );
half3 halfAng = normalize( eyeVec + -LIGHT_VEC );
float specular = saturate( dot( newbump, halfAng ) );
specular = pow( specular, SPEC_POWER );
gl_FragColor.rgb = gl_FragColor.rgb + ( SPEC_COLOR * specular.xxx );
OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx );
#else // Disable fogging if spec is on because otherwise we run out of instructions.
// Fog it.
float factor = computeSceneFog( eyePos,
objPos.xyz,
IN_objPos.xyz,
WORLD_Z,
fogData.x,
fogData.y,
fogData.z );
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
#endif
//OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
#endif
OUT_FragColor0 = OUT;
#endif
}

View file

@ -27,23 +27,30 @@
//-----------------------------------------------------------------------------
// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
varying vec4 rippleTexCoord01;
out vec4 rippleTexCoord01;
#define OUT_rippleTexCoord01 rippleTexCoord01
// TexCoord 2 for ripple texture lookup
varying vec2 rippleTexCoord2;
out vec2 rippleTexCoord2;
#define OUT_rippleTexCoord2 rippleTexCoord2
// Screenspace vert position BEFORE wave transformation
varying vec4 posPreWave;
out vec4 posPreWave;
#define OUT_posPreWave posPreWave
// Screenspace vert position AFTER wave transformation
varying vec4 posPostWave;
out vec4 posPostWave;
#define OUT_posPostWave posPostWave
// Worldspace unit distance/depth of this vertex/pixel
varying float pixelDist;
out float pixelDist;
#define OUT_pixelDist pixelDist
varying vec4 objPos;
out vec4 objPos;
#define OUT_objPos objPos
varying vec3 misc;
out vec3 misc;
#define OUT_misc misc
//-----------------------------------------------------------------------------
// Uniforms
@ -63,49 +70,56 @@ uniform float gridElementSize;
uniform float elapsedTime;
uniform float undulateMaxDist;
in vec4 vPosition;
in vec3 vNormal;
in vec4 vColor;
in vec2 vTexCoord0;
in vec4 vTexCoord1;
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
void main()
{
vec4 position = gl_Vertex;
vec3 normal = gl_Normal;
vec2 undulateData = gl_MultiTexCoord0.st;
vec4 horizonFactor = gl_MultiTexCoord1;
vec4 IN_position = vPosition;
vec3 IN_normal = vNormal;
vec2 IN_undulateData = vTexCoord0;
vec4 IN_horizonFactor = vTexCoord1;
vec4 OUT_hpos = vec4(0);
// use projection matrix for reflection / refraction texture coords
mat4 texGen = mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5,
0.0, -0.5, 0.0, 0.5,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
// Move the vertex based on the horizonFactor if specified to do so for this vert.
//if ( horizonFactor.z > 0.0 )
//{
//vec2 offsetXY = eyePos.xy - mod(eyePos.xy, gridElementSize);
//position.xy += offsetXY;
//undulateData += offsetXY;
//}
// if ( IN_horizonFactor.z > 0 )
// {
// vec2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize;
// IN_position.xy += offsetXY;
// IN_undulateData += offsetXY;
// }
vec4 worldPos = modelMat * position;
//fogPos = position.xyz;
position.z = mix( position.z, eyePos.z, horizonFactor.x );
objPos.xyz = position.xyz;
objPos.w = worldPos.z;
vec4 worldPos = tMul( modelMat, IN_position );
IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x );
//OUT_objPos = worldPos;
OUT_objPos.xyz = IN_position.xyz;
OUT_objPos.w = worldPos.z;
// Send pre-undulation screenspace position
posPreWave = modelview * position;
posPreWave = texGen * posPreWave;
OUT_posPreWave = tMul( modelview, IN_position );
OUT_posPreWave = tMul( texGen, OUT_posPreWave );
// Calculate the undulation amount for this vertex.
vec2 undulatePos = (modelMat * vec4( undulateData.xy, 0, 1 )).xy;
//if ( undulatePos.x < 0.0 )
//undulatePos = position.xy;
float undulateAmt = 0.0;
vec2 undulatePos = tMul( modelMat, vec4( IN_undulateData.xy, 0, 1 ) ).xy;
//if ( undulatePos.x < 0 )
// undulatePos = IN_position.xy;
float undulateAmt = 0.0;
undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
undulatePos.x * waveDir[0].x +
undulatePos.y * waveDir[0].y );
@ -114,118 +128,84 @@ void main()
undulatePos.y * waveDir[1].y );
undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
undulatePos.x * waveDir[2].x +
undulatePos.y * waveDir[2].y );
float undulateFade = 1.0;
// Scale down wave magnitude amount based on distance from the camera.
float dist = length( position.xyz - eyePos );
undulatePos.y * waveDir[2].y );
float undulateFade = 1;
// Scale down wave magnitude amount based on distance from the camera.
float dist = distance( IN_position.xyz, eyePos );
dist = clamp( dist, 1.0, undulateMaxDist );
undulateFade *= ( 1.0 - dist / undulateMaxDist );
undulateFade *= ( 1 - dist / undulateMaxDist );
// Also scale down wave magnitude if the camera is very very close.
undulateFade *= saturate( ( length( position.xyz - eyePos ) - 0.5 ) / 10.0 );
undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 );
undulateAmt *= undulateFade;
//#endif
//undulateAmt = 0;
// Apply wave undulation to the vertex.
posPostWave = position;
posPostWave.xyz += normal.xyz * undulateAmt;
OUT_posPostWave = IN_position;
OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt;
// Save worldSpace position of this pixel/vert
//worldPos = posPostWave.xyz;
//OUT_worldPos = OUT_posPostWave.xyz;
//OUT_worldPos = tMul( modelMat, OUT_posPostWave.xyz );
//OUT_worldPos.z += objTrans[2][2]; //91.16;
//worldSpaceZ = ( modelMat * vec4(fogPos,1.0) ).z;
//if ( horizonFactor.x > 0.0 )
//{
//vec3 awayVec = normalize( fogPos.xyz - eyePos );
//fogPos.xy += awayVec.xy * 1000.0;
//}
// OUT_misc.w = tMul( modelMat, OUT_fogPos ).z;
// if ( IN_horizonFactor.x > 0 )
// {
// vec3 awayVec = normalize( OUT_fogPos.xyz - eyePos );
// OUT_fogPos.xy += awayVec.xy * 1000.0;
// }
// Convert to screen
posPostWave = modelview * posPostWave;
OUT_posPostWave = tMul( modelview, OUT_posPostWave ); // tMul( modelview, vec4( OUT_posPostWave.xyz, 1 ) );
// Setup the OUT position symantic variable
gl_Position = posPostWave;
//gl_Position.z = mix(gl_Position.z, gl_Position.w, horizonFactor.x);
OUT_hpos = OUT_posPostWave; // tMul( modelview, vec4( IN_position.xyz, 1 ) ); //vec4( OUT_posPostWave.xyz, 1 );
//OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x );
// Save world space camera dist/depth of the outgoing pixel
pixelDist = gl_Position.z;
OUT_pixelDist = OUT_hpos.z;
// Convert to reflection texture space
posPostWave = texGen * posPostWave;
OUT_posPostWave = tMul( texGen, OUT_posPostWave );
vec2 txPos = undulatePos;
if ( horizonFactor.x > 0.0 )
if ( bool(IN_horizonFactor.x) )
txPos = normalize( txPos ) * 50000.0;
// set up tex coordinates for the 3 interacting normal maps
rippleTexCoord01.xy = txPos * rippleTexScale[0];
rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
// set up tex coordinates for the 3 interacting normal maps
OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0];
OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
mat2 texMat;
texMat[0][0] = rippleMat[0].x;
texMat[1][0] = rippleMat[0].y;
texMat[0][1] = rippleMat[0].z;
texMat[1][1] = rippleMat[0].w;
rippleTexCoord01.xy = texMat * rippleTexCoord01.xy ;
OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy );
rippleTexCoord01.zw = txPos * rippleTexScale[1];
rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1];
OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
texMat[0][0] = rippleMat[1].x;
texMat[1][0] = rippleMat[1].y;
texMat[0][1] = rippleMat[1].z;
texMat[1][1] = rippleMat[1].w;
rippleTexCoord01.zw = texMat * rippleTexCoord01.zw ;
OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw );
rippleTexCoord2.xy = txPos * rippleTexScale[2];
rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2];
OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
texMat[0][0] = rippleMat[2].x;
texMat[1][0] = rippleMat[2].y;
texMat[0][1] = rippleMat[2].z;
texMat[1][1] = rippleMat[2].w;
rippleTexCoord2.xy = texMat * rippleTexCoord2.xy ;
/*rippleTexCoord01.xy = mix( position.xy * rippleTexScale[0], txPos.xy * rippleTexScale[0], horizonFactor.x );
rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
rippleTexCoord01.zw = mix( position.xy * rippleTexScale[1], txPos.xy * rippleTexScale[1], horizonFactor.x );
rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
rippleTexCoord2.xy = mix( position.xy * rippleTexScale[2], txPos.xy * rippleTexScale[2], horizonFactor.x );
rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z; */
/*rippleTexCoord01.xy = mix( position.xy * rippleTexScale[0], txPos.xy * rippleTexScale[0], horizonFactor.x );
rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
mat2 texMat;
texMat[0][0] = rippleMat[0].x;
texMat[1][0] = rippleMat[0].y;
texMat[0][1] = rippleMat[0].z;
texMat[1][1] = rippleMat[0].w;
rippleTexCoord01.xy = texMat * rippleTexCoord01.xy ;
rippleTexCoord01.zw = mix( position.xy * rippleTexScale[1], txPos.xy * rippleTexScale[1], horizonFactor.x );
rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
texMat[0][0] = rippleMat[1].x;
texMat[1][0] = rippleMat[1].y;
texMat[0][1] = rippleMat[1].z;
texMat[1][1] = rippleMat[1].w;
rippleTexCoord01.zw = texMat * rippleTexCoord01.zw ;
rippleTexCoord2.xy = mix( position.xy * rippleTexScale[2], txPos.xy * rippleTexScale[2], horizonFactor.x );
rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
texMat[0][0] = rippleMat[2].x;
texMat[1][0] = rippleMat[2].y;
texMat[0][1] = rippleMat[2].z;
texMat[1][1] = rippleMat[2].w;
rippleTexCoord2.xy = texMat * rippleTexCoord2.xy ;*/
OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy );
#ifdef WATER_SPEC
@ -234,8 +214,8 @@ void main()
vec3 normal;
for ( int i = 0; i < 3; i++ )
{
binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulateData.x + waveDir[i].y * undulateData.y + elapsedTime * waveData[i].x );
tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulateData.x + waveDir[i].y * undulateData.y + elapsedTime * waveData[i].x );
binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x );
tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x );
}
binormal = normalize( binormal );
@ -246,15 +226,19 @@ void main()
worldToTangent[0] = binormal;
worldToTangent[1] = tangent;
worldToTangent[2] = normal;
worldToTangent = transpose(worldToTangent);
misc.xyz = inLightVec * modelMat;
misc.xyz = worldToTangent * misc.xyz;
OUT_misc.xyz = tMul( inLightVec, modelMat );
OUT_misc.xyz = tMul( worldToTangent, OUT_misc.xyz );
#else
misc.xyz = inLightVec;
OUT_misc.xyz = inLightVec;
#endif
gl_Position = OUT_hpos;
correctSSP(gl_Position);
}

View file

@ -20,6 +20,7 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h"
#include "../../gl/torque.glsl"
@ -27,10 +28,7 @@
// Defines
//-----------------------------------------------------------------------------
#ifdef TORQUE_BASIC_LIGHTING
#define BASIC
#endif
#define PIXEL_DIST IN_rippleTexCoord2.z
// miscParams
#define FRESNEL_BIAS miscParams[0]
#define FRESNEL_POWER miscParams[1]
@ -57,33 +55,54 @@
#define DISTORT_FULL_DEPTH distortionParams[2]
// foamParams
#define FOAM_SCALE foamParams[0]
#define FOAM_OPACITY foamParams[0]
#define FOAM_MAX_DEPTH foamParams[1]
#define FOAM_AMBIENT_LERP foamParams[2]
#define FOAM_RIPPLE_INFLUENCE foamParams[3]
// Incoming data
// Worldspace position of this pixel
varying vec3 worldPos;
// specularParams
#define SPEC_POWER specularParams[3]
#define SPEC_COLOR specularParams.xyz
//-----------------------------------------------------------------------------
// Structures
//-----------------------------------------------------------------------------
//ConnectData IN
in vec4 hpos;
// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
varying vec4 rippleTexCoord01;
in vec4 rippleTexCoord01;
// TexCoord 2 for ripple texture lookup
varying vec2 rippleTexCoord2;
// xy is TexCoord 2 for ripple texture lookup
// z is the Worldspace unit distance/depth of this vertex/pixel
// w is amount of the crestFoam ( more at crest of waves ).
in vec4 rippleTexCoord2;
// Screenspace vert position BEFORE wave transformation
varying vec4 posPreWave;
in vec4 posPreWave;
// Screenspace vert position AFTER wave transformation
varying vec4 posPostWave;
in vec4 posPostWave;
// Worldspace unit distance/depth of this vertex/pixel
varying float pixelDist;
// Objectspace vert position BEFORE wave transformation
// w coord is world space z position.
in vec4 objPos;
varying vec3 fogPos;
in vec4 foamTexCoords;
varying float worldSpaceZ;
in mat3 tangentMat;
varying vec4 foamTexCoords;
#define IN_hpos hpos
#define IN_rippleTexCoord01 rippleTexCoord01
#define IN_rippleTexCoord2 rippleTexCoord2
#define IN_posPreWave posPreWave
#define IN_posPostWave posPostWave
#define IN_objPos objPos
#define IN_foamTexCoords foamTexCoords
#define IN_tangentMat tangentMat
//-----------------------------------------------------------------------------
// approximate Fresnel function
@ -100,10 +119,10 @@ uniform sampler2D bumpMap;
uniform sampler2D prepassTex;
uniform sampler2D reflectMap;
uniform sampler2D refractBuff;
uniform samplerCUBE skyMap;
uniform samplerCube skyMap;
uniform sampler2D foamMap;
uniform vec4 specularColor;
uniform float specularPower;
uniform sampler1D depthGradMap;
uniform vec4 specularParams;
uniform vec4 baseColor;
uniform vec4 miscParams;
uniform vec2 fogParams;
@ -112,64 +131,45 @@ uniform vec3 reflectNormal;
uniform vec2 wetnessParams;
uniform float farPlaneDist;
uniform vec3 distortionParams;
//uniform vec4 renderTargetParams;
uniform vec2 foamParams;
uniform vec3 foamColorMod;
uniform vec4 foamParams;
uniform vec3 ambientColor;
uniform vec3 eyePos;
uniform vec3 inLightVec;
uniform vec3 eyePos; // This is in object space!
uniform vec3 fogData;
uniform vec4 fogColor;
//uniform vec4 rtParams;
uniform vec2 rtScale;
uniform vec2 rtHalfPixel;
uniform vec4 rtOffset;
uniform vec3 rippleMagnitude;
uniform vec4 rippleMagnitude;
uniform vec4 rtParams1;
uniform float depthGradMax;
uniform vec3 inLightVec;
uniform mat4 modelMat;
uniform vec4 sunColor;
uniform float sunBrightness;
uniform float reflectivity;
//-----------------------------------------------------------------------------
// Main
//-----------------------------------------------------------------------------
void main()
{
vec4 rtParams = vec4( rtOffset.x / rtOffset.z + rtHalfPixel.x,
rtOffset.y / rtOffset.w + rtHalfPixel.x,
rtScale );
// Modulate baseColor by the ambientColor.
vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 );
// Get the bumpNorm...
vec3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ) * 2.0 - 1.0 ) * rippleMagnitude.x;
bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord01.zw ) * 2.0 - 1.0 ) * rippleMagnitude.y;
bumpNorm += ( tex2D( bumpMap, IN.rippleTexCoord2 ) * 2.0 - 1.0 ) * rippleMagnitude.z;
// JCF: this was here, but seems to make the dot product against the bump
// normal we use below for cubeMap fade-in to be less reliable.
//bumpNorm.xy *= 0.75;
//bumpNorm = normalize( bumpNorm );
//return vec4( bumpNorm, 1 );
vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
bumpNorm = normalize( bumpNorm );
bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w );
bumpNorm = tMul( bumpNorm, IN_tangentMat );
// Get depth of the water surface (this pixel).
// Convert from WorldSpace to EyeSpace.
float pixelDepth = IN.pixelDist / farPlaneDist;
float pixelDepth = PIXEL_DIST / farPlaneDist;
// Get prepass depth at the undistorted pixel.
//vec4 prepassCoord = IN.posPostWave;
//prepassCoord.xy += renderTargetParams.xy;
vec2 prepassCoord = viewportCoordToRenderTarget( IN.posPostWave, rtParams );
//vec2 prepassCoord = IN.posPostWave.xy;
vec2 prepassCoord = viewportCoordToRenderTarget( IN_posPostWave, rtParams1 );
float startDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w;
//return vec4( startDepth.rrr, 1 );
float startDepth = prepassUncondition( prepassTex, prepassCoord ).w;
// The water depth in world units of the undistorted pixel.
float startDelta = ( startDepth - pixelDepth );
if ( startDelta <= 0.0 )
{
//return vec4( 1, 0, 0, 1 );
startDelta = 0;
}
startDelta = max( startDelta, 0.0 );
startDelta *= farPlaneDist;
// Calculate the distortion amount for the water surface.
@ -177,23 +177,22 @@ void main()
// We subtract a little from it so that we don't
// distort where the water surface intersects the
// camera near plane.
float distortAmt = saturate( ( IN.pixelDist - DISTORT_START_DIST ) / DISTORT_END_DIST );
float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
// Scale down distortion in shallow water.
distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH );
//distortAmt = 0;
// Do the intial distortion... we might remove it below.
vec2 distortDelta = bumpNorm.xy * distortAmt;
vec4 distortPos = IN.posPostWave;
vec4 distortPos = IN_posPostWave;
distortPos.xy += distortDelta;
prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams );
//prepassCoord = distortPos;
//prepassCoord.xy += renderTargetParams.xy;
prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
// Get prepass depth at the position of this distorted pixel.
float prepassDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w;
float prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w;
if ( prepassDepth > 0.99 )
prepassDepth = 5.0;
float delta = ( prepassDepth - pixelDepth ) * farPlaneDist;
@ -202,7 +201,7 @@ void main()
// If we got a negative delta then the distorted
// sample is above the water surface. Mask it out
// by removing the distortion.
distortPos = IN.posPostWave;
distortPos = IN_posPostWave;
delta = startDelta;
distortAmt = 0;
}
@ -212,20 +211,20 @@ void main()
if ( diff < 0 )
{
distortAmt = saturate( ( IN.pixelDist - DISTORT_START_DIST ) / DISTORT_END_DIST );
distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
distortAmt *= saturate( delta / DISTORT_FULL_DEPTH );
distortDelta = bumpNorm.xy * distortAmt;
distortPos = IN.posPostWave;
distortPos = IN_posPostWave;
distortPos.xy += distortDelta;
prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams );
//prepassCoord = distortPos;
//prepassCoord.xy += renderTargetParams.xy;
prepassCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
// Get prepass depth at the position of this distorted pixel.
prepassDepth = prepassUncondition( tex2D( prepassTex, prepassCoord ) ).w;
prepassDepth = prepassUncondition( prepassTex, prepassCoord ).w;
if ( prepassDepth > 0.99 )
prepassDepth = 5.0;
delta = ( prepassDepth - pixelDepth ) * farPlaneDist;
}
@ -234,133 +233,78 @@ void main()
// If we got a negative delta then the distorted
// sample is above the water surface. Mask it out
// by removing the distortion.
distortPos = IN.posPostWave;
distortPos = IN_posPostWave;
delta = startDelta;
distortAmt = 0;
}
}
//return vec4( prepassDepth.rrr, 1 );
vec4 temp = IN.posPreWave;
vec4 temp = IN_posPreWave;
temp.xy += bumpNorm.xy * distortAmt;
vec2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams );
vec2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 );
vec2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams );
vec2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
// Use cubemap colors instead of reflection colors in several cases...
// First lookup the CubeMap color
// JCF: which do we want to use here, the reflectNormal or the bumpNormal
// neithor of them is exactly right and how can we combine the two together?
//bumpNorm = reflectNormal;
vec3 eyeVec = IN.worldPos - eyePos;
vec4 fakeColor = vec4(ambientColor,1);
vec3 eyeVec = IN_objPos.xyz - eyePos;
eyeVec = tMul( mat3(modelMat), eyeVec );
eyeVec = tMul( IN_tangentMat, eyeVec );
vec3 reflectionVec = reflect( eyeVec, bumpNorm );
//vec4 cubeColor = texCUBE( skyMap, reflectionVec );
//return cubeColor;
// JCF: using ambient color instead of cubeColor for waterPlane, how do we still use the cubemap for rivers?
vec4 cubeColor = vec4(ambientColor,1);
//cubeColor.rgb = vec3( 0, 0, 1 );
// Use cubeColor for waves that are angled towards camera
// Use fakeColor for ripple-normals that are angled towards the camera
eyeVec = -eyeVec;
eyeVec = normalize( eyeVec );
float ang = saturate( dot( eyeVec, bumpNorm ) );
float cubeAmt = ang;
float fakeColorAmt = ang;
//float rplaneDist = (reflectPlane.x * IN.pos.x + reflectPlane.y * IN.pos.y + reflectPlane.z * IN.pos.z) + reflectPlane.w;
//rplaneDist = saturate( abs( rplaneDist ) / 0.5 );
//#ifdef RIVER
// for verts far from the reflect plane z position
float rplaneDist = abs( REFLECT_PLANE_Z - IN.worldPos.z );
float rplaneDist = abs( REFLECT_PLANE_Z - IN_objPos.w );
rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 );
//rplaneDist = REFLECT_PLANE_Z / eyePos.z;
rplaneDist *= ISRIVER;
cubeAmt = max( cubeAmt, rplaneDist );
//#endif
//rplaneDist = IN.worldPos.z / eyePos.z;
//return vec4( rplaneDist.rrr, 1 );
//return vec4( (reflectParams[REFLECT_PLANE_Z] / 86.0 ).rrr, 1 );
// and for verts farther from the camera
//float cubeAmt = ( eyeDist - reflectParams[REFLECT_MIN_DIST] ) / ( reflectParams[REFLECT_MAX_DIST] - reflectParams[REFLECT_MIN_DIST] );
//cubeAmt = saturate ( cubeAmt );
//float temp = ( eyeDist - reflectParams[REFLECT_MIN_DIST] ) / ( reflectParams[REFLECT_MAX_DIST] - reflectParams[REFLECT_MIN_DIST] );
//temp = saturate ( temp );
// If the camera is very very close to the reflect plane.
//float eyeToPlaneDist = eyePos.z - REFLECT_PLANE_Z; // dot( reflectNormal, eyePos ) + REFLECT_PLANE_Z;
//eyeToPlaneDist = abs( eyeToPlaneDist );
//eyeToPlaneDist = 1.0 - saturate( abs( eyeToPlaneDist ) / 1 );
//return vec4( eyeToPlaneDist.rrr, 1 );
//cubeAmt = max( cubeAmt, eyeToPlaneDist );
//cubeAmt = max( cubeAmt, rplaneDist );
//cubeAmt = max( cubeAmt, ang );
//cubeAmt = max( cubeAmt, rplaneDist );
//cubeAmt = max( cubeAmt, IN.depth.w );
// All cubemap if fullReflect is specifically user disabled
cubeAmt = max( cubeAmt, NO_REFLECT );
fakeColorAmt = max( fakeColorAmt, rplaneDist );
#ifndef UNDERWATER
// Get foam color and amount
IN.foamTexCoords.xy += distortDelta * 0.5;
IN.foamTexCoords.zw += distortDelta * 0.5;
vec2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE;
vec4 IN_foamTexCoords = IN_foamTexCoords;
IN_foamTexCoords.xy += foamRippleOffset;
IN_foamTexCoords.zw += foamRippleOffset;
vec4 foamColor = tex2D( foamMap, IN.foamTexCoords.xy );
foamColor += tex2D( foamMap, IN.foamTexCoords.zw );
//foamColor += tex2D( foamMap, IN.rippleTexCoord2 ) * 0.3;
vec4 foamColor = texture( foamMap, IN_foamTexCoords.xy );
foamColor += texture( foamMap, IN_foamTexCoords.zw );
foamColor = saturate( foamColor );
// Modulate foam color by ambient color so we don't have glowing white
// foam at night.
foamColor.rgb = lerp( foamColor.rgb, ambientColor.rgb, foamColorMod.rgb );
// Modulate foam color by ambient color
// so we don't have glowing white foam at night.
foamColor.rgb = mix( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP );
float foamDelta = saturate( delta / FOAM_MAX_DEPTH );
float foamAmt = 1.0 - foamDelta;
float foamAmt = 1 - pow( foamDelta, 2 );
// Fade out the foam in very very low depth,
// this improves the shoreline a lot.
float diff = 0.8 - foamAmt;
if ( diff < 0.0 )
{
//return vec4( 1,0,0,1 );
foamAmt -= foamAmt * abs( diff ) / 0.2;
}
//return vec4( foamAmt.rrr, 1 );
foamAmt *= FOAM_SCALE * foamColor.a;
//return vec4( foamAmt.rrr, 1 );
// Get reflection map color
vec4 refMapColor = tex2D( reflectMap, reflectCoord );
foamAmt *= FOAM_OPACITY * foamColor.a;
//cubeAmt = 0;
foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a;
// Combine cube and foam colors into reflect color
vec4 reflectColor = lerp( refMapColor, cubeColor, cubeAmt );
//return refMapColor;
// Get reflection map color.
vec4 refMapColor = hdrDecode( texture( reflectMap, reflectCoord ) );
// This doesn't work because REFLECT_PLANE_Z is in worldSpace
// while eyePos is actually in objectSpace!
// If we do not have a reflection texture then we use the cubemap.
refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT );
//float eyeToPlaneDist = eyePos.z - REFLECT_PLANE_Z; // dot( reflectNormal, eyePos ) + REFLECT_PLANE_Z;
//float transitionFactor = 1.0 - saturate( ( abs( eyeToPlaneDist ) - 0.5 ) / 5 );
//reflectColor = lerp( reflectColor, waterBaseColor, transitionFactor );
//return reflectColor;
fakeColor = ( texture( skyMap, reflectionVec ) );
fakeColor.a = 1;
// Combine reflection color and fakeColor.
vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt );
// Get refract color
vec4 refractColor = tex2D( refractBuff, refractCoord );
//return refractColor;
vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) );
// We darken the refraction color a bit to make underwater
// elements look wet. We fade out this darkening near the
@ -371,86 +315,80 @@ void main()
// Add Water fog/haze.
float fogDelta = delta - FOG_DENSITY_OFFSET;
//return vec4( fogDelta.rrr, 1 );
if ( fogDelta < 0.0 )
fogDelta = 0.0;
float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) );
//return vec4( fogAmt.rrr, 1 );
// Calculate the water "base" color based on depth.
vec4 waterBaseColor = baseColor * texture( depthGradMap, saturate( delta / depthGradMax ) );
// Modulate baseColor by the ambientColor.
waterBaseColor *= vec4( ambientColor.rgb, 1 );
// calc "diffuse" color by lerping from the water color
// to refraction image based on the water clarity.
vec4 diffuseColor = lerp( refractColor, waterBaseColor, fogAmt );
vec4 diffuseColor = mix( refractColor, waterBaseColor, fogAmt );
// fresnel calculation
float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
//return vec4( fresnelTerm.rrr, 1 );
// Scale the frensel strength by fog amount
// so that parts that are very clear get very little reflection.
fresnelTerm *= fogAmt;
//return vec4( fresnelTerm.rrr, 1 );
// Also scale the frensel by our distance to the
// water surface. This removes the hard reflection
// when really close to the water surface.
fresnelTerm *= saturate( IN.pixelDist - 0.1 );
fresnelTerm *= saturate( PIXEL_DIST - 0.1 );
fresnelTerm *= reflectivity;
// Combine the diffuse color and reflection image via the
// fresnel term and set out output color.
vec4 gl_FragColor = lerp( diffuseColor, reflectColor, fresnelTerm );
vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm );
//float brightness = saturate( 1.0 - ( waterHeight - eyePosWorld.z - 5.0 ) / 50.0 );
//gl_FragColor.rgb *= brightness;
vec3 lightVec = inLightVec;
// Get some specular reflection.
vec3 newbump = bumpNorm;
newbump.xy *= 3.5;
newbump = normalize( bumpNorm );
vec3 halfAng = normalize( eyeVec + -lightVec );
float specular = saturate( dot( newbump, halfAng ) );
specular = pow( specular, SPEC_POWER );
// Scale down specularity in very shallow water to improve the transparency of the shoreline.
specular *= saturate( delta / 2 );
OUT.rgb = OUT.rgb + ( SPEC_COLOR * vec3(specular) );
#else
vec4 refractColor = tex2D( refractBuff, refractCoord );
vec4 gl_FragColor = refractColor;
vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) );
vec4 OUT = refractColor;
#endif
#ifndef UNDERWATER
gl_FragColor.rgb = lerp( gl_FragColor.rgb, foamColor.rgb, foamAmt );
#endif
gl_FragColor.a = 1.0;
// specular experiments
// 1:
/*
float fDot = dot( bumpNorm, inLightVec );
vec3 reflect = normalize( 2.0 * bumpNorm * fDot - eyeVec );
// float specular = saturate(dot( reflect, inLightVec ) );
float specular = pow( reflect, specularPower );
gl_FragColor += specularColor * specular;
*/
// 2: This almost looks good
/*
bumpNorm.xy *= 2.0;
bumpNorm = normalize( bumpNorm );
vec3 halfAng = normalize( eyeVec + inLightVec );
float specular = saturate( dot( bumpNorm, halfAng) );
specular = pow(specular, specularPower);
gl_FragColor += specularColor * specular;
*/
#ifndef UNDERWATER
OUT.rgb = OUT.rgb + foamColor.rgb;
float factor = computeSceneFog( eyePos,
IN.fogPos,
IN.worldSpaceZ,
IN_objPos.xyz,
IN_objPos.w,
fogData.x,
fogData.y,
fogData.z );
gl_FragColor.rgb = lerp( gl_FragColor.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
//OUT.rgb = fogColor.rgb;
#endif
//return vec4( refMapColor.rgb, 1 );
gl_FragColor.a = 1.0;
OUT.a = 1.0;
//return OUT;
return gl_FragColor;
OUT_FragColor0 = hdrEncode( OUT );
}

View file

@ -20,58 +20,86 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h"
//-----------------------------------------------------------------------------
// Structures
//-----------------------------------------------------------------------------
struct VertData
{
vec4 position ;// POSITION;
vec3 normal ;// NORMAL;
vec2 undulateData ;// TEXCOORD0;
vec4 horizonFactor ;// TEXCOORD1;
};
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
//VertData IN
in vec4 vPosition;
in vec3 vNormal;
in vec2 vTexCoord0;
in vec4 vTexCoord1;
// waveData
#define WAVE_SPEED(i) waveData[i].x
#define WAVE_MAGNITUDE(i) waveData[i].y
#define IN_position_ vPosition
#define IN_normal vNormal
#define IN_undulateData vTexCoord0
#define IN_horizonFactor vTexCoord1
// Outgoing data
// Worldspace position of this pixel
varying vec3 worldPos;
//ConnectData OUT
//
out vec4 hpos ;
// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
varying vec4 rippleTexCoord01;
out vec4 rippleTexCoord01;
// TexCoord 2 for ripple texture lookup
varying vec2 rippleTexCoord2;
// xy is TexCoord 2 for ripple texture lookup
// z is the Worldspace unit distance/depth of this vertex/pixel
// w is amount of the crestFoam ( more at crest of waves ).
out vec4 rippleTexCoord2 ;
// Screenspace vert position BEFORE wave transformation
varying vec4 posPreWave;
out vec4 posPreWave;
// Screenspace vert position AFTER wave transformation
varying vec4 posPostWave;
out vec4 posPostWave;
// Worldspace unit distance/depth of this vertex/pixel
varying float pixelDist;
// Objectspace vert position BEFORE wave transformation
// w coord is world space z position.
out vec4 objPos ;
varying vec3 fogPos;
out vec4 foamTexCoords ;
varying float worldSpaceZ;
out mat3 tangentMat ;
//
varying vec4 foamTexCoords;
#define OUT_hpos hpos
#define OUT_rippleTexCoord01 rippleTexCoord01
#define OUT_rippleTexCoord2 rippleTexCoord2
#define OUT_posPreWave posPreWave
#define OUT_posPostWave posPostWave
#define OUT_objPos objPos
#define OUT_foamTexCoords foamTexCoords
#define OUT_tangentMat tangentMat
//-----------------------------------------------------------------------------
// Uniforms
//-----------------------------------------------------------------------------
uniform mat4 modelMat;
uniform mat4 modelview;
uniform mat3 cubeTrans;
uniform mat4 objTrans;
uniform vec3 cubeEyePos;
uniform vec4 rippleMat[3];
uniform vec3 eyePos;
uniform vec2 waveDir[3];
uniform vec2 waveData[3];
uniform vec2 rippleDir[3];
uniform vec2 rippleTexScale[3];
uniform vec3 rippleSpeed;
uniform vec2 reflectTexSize;
uniform vec4 foamDir;
uniform vec4 foamTexScale;
uniform vec2 foamSpeed;
uniform vec3 inLightVec;
uniform vec3 reflectNormal;
uniform float gridElementSize;
uniform float elapsedTime;
uniform float undulateMaxDist;
@ -81,97 +109,133 @@ uniform float undulateMaxDist;
//-----------------------------------------------------------------------------
void main()
{
// Copy incoming attributes into locals so we can modify them in place.
vec4 position = gl_Vertex.xyzw;
vec3 normal = gl_Normal.xyz;
vec2 undulateData = gl_MultiTexCoord0.st;
vec4 horizonFactor = gl_MultiTexCoord1.xyzw;
vec4 IN_position = IN_position_;
// use projection matrix for reflection / refraction texture coords
mat4 texGen = { 0.5, 0.0, 0.0, 0.5, //+ 0.5 / reflectTexSize.x,
0.0, 0.5, 0.0, 0.5, //+ 1.0 / reflectTexSize.y,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5,
0.0, -0.5, 0.0, 0.5,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 );
// Move the vertex based on the horizonFactor if specified to do so for this vert.
if ( horizonFactor.z > 0 )
{
vec2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize;
position.xy += offsetXY;
undulateData += offsetXY;
}
IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x );
fogPos = position;
position.z = mix( position.z, eyePos.z, horizonFactor.x );
OUT_objPos = IN_position;
OUT_objPos.w = tMul( modelMat, IN_position ).z;
// Send pre-undulation screenspace position
posPreWave = modelview * position;
posPreWave = texGen * posPreWave;
OUT_posPreWave = tMul( modelview, IN_position );
OUT_posPreWave = tMul( texGen, OUT_posPreWave );
// Calculate the undulation amount for this vertex.
vec2 undulatePos = undulateData;
float undulateAmt = 0;
vec2 undulatePos = tMul( modelMat, vec4 ( IN_undulateData.xy, 0, 1 ) ).xy;
float undulateAmt = 0.0;
for ( int i = 0; i < 3; i++ )
{
undulateAmt += WAVE_MAGNITUDE(i) * sin( elapsedTime * WAVE_SPEED(i) +
undulatePos.x * waveDir[i].x +
undulatePos.y * waveDir[i].y );
}
undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
undulatePos.x * waveDir[0].x +
undulatePos.y * waveDir[0].y );
undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x +
undulatePos.x * waveDir[1].x +
undulatePos.y * waveDir[1].y );
undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
undulatePos.x * waveDir[2].x +
undulatePos.y * waveDir[2].y );
float undulateFade = 1;
// Scale down wave magnitude amount based on distance from the camera.
float dist = distance( position, eyePos );
float dist = distance( IN_position.xyz, eyePos );
dist = clamp( dist, 1.0, undulateMaxDist );
undulateAmt *= ( 1 - dist / undulateMaxDist );
undulateFade *= ( 1 - dist / undulateMaxDist );
// Also scale down wave magnitude if the camera is very very close.
undulateAmt *= clamp( ( distance( IN.position, eyePos ) - 0.5 ) / 10.0, 0.0, 1.0 );
undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 );
undulateAmt *= undulateFade;
OUT_rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y );
OUT_rippleTexCoord2.w = saturate( OUT_rippleTexCoord2.w - 0.2 ) / 0.8;
// Apply wave undulation to the vertex.
posPostWave = position;
posPostWave.xyz += normal.xyz * undulateAmt;
// Save worldSpace position of this pixel/vert
worldPos = posPostWave.xyz;
OUT_posPostWave = IN_position;
OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt;
// Convert to screen
posPostWave = modelview * posPostWave;
OUT_posPostWave = tMul( modelview, OUT_posPostWave );
// Setup the OUT position symantic variable
gl_Position = posPostWave;
gl_Position.z = mix(gl_Position.z, gl_Position.w, horizonFactor.x);
OUT_hpos = OUT_posPostWave;
//OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x );
worldSpaceZ = modelMat * vec4(fogPos, 1.0) ).z;
if ( horizonFactor.x > 0.0 )
{
vec3 awayVec = normalize( fogPos.xyz - eyePos );
fogPos.xy += awayVec.xy * 1000.0;
}
// if ( IN_horizonFactor.x > 0 )
// {
// vec3 awayVec = normalize( OUT_objPos.xyz - eyePos );
// OUT_objPos.xy += awayVec.xy * 1000.0;
// }
// Save world space camera dist/depth of the outgoing pixel
pixelDist = gl_Position.z;
OUT_rippleTexCoord2.z = OUT_hpos.z;
// Convert to reflection texture space
posPostWave = texGen * posPostWave;
OUT_posPostWave = tMul( texGen, OUT_posPostWave );
float2 ripplePos = undulateData;
float2 txPos = normalize( ripplePos );
txPos *= 50000.0;
ripplePos = mix( ripplePos, txPos, IN.horizonFactor.x );
vec2 txPos = undulatePos;
if ( bool(IN_horizonFactor.x) )
txPos = normalize( txPos ) * 50000.0;
// set up tex coordinates for the 3 interacting normal maps
rippleTexCoord01.xy = mix( ripplePos * rippleTexScale[0], txPos.xy * rippleTexScale[0], IN.horizonFactor.x );
rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0];
OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
rippleTexCoord01.zw = mix( ripplePos * rippleTexScale[1], txPos.xy * rippleTexScale[1], IN.horizonFactor.x );
rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
mat2 texMat;
texMat[0][0] = rippleMat[0].x;
texMat[1][0] = rippleMat[0].y;
texMat[0][1] = rippleMat[0].z;
texMat[1][1] = rippleMat[0].w;
OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy );
rippleTexCoord2.xy = mix( ripplePos * rippleTexScale[2], txPos.xy * rippleTexScale[2], IN.horizonFactor.x );
rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1];
OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
texMat[0][0] = rippleMat[1].x;
texMat[1][0] = rippleMat[1].y;
texMat[0][1] = rippleMat[1].z;
texMat[1][1] = rippleMat[1].w;
OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw );
foamTexCoords.xy = mix( ripplePos * 0.2, txPos.xy * rippleTexScale[0], IN.horizonFactor.x );
foamTexCoords.xy += rippleDir[0] * sin( ( elapsedTime + 500.0 ) * -0.4 ) * 0.15;
OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2];
OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
foamTexCoords.zw = mix( ripplePos * 0.3, txPos.xy * rippleTexScale[1], IN.horizonFactor.x );
foamTexCoords.zw += rippleDir[1] * sin( elapsedTime * 0.4 ) * 0.15;
texMat[0][0] = rippleMat[2].x;
texMat[1][0] = rippleMat[2].y;
texMat[0][1] = rippleMat[2].z;
texMat[1][1] = rippleMat[2].w;
OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy );
OUT_foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime;
OUT_foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime;
vec3 binormal = vec3 ( 1, 0, 0 );
vec3 tangent = vec3 ( 0, 1, 0 );
vec3 normal;
for ( int i = 0; i < 3; i++ )
{
binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
}
binormal = binormal;
tangent = tangent;
normal = cross( binormal, tangent );
mat3 worldToTangent;
worldToTangent[0] = binormal;
worldToTangent[1] = tangent;
worldToTangent[2] = normal;
OUT_tangentMat = transpose(worldToTangent);
gl_Position = OUT_hpos;
correctSSP(gl_Position);
}