diff --git a/Templates/Empty/game/shaders/common/gl/blurP.glsl b/Templates/Empty/game/shaders/common/gl/blurP.glsl index bc05b992f..5c37ebc6b 100644 --- a/Templates/Empty/game/shaders/common/gl/blurP.glsl +++ b/Templates/Empty/game/shaders/common/gl/blurP.glsl @@ -26,12 +26,12 @@ uniform vec4 kernel; uniform sampler2D diffuseMap; -varying vec2 texc0, texc1, texc2, texc3; +in vec2 texc0, texc1, texc2, texc3; void main() { - gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x; - gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y; - gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z; - gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w; + OUT_FragColor0 = texture(diffuseMap, texc0) * kernel.x; + OUT_FragColor0 += texture(diffuseMap, texc1) * kernel.y; + OUT_FragColor0 += texture(diffuseMap, texc2) * kernel.z; + OUT_FragColor0 += texture(diffuseMap, texc3) * kernel.w; } diff --git a/Templates/Empty/game/shaders/common/gl/blurV.glsl b/Templates/Empty/game/shaders/common/gl/blurV.glsl index d5d615fb9..1bfb0cd1b 100644 --- a/Templates/Empty/game/shaders/common/gl/blurV.glsl +++ b/Templates/Empty/game/shaders/common/gl/blurV.glsl @@ -24,20 +24,25 @@ // Glow shader //***************************************************************************** +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + uniform mat4 modelview; uniform vec2 offset0, offset1, offset2, offset3; -varying vec2 texc0, texc1, texc2, texc3; +out vec2 texc0, texc1, texc2, texc3; void main() { - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - vec2 tc = gl_MultiTexCoord0.st; + vec2 tc = vTexCoord0.st; tc.y = 1.0 - tc.y; texc0 = tc + offset0; texc1 = tc + offset1; texc2 = tc + offset2; texc3 = tc + offset3; + gl_Position.y *= -1; } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl b/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl index 326f2d3c6..da3996d58 100644 --- a/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl +++ b/Templates/Empty/game/shaders/common/gl/cloudLayerP.glsl @@ -22,12 +22,20 @@ #include "hlslCompat.glsl" -varying vec4 texCoord12; -varying vec4 texCoord34; -varying vec3 vLightTS; // light vector in tangent space, denormalized -varying vec3 vViewTS; // view vector in tangent space, denormalized -varying vec3 vNormalWS; // Normal vector in world space -varying float worldDist; +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +//ConnectData +in vec4 texCoord12; +#define IN_texCoord12 texCoord12 +in vec4 texCoord34; +#define IN_texCoord34 texCoord34 +in vec3 vLightTS; // light vector in tangent space, denormalized +#define IN_vLightTS vLightTS +in vec3 vViewTS; // view vector in tangent space, denormalized +#define IN_vViewTS vViewTS +in float worldDist; +#define IN_worldDist worldDist //----------------------------------------------------------------------------- // Uniforms @@ -37,6 +45,7 @@ uniform vec3 ambientColor; uniform vec3 sunColor; uniform float cloudCoverage; uniform vec3 cloudBaseColor; +uniform float cloudExposure; //----------------------------------------------------------------------------- // Globals @@ -97,26 +106,25 @@ void main() // Normalize the interpolated vectors: vec3 vViewTS = normalize( vViewTS ); vec3 vLightTS = normalize( vLightTS ); - vec3 vNormalWS = normalize( vNormalWS ); - vec4 cResultColor = float4( 0, 0, 0, 1 ); + vec4 cResultColor = vec4( 0, 0, 0, 1 ); - vec2 texSample = texCoord12.xy; + vec2 texSample = IN_texCoord12.xy; - vec4 noise1 = texture2D( normalHeightMap, texCoord12.zw ); + vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw ); noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); //return noise1; - vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy ); + vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy ); noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); //return noise2; vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; - //return float4( noiseNormal, 1.0 ); + //return vec4( noiseNormal, 1.0 ); float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); - vec3 vNormalTS = normalize( texture2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); + vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); vNormalTS += noiseNormal; vNormalTS = normalize( vNormalTS ); @@ -124,16 +132,14 @@ void main() cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); float coverage = ( cloudCoverage - 0.5 ) * 2.0; - cResultColor.a = texture2D( normalHeightMap, texSample ).a + coverage + noiseHeight; + cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight; if ( cloudCoverage > -1.0 ) cResultColor.a /= 1.0 + coverage; - cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) ); + cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 ); - cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(worldDist,2.0) ); + cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) ); - // If using HDR rendering, make sure to tonemap the resuld color prior to outputting it. - // But since this example isn't doing that, we just output the computed result color here: - gl_FragColor = cResultColor; + OUT_FragColor0 = cResultColor; } diff --git a/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl b/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl index 39a6f4ba8..395c6f286 100644 --- a/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl +++ b/Templates/Empty/game/shaders/common/gl/cloudLayerV.glsl @@ -20,12 +20,24 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 texCoord12; -varying vec4 texCoord34; -varying vec3 vLightTS; // light vector in tangent space, denormalized -varying vec3 vViewTS; // view vector in tangent space, denormalized -varying vec3 vNormalWS; // Normal vector in world space -varying float worldDist; +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec3 vNormal; +in vec3 vBinormal; +in vec3 vTangent; +in vec2 vTexCoord0; + +out vec4 texCoord12; +#define OUT_texCoord12 texCoord12 +out vec4 texCoord34; +#define OUT_texCoord34 texCoord34 +out vec3 vLightTS; // light vector in tangent space, denormalized +#define OUT_vLightTS vLightTS +out vec3 vViewTS; // view vector in tangent space, denormalized +#define OUT_vViewTS vViewTS +out float worldDist; +#define OUT_worldDist worldDist //----------------------------------------------------------------------------- // Uniforms @@ -43,37 +55,37 @@ uniform vec3 texScale; //----------------------------------------------------------------------------- void main() { - vec4 pos = gl_Vertex; - vec3 normal = gl_Normal; - vec3 binormal = gl_MultiTexCoord0.xyz; - vec3 tangent = gl_MultiTexCoord1.xyz; - vec2 uv0 = gl_MultiTexCoord2.st; + vec4 IN_pos = vPosition; + vec3 IN_normal = vNormal; + vec3 IN_binormal = vBinormal; + vec3 IN_tangent = vTangent; + vec2 IN_uv0 = vTexCoord0.st; - gl_Position = modelview * pos; + gl_Position = modelview * IN_pos; // Offset the uv so we don't have a seam directly over our head. - vec2 uv = uv0 + vec2( 0.5, 0.5 ); + vec2 uv = IN_uv0 + vec2( 0.5, 0.5 ); - texCoord12.xy = uv * texScale.x; - texCoord12.xy += texOffset0; + OUT_texCoord12.xy = uv * texScale.x; + OUT_texCoord12.xy += texOffset0; - texCoord12.zw = uv * texScale.y; - texCoord12.zw += texOffset1; + OUT_texCoord12.zw = uv * texScale.y; + OUT_texCoord12.zw += texOffset1; - texCoord34.xy = uv * texScale.z; - texCoord34.xy += texOffset2; + OUT_texCoord34.xy = uv * texScale.z; + OUT_texCoord34.xy += texOffset2; - texCoord34.z = pos.z; - texCoord34.w = 0.0; + OUT_texCoord34.z = IN_pos.z; + OUT_texCoord34.w = 0.0; // Transform the normal, tangent and binormal vectors from object space to // homogeneous projection space: - vNormalWS = -normal; - vec3 vTangentWS = -tangent; - vec3 vBinormalWS = -binormal; + vec3 vNormalWS = -IN_normal; + vec3 vTangentWS = -IN_tangent; + vec3 vBinormalWS = -IN_binormal; // Compute position in world space: - vec4 vPositionWS = pos + vec4( eyePosWorld, 1 ); //mul( pos, objTrans ); + vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans ); // Compute and output the world view vector (unnormalized): vec3 vViewWS = eyePosWorld - vPositionWS.xyz; @@ -81,12 +93,14 @@ void main() // Compute denormalized light vector in world space: vec3 vLightWS = -sunVec; - // Normalize the light and view vectors and transform it to the tangent space: + // Normalize the light and view vectors and transform it to the IN_tangent space: mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS ); // Propagate the view and the light vectors (in tangent space): - vLightTS = mWorldToTangent * vLightWS; - vViewTS = vViewWS * mWorldToTangent; - - worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 ); + OUT_vLightTS = vLightWS * mWorldToTangent; + OUT_vViewTS = mWorldToTangent * vViewWS; + + OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 ); + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/gl/foliage.glsl b/Templates/Empty/game/shaders/common/gl/foliage.glsl index 2fee902e3..38b66e767 100644 --- a/Templates/Empty/game/shaders/common/gl/foliage.glsl +++ b/Templates/Empty/game/shaders/common/gl/foliage.glsl @@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo; uniform vec2 gc_turbInfo; -//static float sMovableCorner[4] = { 0.0, 0.0, 1.0, 1.0 }; +const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 ); + +const float sCornerUp[4] = float[]( 0, 0, 1, 1 ); + +const float sMovableCorner[4] = float[]( 0, 0, 1, 1 ); + +const vec2 sUVCornerExtent[4] = vec2[] +( + vec2( 0, 1 ), + vec2( 1, 1 ), + vec2( 1, 0 ), + vec2( 0, 0 ) +); /////////////////////////////////////////////////////////////////////////////// @@ -106,34 +118,13 @@ vec2 windEffect( float bbPhase, void foliageProcessVert( inout vec3 position, inout vec4 diffuse, - in vec4 texCoord, - out vec2 outTexCoord, + inout vec4 texCoord, inout vec3 normal, inout vec3 T, in vec3 eyePos ) { - - float sCornerRight[4]; - sCornerRight[0] = -0.5; - sCornerRight[1] = 0.5; - sCornerRight[2] = 0.5; - sCornerRight[3] = -0.5; - - float sCornerUp[4]; - sCornerUp[0] = 0.0; - sCornerUp[1] = 0.0; - sCornerUp[2] = 1.0; - sCornerUp[3] = 1.0; - - vec2 sUVCornerExtent[4]; - sUVCornerExtent[0] = vec2( 0.0, 1.0 ); - sUVCornerExtent[1] = vec2( 1.0, 1.0 ); - sUVCornerExtent[2] = vec2( 1.0, 0.0 ); - sUVCornerExtent[3] = vec2( 0.0, 0.0 ); - - // Assign the normal and tagent values. - //normal = cross( gc_camUp, gc_camRight ); + //normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight ); T = gc_camRight; // Pull out local vars we need for work. @@ -172,8 +163,8 @@ void foliageProcessVert( inout vec3 position, // Grab the uv set and setup the texture coord. vec4 uvSet = gc_typeRects[type]; - outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); - outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); // Animate the normal to get lighting changes // across the the wind swept foliage. @@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position, normal.xy += wind.xy * ( 10.0 * texCoord.w ); normal = normalize( normal ); - // Get the alpha fade value. float fadeStart = gc_fadeParams.x; diff --git a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl index 9e5b34caa..fb5abb91e 100644 --- a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl +++ b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorP.glsl @@ -26,15 +26,15 @@ uniform sampler2D diffuseMap, alphaMap; uniform vec4 groundAlpha; -varying vec4 color, groundAlphaCoeff; -varying vec2 outTexCoord, alphaLookup; +in vec4 color, groundAlphaCoeff; +in vec2 outTexCoord, alphaLookup; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - vec4 alpha = texture2D(alphaMap, alphaLookup); - gl_FragColor = color * texture2D(diffuseMap, outTexCoord); - gl_FragColor.a = gl_FragColor.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; + vec4 alpha = texture(alphaMap, alphaLookup); + OUT_FragColor0 = color * texture(diffuseMap, outTexCoord); + OUT_FragColor0.a = OUT_FragColor0.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; } diff --git a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl index 94a7af2b0..c8dcf1ddb 100644 --- a/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl +++ b/Templates/Empty/game/shaders/common/gl/fxFoliageReplicatorV.glsl @@ -23,13 +23,20 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec3 vNormal; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; +in vec2 vTexCoord2; + uniform mat4 projection, world; uniform vec3 CameraPos; uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; -varying vec4 color, groundAlphaCoeff; -varying vec2 outTexCoord, alphaLookup; +out vec4 color, groundAlphaCoeff; +out vec2 outTexCoord, alphaLookup; //----------------------------------------------------------------------------- // Main @@ -42,9 +49,9 @@ void main() trans[1][1] = 1.0; trans[2][2] = 1.0; trans[3][3] = 1.0; - trans[3][0] = gl_Vertex.x; - trans[3][1] = gl_Vertex.y; - trans[3][2] = gl_Vertex.z; + trans[3][0] = vPosition.x; + trans[3][1] = vPosition.y; + trans[3][2] = vPosition.z; // Billboard transform * world matrix mat4 o = world; @@ -64,28 +71,29 @@ void main() // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, // the y coordinate determines if this vertex actually sways or not. float xSway, ySway; - float wavePhase = GlobalSwayPhase * gl_MultiTexCoord1.x; + float wavePhase = GlobalSwayPhase * vTexCoord1.x; ySway = sin(wavePhase); xSway = cos(wavePhase); - xSway = xSway * gl_MultiTexCoord1.y * SwayMagnitudeSide; - ySway = ySway * gl_MultiTexCoord1.y * SwayMagnitudeFront; + xSway = xSway * vTexCoord1.y * SwayMagnitudeSide; + ySway = ySway * vTexCoord1.y * SwayMagnitudeFront; vec4 p; - p = o * vec4(gl_Normal.x + xSway, ySway, gl_Normal.z, 1.0); + p = o * vec4(vNormal.x + xSway, ySway, vNormal.z, 1.0); // Project the point gl_Position = projection * p; // Lighting - float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + gl_Normal.y); + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y); // Alpha - vec3 worldPos = vec3(gl_Vertex.x, gl_Vertex.y, gl_Vertex.z); + vec3 worldPos = vec3(vPosition.x, vPosition.y, vPosition.z); float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; alpha = clamp(alpha, 0.0, 1.0); //pass it through alphaLookup = vec2(alpha, 0.0); - bool alphaCoeff = bool(gl_Normal.z); + bool alphaCoeff = bool(vNormal.z); groundAlphaCoeff = vec4(float(alphaCoeff)); - outTexCoord = gl_MultiTexCoord0.st; + outTexCoord = vTexCoord0.st; color = vec4(Luminance, Luminance, Luminance, 1.0); + gl_Position.y *= -1; } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl b/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl index cd44de2f2..de3845ee7 100644 --- a/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl +++ b/Templates/Empty/game/shaders/common/gl/guiMaterialV.glsl @@ -20,16 +20,20 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4x4 modelview; -varying vec4 hpos; -varying vec2 uv0; +out vec4 hpos; +out vec2 uv0; void main() { - hpos = vec4( modelview * gl_Vertex ); + hpos = vec4( modelview * vPosition ); gl_Position = hpos; - uv0 = gl_MultiTexCoord0.st; + uv0 = vTexCoord0.st; + gl_Position.y *= -1; } diff --git a/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl b/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl index be5c63340..0815df51f 100644 --- a/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl +++ b/Templates/Empty/game/shaders/common/gl/hlslCompat.glsl @@ -27,17 +27,79 @@ #define float3 vec3 #define float2 vec2 -#define texCUBE textureCube -#define tex2D texture2D +#define half float +#define half2 vec2 +#define half3 vec3 +#define half4 vec4 + +#define float4x4 mat4 +#define float3x3 mat3 +#define float2x2 mat2 + +#define texCUBE texture +#define tex2D texture +#define tex1D texture +#define tex2Dproj textureProj +#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w) + +#define samplerCUBE samplerCube + +#define frac fract #define lerp mix -float saturate( float val ) { return clamp( val, 0.0, 1.0 ); } -vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); } -vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); } -vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); } +void tSetMatrixRow(out float3x3 m, int row, float3 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; +} -float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } +void tSetMatrixRow(out float4x4 m, int row, float4 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; + m[3][row] = value.w; +} + +#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row]) +#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row]) + +float3x3 float4x4to3x3(float4x4 m) +{ + return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz); +} + +float3x3 float4x4to3x3_(float4x4 m) +{ + return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz); +} + +mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3, + float r1c0, float r1c1, float r1c2, float r1c3, + float r2c0, float r2c1, float r2c2, float r2c3, + float r3c0, float r3c1, float r3c2, float r3c3 ) +{ + return mat4( r0c0, r1c0, r2c0, r3c0, + r0c1, r1c1, r2c1, r3c1, + r0c2, r1c2, r2c2, r3c2, + r0c3, r1c3, r2c3, r3c3 ); +} + + +#define saturate( val ) clamp( val, 0.0, 1.0 ) + +#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 )) + +#define tMul(a, b) (a*b) + +#define inversesqrt( n ) inversesqrt( n ) + +#define correctSSP(vec) vec.y *= -1 + +#ifdef TORQUE_PIXEL_SHADER + void clip(float a) { if(a < 0) discard;} + + out vec4 OUT_FragColor0; +#endif diff --git a/Templates/Empty/game/shaders/common/gl/lighting.glsl b/Templates/Empty/game/shaders/common/gl/lighting.glsl index 3f8867d3b..4483c7526 100644 --- a/Templates/Empty/game/shaders/common/gl/lighting.glsl +++ b/Templates/Empty/game/shaders/common/gl/lighting.glsl @@ -20,73 +20,181 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- + +#ifndef TORQUE_SHADERGEN + // These are the uniforms used by most lighting shaders. -uniform vec3 inLightPos[4]; +uniform vec4 inLightPos[3]; uniform vec4 inLightInvRadiusSq; uniform vec4 inLightColor[4]; + +#ifndef TORQUE_BL_NOSPOTLIGHT + uniform vec4 inLightSpotDir[3]; + uniform vec4 inLightSpotAngle; + uniform vec4 inLightSpotFalloff; +#endif + uniform vec4 ambient; uniform float specularPower; uniform vec4 specularColor; - -// This is used to limit the maximum processed -// lights in the compute4Lights down for really -// low end GPUs. -// -// NOTE: If you want to support 10.5.x, this needs to be changed to 2. -#define C4L_MAX_LIGHTS 4 +#endif // !TORQUE_SHADERGEN void compute4Lights( vec3 wsView, vec3 wsPosition, - vec3 wsNormal, + vec3 wsNormal, + vec4 shadowMask, + + #ifdef TORQUE_SHADERGEN + + vec4 inLightPos[3], + vec4 inLightInvRadiusSq, + vec4 inLightColor[4], + vec4 inLightSpotDir[3], + vec4 inLightSpotAngle, + vec4 inLightSpotFalloff, + float specularPower, + vec4 specularColor, + + #endif // TORQUE_SHADERGEN + out vec4 outDiffuse, out vec4 outSpecular ) { - #ifdef PHONG_SPECULAR - // (R.V)^c - float reflected = reflect( wsView, wsNormal ); - #endif - - vec4 nDotL = vec4( 0.0 ); - vec4 rDotL = vec4( 0.0 ); - vec4 sqDists = vec4( 0.0 ); + // NOTE: The light positions and spotlight directions + // are stored in SoA order, so inLightPos[0] is the + // x coord for all 4 lights... inLightPos[1] is y... etc. + // + // This is the key to fully utilizing the vector units and + // saving a huge amount of instructions. + // + // For example this change saved more than 10 instructions + // over a simple for loop for each light. + int i; - for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) - { - vec3 lightVector = inLightPos[i] - wsPosition; - vec3 lightDirection = normalize( lightVector ); + vec4 lightVectors[3]; + for ( i = 0; i < 3; i++ ) + lightVectors[i] = wsPosition[i] - inLightPos[i]; - nDotL[i] = max( dot( lightDirection, wsNormal ), 0.0 ); + vec4 squareDists = vec4(0); + for ( i = 0; i < 3; i++ ) + squareDists += lightVectors[i] * lightVectors[i]; - #ifdef PHONG_SPECULAR - rDotL[i] = saturate( dot( lightDirection, reflected ) ); - #else - // (N.H)^c [Blinn-Phong, TGEA style, default] - rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) ); - #endif + // Accumulate the dot product between the light + // vector and the normal. + // + // The normal is negated because it faces away from + // the surface and the light faces towards the + // surface... this keeps us from needing to flip + // the light vector direction which complicates + // the spot light calculations. + // + // We normalize the result a little later. + // + vec4 nDotL = vec4(0); + for ( i = 0; i < 3; i++ ) + nDotL += lightVectors[i] * -wsNormal[i]; - sqDists[i] = dot( lightVector, lightVector ); - } + vec4 rDotL = vec4(0); + #ifndef TORQUE_BL_NOSPECULAR - // Attenuation - vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq ); + // We're using the Phong specular reflection model + // here where traditionally Torque has used Blinn-Phong + // which has proven to be more accurate to real materials. + // + // We do so because its cheaper as do not need to + // calculate the half angle for all 4 lights. + // + // Advanced Lighting still uses Blinn-Phong, but the + // specular reconstruction it does looks fairly similar + // to this. + // + vec3 R = reflect( wsView, -wsNormal ); + + for ( i = 0; i < 3; i++ ) + rDotL += lightVectors[i] * R[i]; + + #endif + + // Normalize the dots. + // + // Notice we're using the half type here to get a + // much faster sqrt via the rsq_pp instruction at + // the loss of some precision. + // + // Unless we have some extremely large point lights + // i don't believe the precision loss will matter. + // + half4 correction = half4(inversesqrt( squareDists )); + nDotL = saturate( nDotL * correction ); + rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); + + // First calculate a simple point light linear + // attenuation factor. + // + // If this is a directional light the inverse + // radius should be greater than the distance + // causing the attenuation to have no affect. + // + vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); + + #ifndef TORQUE_BL_NOSPOTLIGHT + + // The spotlight attenuation factor. This is really + // fast for what it does... 6 instructions for 4 spots. + + vec4 spotAtten = vec4(0); + for ( i = 0; i < 3; i++ ) + spotAtten += lightVectors[i] * inLightSpotDir[i]; + + vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; + atten *= saturate( cosAngle * inLightSpotFalloff ); + + #endif + + // Finally apply the shadow masking on the attenuation. + atten *= shadowMask; + + // Get the final light intensity. + vec4 intensity = nDotL * atten; // Combine the light colors for output. - vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) ); - outDiffuse = vec4( 0.0 ); - for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) - outDiffuse += vec4( diffuse[i] ) * inLightColor[i]; + outDiffuse = vec4(0); + for ( i = 0; i < 4; i++ ) + outDiffuse += intensity[i] * inLightColor[i]; // Output the specular power. - rDotL = max( rDotL, vec4( 0.00001 ) ); - outSpecular = pow( rDotL, vec4( specularPower ) ); + vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten; + + // Apply the per-light specular attenuation. + vec4 specular = vec4(0,0,0,1); + for ( i = 0; i < 4; i++ ) + specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); + + // Add the final specular intensity values together + // using a single dot product operation then get the + // final specular lighting color. + outSpecular = specularColor * specular; } -/// The standard specular calculation. +// This value is used in AL as a constant power to raise specular values +// to, before storing them into the light info buffer. The per-material +// specular value is then computer by using the integer identity of +// exponentiation: +// +// (a^m)^n = a^(m*n) +// +// or +// +// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) +// +#define AL_ConstantSpecularPower 12.0f + +/// The specular calculation used in Advanced Lighting. /// /// @param toLight Normalized vector representing direction from the pixel /// being lit, to the light source, in world space. @@ -96,11 +204,7 @@ void compute4Lights( vec3 wsView, /// @param toEye The normalized vector representing direction from the pixel /// being lit to the camera. /// -/// @param specPwr The specular exponent. -/// -/// @param specScale A scalar on the specular output used in RGB accumulation. -/// -float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr ) +float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye ) { #ifdef PHONG_SPECULAR // (R.V)^c @@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr ) #endif // Return the specular factor. - return pow( max( specVal, 0.00001f ), specPwr ); + return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); } diff --git a/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl b/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl index 4f2d9b359..6971e1013 100644 --- a/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl +++ b/Templates/Empty/game/shaders/common/gl/particleCompositeP.glsl @@ -21,6 +21,13 @@ //----------------------------------------------------------------------------- #include "torque.glsl" +#include "hlslCompat.glsl" + +in vec4 offscreenPos; +in vec4 backbufferPos; + +#define IN_offscreenPos offscreenPos +#define IN_backbufferPos backbufferPos uniform sampler2D colorSource; uniform vec4 offscreenTargetParams; @@ -31,8 +38,6 @@ uniform sampler2D edgeSource; uniform vec4 edgeTargetParams; #endif -varying vec4 backbufferPos; -varying vec4 offscreenPos; void main() { @@ -47,11 +52,10 @@ void main() #ifdef REJECT_EDGES // Cut out particles along the edges, this will create the stencil mask uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); - float edge = texture2D( edgeSource, uvScene.zw ).r; - if (-edge < 0.0) - discard; + float edge = texture( edgeSource, uvScene.zw ).r; + clip( -edge ); #endif // Sample offscreen target and return - gl_FragColor = texture2D( colorSource, uvScene.xy ); -} + OUT_FragColor0 = texture( colorSource, uvScene.xy ); +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl b/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl index 88a9431d1..8c8f840d1 100644 --- a/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl +++ b/Templates/Empty/game/shaders/common/gl/particleCompositeV.glsl @@ -20,16 +20,29 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -uniform mat4 modelViewProj; -uniform mat4 targetModelViewProj; +#include "hlslCompat.glsl" -varying vec4 offscreenPos; -varying vec4 backbufferPos; +in vec2 vTexCoord0; +#define uvCoord vTexCoord0 + +out vec4 offscreenPos; +out vec4 backbufferPos; + +#define OUT_hpos gl_Position +#define OUT_offscreenPos offscreenPos +#define OUT_backbufferPos backbufferPos + +uniform vec4 screenRect; // point, extent void main() { - gl_Position = modelViewProj * gl_Vertex; - backbufferPos = gl_Position; - offscreenPos = targetModelViewProj * gl_Vertex; + OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0); + OUT_hpos.xy *= screenRect.zw; + OUT_hpos.xy += screenRect.xy; + + OUT_backbufferPos = OUT_hpos; + OUT_offscreenPos = OUT_hpos; + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/gl/particlesP.glsl b/Templates/Empty/game/shaders/common/gl/particlesP.glsl index 66a3fee28..efd930302 100644 --- a/Templates/Empty/game/shaders/common/gl/particlesP.glsl +++ b/Templates/Empty/game/shaders/common/gl/particlesP.glsl @@ -20,63 +20,92 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -#include "hlslCompat.glsl" #include "torque.glsl" - +#include "hlslCompat.glsl" + // With advanced lighting we get soft particles. #ifdef TORQUE_LINEAR_DEPTH #define SOFTPARTICLES #endif -#define CLIP_Z // TODO: Make this a proper macro - -uniform sampler2D diffuseMap; - #ifdef SOFTPARTICLES #include "shadergen:/autogenConditioners.h" uniform float oneOverSoftness; uniform float oneOverFar; - uniform sampler2D prepassTex; + uniform sampler2D prepassTex; //uniform vec3 vEye; uniform vec4 prePassTargetParams; #endif +#define CLIP_Z // TODO: Make this a proper macro + +in vec4 color; +in vec2 uv0; +in vec4 pos; + +#define IN_color color +#define IN_uv0 uv0 +#define IN_pos pos + +uniform sampler2D diffuseMap; + +uniform sampler2D paraboloidLightMap; + +vec4 lmSample( vec3 nrm ) +{ + bool calcBack = (nrm.z < 0.0); + if ( calcBack ) + nrm.z = nrm.z * -1.0; + + vec2 lmCoord; + lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5; + lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5); + + + // If this is the back, offset in the atlas + if ( calcBack ) + lmCoord.x += 1.0; + + // Atlasing front and back maps, so scale + lmCoord.x *= 0.5; + + return texture(paraboloidLightMap, lmCoord); +} + + uniform float alphaFactor; uniform float alphaScale; -varying vec4 color; -varying vec2 uv0; -varying vec4 pos; - - void main() { - float softBlend = 1.0; + float softBlend = 1; #ifdef SOFTPARTICLES - float2 tc = pos.xy * vec2(1.0, -1.0 ) / pos.w; + vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w; tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); float sceneDepth = prepassUncondition( prepassTex, tc ).w; - float depth = pos.w * oneOverFar; - float diff = sceneDepth - depth; + float depth = IN_pos.w * oneOverFar; + float diff = sceneDepth - depth; #ifdef CLIP_Z // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer // When drawing high-res, though, we want to be able to take advantage of hi-z // so this is #ifdef'd out - if (diff < 0.0) - discard; + //clip(diff); #endif softBlend = saturate( diff * oneOverSoftness ); #endif - - vec4 diffuse = texture2D( diffuseMap, uv0 ); + + vec4 diffuse = texture( diffuseMap, IN_uv0 ); + + //OUT_FragColor0 = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale); // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) - vec3 colorScale = ( alphaFactor < 0.0 ? color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? vec3(color.a * alphaFactor * diffuse.a * softBlend) : vec3(softBlend) ) ); + vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) ); - gl_FragColor = hdrEncode( vec4(color.rgb * diffuse.rgb * colorScale, softBlend * color.a * diffuse.a * alphaScale) ); + OUT_FragColor0 = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale, + IN_color.a * diffuse.a * softBlend * alphaScale ) ); } diff --git a/Templates/Empty/game/shaders/common/gl/particlesV.glsl b/Templates/Empty/game/shaders/common/gl/particlesV.glsl index da896431f..3d75a6fb6 100644 --- a/Templates/Empty/game/shaders/common/gl/particlesV.glsl +++ b/Templates/Empty/game/shaders/common/gl/particlesV.glsl @@ -20,18 +20,35 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 color; -varying vec2 uv0; -varying vec4 pos; +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +#define In_pos vPosition +#define In_color vColor +#define In_uv0 vTexCoord0 + +out vec4 color; +out vec2 uv0; +out vec4 pos; + +#define OUT_hpos gl_Position +#define OUT_color color +#define OUT_uv0 uv0 +#define OUT_pos pos uniform mat4 modelViewProj; uniform mat4 fsModelViewProj; void main() { - gl_Position = modelViewProj * gl_Vertex; - pos = fsModelViewProj * gl_Vertex; - color = gl_Color; - uv0 = gl_MultiTexCoord0.st; + OUT_hpos = tMul( modelViewProj, In_pos ); + OUT_pos = tMul( fsModelViewProj, In_pos ); + OUT_color = In_color; + OUT_uv0 = In_uv0; + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl index 00413aa3b..334c70a70 100644 --- a/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl +++ b/Templates/Empty/game/shaders/common/gl/planarReflectBumpP.glsl @@ -26,8 +26,8 @@ uniform sampler2D diffuseMap, refractMap, bumpMap; uniform vec4 shadeColor; -varying vec2 TEX0; -varying vec4 TEX1; +in vec2 TEX0; +in vec4 TEX1; //----------------------------------------------------------------------------- // Fade edges of axis for texcoord passed in @@ -49,7 +49,7 @@ float fadeAxis( float val ) //----------------------------------------------------------------------------- void main() { - vec3 bumpNorm = texture2D( bumpMap, TEX0 ).rgb * 2.0 - 1.0; + vec3 bumpNorm = texture( bumpMap, TEX0 ).rgb * 2.0 - 1.0; vec2 offset = vec2( bumpNorm.x, bumpNorm.y ); vec4 texIndex = TEX1; @@ -61,8 +61,8 @@ void main() const float distortion = 0.2; texIndex.xy += offset * distortion * fadeVal; - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - vec4 reflectColor = texture2DProj( refractMap, texIndex ); + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, texIndex ); - gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; + OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a; } diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl index 820bdf698..90bcd27d8 100644 --- a/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl +++ b/Templates/Empty/game/shaders/common/gl/planarReflectBumpV.glsl @@ -23,10 +23,13 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 TEX0; -varying vec4 TEX1; +out vec2 TEX0; +out vec4 TEX1; //----------------------------------------------------------------------------- // Main @@ -38,11 +41,11 @@ void main() 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0); - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - TEX0 = gl_MultiTexCoord0.st; + TEX0 = vTexCoord0.st; TEX1 = texGenTest * gl_Position; TEX1.y = -TEX1.y; - + gl_Position.y *= -1; } diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl index b4f4fab39..77914b80e 100644 --- a/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl +++ b/Templates/Empty/game/shaders/common/gl/planarReflectP.glsl @@ -26,16 +26,16 @@ uniform sampler2D diffuseMap, refractMap; uniform vec4 shadeColor; -varying vec2 TEX0; -varying vec4 TEX1; +in vec2 TEX0; +in vec4 TEX1; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - vec4 reflectColor = texture2DProj( refractMap, TEX1 ); + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, TEX1 ); - gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; + OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a; } diff --git a/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl b/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl index 820bdf698..ba2484f66 100644 --- a/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl +++ b/Templates/Empty/game/shaders/common/gl/planarReflectV.glsl @@ -23,10 +23,13 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 TEX0; -varying vec4 TEX1; +out vec2 TEX0; +out vec4 TEX1; //----------------------------------------------------------------------------- // Main @@ -38,9 +41,9 @@ void main() 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0); - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - TEX0 = gl_MultiTexCoord0.st; + TEX0 = vTexCoord0; TEX1 = texGenTest * gl_Position; TEX1.y = -TEX1.y; diff --git a/Templates/Empty/game/shaders/common/gl/precipP.glsl b/Templates/Empty/game/shaders/common/gl/precipP.glsl index a04f16e4b..3c669517d 100644 --- a/Templates/Empty/game/shaders/common/gl/precipP.glsl +++ b/Templates/Empty/game/shaders/common/gl/precipP.glsl @@ -25,13 +25,13 @@ //----------------------------------------------------------------------------- uniform sampler2D diffuseMap; -varying vec4 color; -varying vec2 texCoord; +in vec4 color; +in vec2 texCoord; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - gl_FragColor = texture2D(diffuseMap, texCoord) * color; + OUT_FragColor0 = texture(diffuseMap, texCoord) * color; } diff --git a/Templates/Empty/game/shaders/common/gl/precipV.glsl b/Templates/Empty/game/shaders/common/gl/precipV.glsl index 3535f2f38..29f921630 100644 --- a/Templates/Empty/game/shaders/common/gl/precipV.glsl +++ b/Templates/Empty/game/shaders/common/gl/precipV.glsl @@ -23,28 +23,32 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; uniform vec3 cameraPos, ambient; uniform vec2 fadeStartEnd; -varying vec4 color; -varying vec2 texCoord; +out vec4 color; +out vec2 texCoord; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - gl_Position = modelview * gl_Vertex; - texCoord = gl_MultiTexCoord0.st; + gl_Position = modelview * vPosition; + texCoord = vTexCoord0.st; color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); // Do we need to do a distance fade? if ( fadeStartEnd.x < fadeStartEnd.y ) { - float distance = length( cameraPos - gl_Vertex.xyz ); + float distance = length( cameraPos - vPosition.xyz ); color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 ); } + gl_Position.y *= -1; } diff --git a/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl b/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl index 1dc963a4f..8ce0fba13 100644 --- a/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl +++ b/Templates/Empty/game/shaders/common/gl/projectedShadowP.glsl @@ -20,9 +20,11 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec2 texCoord; -varying vec4 color; -varying float fade; +in vec2 texCoord; +in vec4 color; +in float fade; + +out vec4 OUT_FragColor0; uniform sampler2D inputTex; uniform vec4 ambient; @@ -30,17 +32,6 @@ uniform vec4 ambient; void main() { - vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f); - float esmFactor = 200.0; - - float lum = dot( ambient.rgb, LUMINANCE_VECTOR ); - - gl_FragColor.rgb = ambient.rgb * lum; - gl_FragColor.a = 0.0; - float depth = texture2D(inputTex, texCoord).a; - - depth = depth * exp(depth - 10.0); - depth = exp(esmFactor * depth) - 1.0; - - gl_FragColor.a = clamp(depth * 300.0, 0.0, 1.0) * (1.0 - lum) * fade * color.a; + float shadow = texture( inputTex, texCoord ).a * color.a; + OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow ); } diff --git a/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl b/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl index c8abde742..b5de84181 100644 --- a/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl +++ b/Templates/Empty/game/shaders/common/gl/projectedShadowV.glsl @@ -20,13 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -//***************************************************************************** -// Precipitation vertex shader -//***************************************************************************** +#include "hlslCompat.glsl" -varying vec2 texCoord; -varying vec4 color; -varying float fade; +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; + +out vec2 texCoord; +out vec4 color; +out float fade; uniform mat4 modelview; uniform float shadowLength; @@ -34,11 +37,13 @@ uniform vec3 shadowCasterPosition; void main() { - gl_Position = modelview * vec4(gl_Vertex.xyz, 1.0); + gl_Position = modelview * vec4(vPosition.xyz, 1.0); - color = gl_Color; - texCoord = gl_MultiTexCoord1.st; + color = vColor; + texCoord = vTexCoord1.st; - float fromCasterDist = length(gl_Vertex.xyz - shadowCasterPosition) - shadowLength; - fade = 1.0 - clamp(fromCasterDist/shadowLength, 0.0, 1.0); + float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength; + fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 ); + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl b/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl index 6a6b9b97c..691567a37 100644 --- a/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl +++ b/Templates/Empty/game/shaders/common/gl/scatterSkyP.glsl @@ -21,36 +21,32 @@ //----------------------------------------------------------------------------- #include "torque.glsl" +#include "hlslCompat.glsl" -// Calculates the Mie phase function -float getMiePhase(float fCos, float fCos2, float g, float g2) -{ - return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); -} -// Calculates the Rayleigh phase function -float getRayleighPhase(float fCos2) -{ - //return 1.0; - return 0.75 + 0.75*fCos2; -} +// Conn +in vec4 rayleighColor; +#define IN_rayleighColor rayleighColor +in vec4 mieColor; +#define IN_mieColor mieColor +in vec3 v3Direction; +#define IN_v3Direction v3Direction +in float zPosition; +#define IN_zPosition zPosition +in vec3 pos; +#define IN_pos pos -varying vec4 rayleighColor; -varying vec4 mieColor; -varying vec3 v3Direction; -varying float zPosition; -varying vec3 pos; - -uniform samplerCube nightSky; +uniform samplerCube nightSky ; uniform vec4 nightColor; uniform vec2 nightInterpAndExposure; uniform float useCubemap; uniform vec3 lightDir; uniform vec3 sunDir; -void main() +void main() { - float fCos = dot( lightDir, v3Direction ) / length(v3Direction); + + float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction); float fCos2 = fCos*fCos; float g = -0.991; @@ -58,15 +54,15 @@ void main() float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); - vec4 color = rayleighColor + fMiePhase * mieColor; + vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor; color.a = color.b; - vec4 nightSkyColor = textureCube(nightSky, -v3Direction); + vec4 nightSkyColor = texture(nightSky, -v3Direction); nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); float fac = dot( normalize( pos ), sunDir ); fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); - gl_FragColor = mix( color, nightSkyColor, nightInterpAndExposure.y ); + OUT_FragColor0 = mix( color, nightSkyColor, nightInterpAndExposure.y ); // Clip based on the camera-relative // z position of the vertex, passed through @@ -74,6 +70,6 @@ void main() if(zPosition < 0.0) discard; - gl_FragColor.a = 1; - gl_FragColor = hdrEncode( gl_FragColor ); + OUT_FragColor0.a = 1; + OUT_FragColor0 = hdrEncode( OUT_FragColor0 ); } diff --git a/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl b/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl index 53abd5a6b..61580d785 100644 --- a/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl +++ b/Templates/Empty/game/shaders/common/gl/scatterSkyV.glsl @@ -20,12 +20,7 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -const int nSamples = 4; -const float fSamples = 4.0; - -// The scale depth (the altitude at which the average atmospheric density is found) -const float fScaleDepth = 0.25; -const float fInvScaleDepth = 1.0 / 0.25; +#include "hlslCompat.glsl" // The scale equation calculated by Vernier's Graphical Analysis float vernierScale(float fCos) @@ -40,12 +35,27 @@ float vernierScale(float fCos) return 0.25 * outx; } +in vec4 vPosition; +in vec3 vNormal; +in vec4 vColor; +in vec2 vTexCoord0; + +// This is the shader input vertex structure. +#define IN_position vPosition +#define IN_normal vNormal +#define IN_color vColor + // This is the shader output data. -varying vec4 rayleighColor; -varying vec4 mieColor; -varying vec3 v3Direction; -varying float zPosition; -varying vec3 pos; +out vec4 rayleighColor; +#define OUT_rayleighColor rayleighColor +out vec4 mieColor; +#define OUT_mieColor mieColor +out vec3 v3Direction; +#define OUT_v3Direction v3Direction +out float zPosition; +#define OUT_zPosition zPosition +out vec3 pos; +#define OUT_pos pos uniform mat4 modelView; uniform vec4 misc; @@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs; uniform vec3 camPos; uniform vec3 lightDir; uniform vec4 invWaveLength; - -void main() -{ - vec4 position = gl_Vertex.xyzw; - vec3 normal = gl_Normal.xyz; - vec4 color = gl_MultiTexCoord0.xyzw; +uniform vec4 colorize; +vec3 desaturate(const vec3 color, const float desaturation) +{ + const vec3 gray_conv = vec3 (0.30, 0.59, 0.11); + return mix(color, vec3(dot(gray_conv , color)), desaturation); +} + +void main() +{ // Pull some variables out: float camHeight = misc.x; float camHeightSqr = misc.y; @@ -83,7 +96,7 @@ void main() // Get the ray from the camera to the vertex, // and its length (which is the far point of the ray // passing through the atmosphere). - vec3 v3Pos = position.xyz / 6378000.0;// / outerRadius; + vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius; vec3 newCamPos = vec3( 0, 0, camHeight ); v3Pos.z += innerRadius; vec3 v3Ray = v3Pos.xyz - newCamPos; @@ -97,16 +110,7 @@ void main() float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); float fStartAngle = dot(v3Ray, v3Start) / fHeight; - float x = 1.0 - fStartAngle; - float x5 = x * 5.25; - float x5p6 = (-6.80 + x5); - float xnew = (3.83 + x * x5p6); - float xfinal = (0.459 + x * xnew); - float xfinal2 = -0.00287 + x * xfinal; - float othx = exp( xfinal2 ); - float vscale1 = 0.25 * othx; - - float fStartOffset = fDepth * vscale1;//vernierScale(fStartAngle); + float fStartOffset = fDepth * vernierScale( fStartAngle ); // Initialize the scattering loop variables. float fSampleLength = fFar / 2.0; @@ -123,24 +127,8 @@ void main() float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; - x = 1.0 - fCameraAngle; - x5 = x * 5.25; - x5p6 = (-6.80 + x5); - xnew = (3.83 + x * x5p6); - xfinal = (0.459 + x * xnew); - xfinal2 = -0.00287 + x * xfinal; - othx = exp( xfinal2 ); - float vscale3 = 0.25 * othx; - - - x = 1.0 - fLightAngle; - x5 = x * 5.25; - x5p6 = (-6.80 + x5); - xnew = (3.83 + x * x5p6); - xfinal = (0.459 + x * xnew); - xfinal2 = -0.00287 + x * xfinal; - othx = exp( xfinal2 ); - float vscale2 = 0.25 * othx; + float vscale3 = vernierScale( fCameraAngle ); + float vscale2 = vernierScale( fLightAngle ); float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); @@ -150,16 +138,24 @@ void main() // Finally, scale the Mie and Rayleigh colors // and set up the varying variables for the pixel shader. - gl_Position = modelView * position; - mieColor.rgb = v3FrontColor * mieBrightness; - mieColor.a = 1.0; - rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); - rayleighColor.a = 1.0; - v3Direction = newCamPos - v3Pos.xyz; + gl_Position = modelView * IN_position; + OUT_mieColor.rgb = v3FrontColor * mieBrightness; + OUT_mieColor.a = 1.0; + OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + OUT_rayleighColor.a = 1.0; + OUT_v3Direction = newCamPos - v3Pos.xyz; + OUT_pos = IN_position.xyz; - // This offset is to get rid of the black line between the atmosky and the waterPlane - // along the horizon. - zPosition = position.z + 4000.0; - pos = position.xyz; +#ifdef USE_COLORIZE + + OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a; + + OUT_rayleighColor.r *= colorize.r; + OUT_rayleighColor.g *= colorize.g; + OUT_rayleighColor.b *= colorize.b; + +#endif + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/gl/torque.glsl b/Templates/Empty/game/shaders/common/gl/torque.glsl index dc73a706f..a98ef859f 100644 --- a/Templates/Empty/game/shaders/common/gl/torque.glsl +++ b/Templates/Empty/game/shaders/common/gl/torque.glsl @@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat ) return mat; } + /// The number of additional substeps we take when refining /// the results of the offset parallax mapping function below. /// @@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat ) /// Performs fast parallax offset mapping using /// multiple refinement steps. -////// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// +/// @param texMap The texture map whos alpha channel we sample the parallax depth. /// @param texCoord The incoming texture coordinate for sampling the parallax depth. /// @param negViewTS The negative view vector in tangent space. /// @param depthScale The parallax factor used to scale the depth result. /// vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) { - float depth = texture2D( texMap, texCoord ).a; + float depth = texture( texMap, texCoord ).a; vec2 offset = negViewTS.xy * ( depth * depthScale ); for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) { - depth = ( depth + texture2D( texMap, texCoord + offset ).a ) * 0.5; + depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5; offset = negViewTS.xy * ( depth * depthScale ); } @@ -151,59 +153,61 @@ vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float dept /// The maximum value for 16bit per component integer HDR encoding. const float HDR_RGB16_MAX = 100.0; -/// The maximum value for 10bit per component integer HDR encoding.const float HDR_RGB10_MAX = 4.0; +/// The maximum value for 10bit per component integer HDR encoding. +const float HDR_RGB10_MAX = 4.0; /// Encodes an HDR color for storage into a target. -vec3 hdrEncode( vec3 sample ){ +vec3 hdrEncode( vec3 _sample ) +{ #if defined( TORQUE_HDR_RGB16 ) - return sample / HDR_RGB16_MAX; + return _sample / HDR_RGB16_MAX; #elif defined( TORQUE_HDR_RGB10 ) - return sample / HDR_RGB10_MAX; + return _sample / HDR_RGB10_MAX; #else // No encoding. - return sample; + return _sample; #endif } /// Encodes an HDR color for storage into a target. -vec4 hdrEncode( vec4 sample ) +vec4 hdrEncode( vec4 _sample ) { - return vec4( hdrEncode( sample.rgb ), sample.a ); + return vec4( hdrEncode( _sample.rgb ), _sample.a ); } /// Decodes an HDR color from a target. -vec3 hdrDecode( vec3 sample ) +vec3 hdrDecode( vec3 _sample ) { #if defined( TORQUE_HDR_RGB16 ) - return sample * HDR_RGB16_MAX; + return _sample * HDR_RGB16_MAX; #elif defined( TORQUE_HDR_RGB10 ) - return sample * HDR_RGB10_MAX; + return _sample * HDR_RGB10_MAX; #else // No encoding. - return sample; + return _sample; #endif } /// Decodes an HDR color from a target. -vec4 hdrDecode( vec4 sample ) +vec4 hdrDecode( vec4 _sample ) { - return vec4( hdrDecode( sample.rgb ), sample.a ); + return vec4( hdrDecode( _sample.rgb ), _sample.a ); } /// Returns the luminance for an HDR pixel. -float hdrLuminance( vec3 sample ) +float hdrLuminance( vec3 _sample ) { // There are quite a few different ways to // calculate luminance from an rgb value. @@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample ) // // Max component luminance. // - //float lum = max( sample.r, max( sample.g, sample.b ) ); + //float lum = max( _sample.r, max( _sample.g, _sample.b ) ); //////////////////////////////////////////////////////////////////////////// // The perceptual relative luminance. @@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample ) // See http://en.wikipedia.org/wiki/Luminance_(relative) // const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); - float lum = dot( sample, RELATIVE_LUMINANCE ); + float lum = dot( _sample, RELATIVE_LUMINANCE ); //////////////////////////////////////////////////////////////////////////// // // The average component luminance. // //const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); - //float lum = dot( sample, AVERAGE_LUMINANCE ); + //float lum = dot( _sample, AVERAGE_LUMINANCE ); return lum; } +#ifdef TORQUE_PIXEL_SHADER +/// Called from the visibility feature to do screen +/// door transparency for fading of objects. +void fizzle(vec2 vpos, float visibility) +{ + // NOTE: The magic values below are what give us + // the nice even pattern during the fizzle. + // + // These values can be changed to get different + // patterns... some better than others. + // + // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 } + // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 } + // + // I'm sure there are many more patterns here to + // discover for different effects. + + mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 ); + if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard; + discard; +} +#endif //TORQUE_PIXEL_SHADER /// Basic assert macro. If the condition fails, then the shader will output color. /// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail. /// @param color The color that should be outputted if the condition fails. /// @note This macro will only work in the void main() method of a pixel shader. -#define assert(condition, color) { if(!any(condition)) { gl_FragColor = color; return; } } +#define assert(condition, color) { if(!any(condition)) { OUT_FragColor0 = color; return; } } #endif // _TORQUE_GLSL_ diff --git a/Templates/Empty/game/shaders/common/gl/wavesP.glsl b/Templates/Empty/game/shaders/common/gl/wavesP.glsl index 24bd8cbb4..ddb683947 100644 --- a/Templates/Empty/game/shaders/common/gl/wavesP.glsl +++ b/Templates/Empty/game/shaders/common/gl/wavesP.glsl @@ -28,10 +28,10 @@ uniform float specularPower; uniform vec4 ambient; uniform float accumTime; -varying vec2 TEX0; -varying vec4 outLightVec; -varying vec3 outPos; -varying vec3 outEyePos; +in vec2 TEX0; +in vec4 outLightVec; +in vec3 outPos; +in vec3 outEyePos; void main() { @@ -42,14 +42,14 @@ void main() texOffset.x = TEX0.x + sinOffset1 + sinOffset2; texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; - vec4 bumpNorm = texture2D(bumpMap, texOffset) * 2.0 - 1.0; - vec4 diffuse = texture2D(diffMap, texOffset); + vec4 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0; + vec4 diffuse = texture(diffMap, texOffset); - gl_FragColor = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); + OUT_FragColor0 = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); vec3 eyeVec = normalize(outEyePos - outPos); vec3 halfAng = normalize(eyeVec + outLightVec.xyz); float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; specular = pow(specular, specularPower); - gl_FragColor += specularColor * specular; + OUT_FragColor0 += specularColor * specular; } diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl index 6d3e36e7e..1807ac43f 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl @@ -20,16 +20,33 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 wsEyeDir; -varying vec4 ssPos; +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; + +#define IN_pos vPosition + +out vec4 wsEyeDir; +out vec4 ssPos; +out vec4 vsEyeDir; + +#define OUT_hpos gl_Position +#define OUT_wsEyeDir wsEyeDir +#define OUT_ssPos ssPos +#define OUT_vsEyeDir vsEyeDir uniform mat4 modelview; uniform mat4 objTrans; +uniform mat4 worldViewOnly; uniform vec3 eyePosWorld; void main() { - gl_Position = modelview * gl_Vertex; - wsEyeDir = objTrans * gl_Vertex - vec4( eyePosWorld, 0.0 ); - ssPos = gl_Position; + OUT_hpos = tMul( modelview, IN_pos ); + OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 ); + OUT_vsEyeDir = tMul( worldViewOnly, IN_pos ); + OUT_ssPos = OUT_hpos; + + correctSSP(gl_Position); } + diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl index 4a954ae84..e3ee59c8a 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl @@ -20,14 +20,15 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D prepassBuffer; uniform sampler1D depthViz; void main() { float depth = prepassUncondition( prepassBuffer, uv0 ).w; - gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1 ); + OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1.0 ); } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl index 580204487..aa17df4d6 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl @@ -20,15 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D lightInfoBuffer; void main() { - vec3 lightcolor; + vec3 lightcolor; float nl_Att, specular; - lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); - gl_FragColor = vec4( lightcolor, 1.0 ); + lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + OUT_FragColor0 = vec4( lightcolor, 1.0 ); } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl index 6f7c52486..e549922ff 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl @@ -20,15 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D lightInfoBuffer; void main() { - vec3 lightcolor; + vec3 lightcolor; float nl_Att, specular; - lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); - gl_FragColor = vec4( specular, specular, specular, 1.0 ); + lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + OUT_FragColor0 = vec4( specular, specular, specular, 1.0 ); } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl index 96b645524..f61706393 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl @@ -20,14 +20,14 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" - -varying vec2 uv0; -uniform sampler2D prepassTex; +in vec2 uv0; +uniform sampler2D prepassBuffer; void main() { - vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; - gl_FragColor = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); + vec3 normal = prepassUncondition( prepassBuffer, uv0 ).xyz; + OUT_FragColor0 = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl index 51609fc6b..e997950ab 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl @@ -19,13 +19,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D shadowMap; uniform sampler1D depthViz; void main() { - float depth = clamp( texture2DLod( shadowMap, uv0, 0 ).r, 0.0, 1.0 ); - gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1.0 ); + float depth = saturate( texture( shadowMap, uv0 ).r ); + OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1 ); } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl index 866a39b0b..76054eb09 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl @@ -24,7 +24,7 @@ vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) { vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos.y = 1.0 - outPos.y; outPos = ( outPos * rtParams.zw ) + rtParams.xy; - //outPos.y = 1.0 - outPos.y; return outPos; } diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl index ce5c2ad81..a80e856ed 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl @@ -20,24 +20,32 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "farFrustumQuad.glsl" -uniform vec4 renderTargetParams; - -varying vec4 hpos; -varying vec2 uv0; -varying vec3 wsEyeRay; +in vec4 vPosition; +in vec3 vNormal; +in vec3 vTangent; +in vec2 vTexCoord0; +uniform vec4 rtParams0; +out vec4 hpos; +out vec2 uv0; +out vec3 wsEyeRay; +out vec3 vsEyeRay; void main() -{ - // Expand the SS coordinate (stored in uv0) - hpos = vec4( gl_MultiTexCoord0.st * 2.0 - 1.0, 1.0, 1.0 ); - gl_Position = hpos; - +{ + hpos = vec4( vTexCoord0, 0, 1 ); + // Get a RT-corrected UV from the SS coord - uv0 = getUVFromSSPos( hpos.xyz, renderTargetParams ); + uv0 = getUVFromSSPos( hpos.xyz, rtParams0 ); + gl_Position = hpos; - // Interpolators will generate eye ray from far-frustum corners - wsEyeRay = gl_Vertex.xyz; + // Interpolators will generate eye rays the + // from far-frustum corners. + wsEyeRay = vTangent; + vsEyeRay = vNormal; + + correctSSP(gl_Position); } diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl index b135f1aa8..c0610508b 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/pointLightP.glsl @@ -21,34 +21,26 @@ //----------------------------------------------------------------------------- #include "../../../gl/hlslCompat.glsl" -#include "farFrustumQuad.glsl" -#include "lightingUtils.glsl" -#include "../../shadowMap/shadowMapIO_GLSL.h" #include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../../gl/lighting.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" -#if TORQUE_SM >= 30 +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else +#ifdef USE_COOKIE_TEX +/// The texture for cookie rendering. +uniform samplerCube cookieMap ; #endif - -// I am not sure if we should do this in a better way -//#define SHADOW_CUBE -//#define SHADOW_PARABOLOID -#define SHADOW_DUALPARABOLOID -#define SHADOW_DUALPARABOLOID_SINGLE_PASS - - #ifdef SHADOW_CUBE vec3 decodeShadowCoord( vec3 shadowCoord ) @@ -56,39 +48,47 @@ return shadowCoord; } - vec4 shadowSample( samplerCUBE shadowMap, vec3 shadowCoord ) + vec4 shadowSample( samplerCube shadowMap, vec3 shadowCoord ) { - return textureCUBE( shadowMap, shadowCoord ); + return texture( shadowMap, shadowCoord ); } - -#elif defined( SHADOW_DUALPARABOLOID ) + +#else vec3 decodeShadowCoord( vec3 paraVec ) { - // Swizzle z and y + // Flip y and z paraVec = paraVec.xzy; - #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + #ifndef SHADOW_PARABOLOID bool calcBack = (paraVec.z < 0.0); - if(calcBack) + if ( calcBack ) + { paraVec.z = paraVec.z * -1.0; + + #ifdef SHADOW_DUALPARABOLOID + paraVec.x = -paraVec.x; + #endif + } #endif vec3 shadowCoord; - shadowCoord.x = (paraVec.x / (2.0*(1.0 + paraVec.z))) + 0.5; - shadowCoord.y = ((paraVec.y / (2.0*(1.0 + paraVec.z))) + 0.5); + shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5; + shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5); shadowCoord.z = 0; // adjust the co-ordinate slightly if it is near the extent of the paraboloid // this value was found via experementation - shadowCoord.xy *= 0.997; + // NOTE: this is wrong, it only biases in one direction, not towards the uv + // center ( 0.5 0.5 ). + //shadowCoord.xy *= 0.997; - #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + #ifndef SHADOW_PARABOLOID // If this is the back, offset in the atlas - if(calcBack) + if ( calcBack ) shadowCoord.x += 1.0; // Atlasing front and back maps, so scale @@ -99,51 +99,35 @@ return shadowCoord; } -#else - - #error Unknown shadow type! - #endif -varying vec4 wsEyeDir; -varying vec4 ssPos; - - uniform sampler2D prePassBuffer; #ifdef SHADOW_CUBE - uniform samplerCube shadowMap; + uniform samplerCube shadowMap; #else - uniform sampler2D shadowMap; -#endif -#ifdef ACCUMULATE_LUV - uniform sampler2D scratchTarget; + uniform sampler2D shadowMap; #endif -uniform vec4 renderTargetParams; +uniform vec4 rtParams0; uniform vec3 lightPosition; uniform vec4 lightColor; -uniform float lightBrightness; -uniform float lightRange; +uniform float lightBrightness; +uniform float lightRange; uniform vec2 lightAttenuation; uniform vec4 lightMapParams; - -uniform vec3 eyePosWorld; -uniform vec4 farPlane; -uniform float negFarPlaneDotEye; -uniform mat3x3 worldToLightProj; - +uniform vec4 vsFarPlane; +uniform mat3 viewToLightProj; uniform vec4 lightParams; uniform float shadowSoftness; -uniform float constantSpecularPower; + - -void main() -{ +void main() +{ // Compute scene UV - vec3 ssPosP = ssPos.xyz / ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + vec3 ssPos = ssPos.xyz / ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); @@ -151,21 +135,17 @@ void main() float depth = prepassSample.a; // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); - - // Get world space pixel position - vec3 worldPos = eyePosWorld + eyeRay * depth; + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; // Build light vec, get length, clip pixel if needed - vec3 lightVec = lightPosition - worldPos; + vec3 lightVec = lightPosition - viewSpacePos; float lenLightV = length( lightVec ); - if ( lightRange - lenLightV < 0.0 ) - discard; - + clip( lightRange - lenLightV ); + // Get the attenuated falloff. float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - if ( atten - 1e-6 < 0.0 ) - discard; + clip( atten - 1e-6 ); // Normalize lightVec lightVec /= lenLightV; @@ -181,61 +161,73 @@ void main() #else - // Convert the light vector into a shadow map - // here once instead of in the filtering loop. - vec4 shadowCoord = vec4(0.0); - #ifdef SHADOW_CUBE - shadowCoord.xy = decodeShadowCoord( -lightVec ); - #else - shadowCoord.xy = decodeShadowCoord( worldToLightProj * -lightVec ).xy; - #endif - // Get a linear depth from the light source. - float distToLight = lenLightV / lightRange; + float distToLight = lenLightV / lightRange; - #ifdef SOFTSHADOW_SM3 + #ifdef SHADOW_CUBE + + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = texture( shadowMap, tMul( viewToLightProj, -lightVec ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + + #else + vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy; + float shadowed = softShadow_filter( shadowMap, - gTapRotationTex, - ssPosP.xy, - shadowCoord.xy, + ssPos.xy, + shadowCoord, shadowSoftness, distToLight, nDotL, lightParams.y ); - - #else // !SOFTSHADOW_SM3 - - // TODO: Implement the SM2 lower quality - // shadow filtering method. #endif #endif // !NO_SHADOW - + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + // NOTE: Do not clip on fully shadowed pixels as it would // cause the hardware occlusion query to disable the shadow. // Specular term - float specular = calcSpecular( lightVec, - normal, - normalize( -eyeRay ), - constantSpecularPower, - shadowed * atten * lightBrightness ); - - // N.L * Attenuation - float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); - - // In LUV color mode we need to blend in the - // output from the previous target. - vec4 previousPix = vec4(0.0); - #ifdef ACCUMULATE_LUV - previousPix = texture2DLod( scratchTarget, uvScene, 0 ); - #endif + float specular = AL_CalcSpecular( lightVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, - Sat_NL_Att, - specular, - previousPix ) * lightMapParams; + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); } diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl index 8ef09ed2f..a14213946 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/softShadow.glsl @@ -19,113 +19,141 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- - - -#define NUM_TAPS 12 - -#define NUM_PRE_TAPS 4 - -/// The non-uniform poisson disk used in the -/// high quality shadow filtering. -vec2 sNonUniformTaps[NUM_TAPS]; -void initNonUniformTaps() + +#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) + +#define NUM_PRE_TAPS 4 +#define NUM_TAPS 12 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_TAPS] = vec2[] +( + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + vec2( 0.992833, 0.979309 ), + vec2( -0.998585, 0.985853 ), + vec2( 0.949299, -0.882562 ), + vec2( -0.941358, -0.893924 ), + + // The rest of the samples. + vec2( 0.545055, -0.589072 ), + vec2( 0.346526, 0.385821 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.248676, -0.679605 ), + vec2( -0.569502, -0.390637 ), + vec2( -0.614096, 0.212577 ), + vec2( -0.259178, 0.876272 ), + vec2( 0.649526, 0.864333 ) +); + +#else + +#define NUM_PRE_TAPS 5 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[] +( + vec2( 0.892833, 0.959309 ), + vec2( -0.941358, -0.873924 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.348676, -0.679605 ), + vec2( -0.569502, -0.390637 ) +); + +#endif + + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +uniform sampler2D gTapRotationTex ; + + +float softShadow_sampleTaps( sampler2D shadowMap, + vec2 sinCos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) { - // These first 4 taps are located around the edges - // of the disk and are used to predict fully shadowed - // or unshadowed areas. - sNonUniformTaps[0] = vec2( 0.992833, 0.979309 ); - sNonUniformTaps[1] = vec2( -0.998585, 0.985853 ); - sNonUniformTaps[2] = vec2( 0.949299, -0.882562 ); - sNonUniformTaps[3] = vec2( -0.941358, -0.893924 ); - - // The rest of the samples. - sNonUniformTaps[4] = vec2( 0.545055, -0.589072 ); - sNonUniformTaps[5] = vec2( 0.346526, 0.385821 ); - sNonUniformTaps[6] = vec2( -0.260183, 0.334412 ); - sNonUniformTaps[7] = vec2( 0.248676, -0.679605 ); - sNonUniformTaps[8] = vec2( -0.569502, -0.390637 ); - sNonUniformTaps[9] = vec2( -0.014096, 0.012577 ); - sNonUniformTaps[10] = vec2( -0.259178, 0.876272 ); - sNonUniformTaps[11] = vec2( 0.649526, 0.664333 ); + float shadow = 0; + + vec2 tap = vec2(0); + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r; + + float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; } - -/// The texture used to do per-pixel pseudorandom -/// rotations of the filter taps. -uniform sampler2D gTapRotationTex; - - -float softShadow_sampleTaps( sampler2D shadowMap, - vec2 sinCos, - vec2 shadowPos, - float filterRadius, - float distToLight, - float esmFactor, - int startTap, - int endTap ) -{ - initNonUniformTaps(); - float shadow = 0.0; - - vec2 tap = vec2(0.0); - for ( int t = startTap; t < endTap; t++ ) - { - tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; - tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; - float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r; - - float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); - shadow += esm / float( endTap - startTap ); - } - - return shadow; -} - - -// HACK! HACK! HACK! -// We take the noise texture directly as the second parameter to ensure that it -// is the "last used" sampler, and thus doesn't collide with the prepass buffer -// or shadow map. If we use gTapRotationTex directly here, then it is the first -// used sampler and will collide with the prepass buffer. -float softShadow_filter( sampler2D shadowMap, - sampler2D noiseTexture, - vec2 vpos, - vec2 shadowPos, - float filterRadius, - float distToLight, - float dotNL, - float esmFactor ) -{ - // Lookup the random rotation for this screen pixel. - vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0; - - // Do the prediction taps first. - float shadow = softShadow_sampleTaps( shadowMap, - sinCos, - shadowPos, - filterRadius, - distToLight, - esmFactor, - 0, - NUM_PRE_TAPS ); - - // Only do the expensive filtering if we're really - // in a partially shadowed area. - if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0.0 ) > 0.06 ) - { - shadow += softShadow_sampleTaps( shadowMap, - sinCos, - shadowPos, - filterRadius, - distToLight, - esmFactor, - NUM_PRE_TAPS, - NUM_TAPS ); - - // This averages the taps above with the results - // of the prediction samples. - shadow *= 0.5; - } - - return shadow; -} \ No newline at end of file + + +float softShadow_filter( sampler2D shadowMap, + vec2 vpos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + #ifndef SOFTSHADOW + + // If softshadow is undefined then we skip any complex + // filtering... just do a single sample ESM. + + float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r; + float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #else + + // Lookup the random rotation for this screen pixel. + vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // We live with only the pretap results if we don't + // have high quality shadow filtering enabled. + #ifdef SOFTSHADOW_HIGH_QUALITY + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + #endif // SOFTSHADOW_HIGH_QUALITY + + #endif // SOFTSHADOW + + return shadow; +} \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl index d29f5edb0..c07be1f34 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/spotLightP.glsl @@ -25,58 +25,49 @@ #include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" #include "shadergen:/autogenConditioners.h" +#include "softShadow.glsl" +#include "../../../gl/lighting.glsl" +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; -#if TORQUE_SM >= 30 +#define IN_wsEyeDir wsEyeDir +#define IN_ssPos ssPos +#define IN_vsEyeDir vsEyeDir - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else +#ifdef USE_COOKIE_TEX +/// The texture for cookie rendering. +uniform sampler2D cookieMap; #endif - -varying vec4 ssPos; -varying vec4 wsEyeDir; - - uniform sampler2D prePassBuffer; uniform sampler2D shadowMap; -#ifdef ACCUMULATE_LUV - uniform sampler2D scratchTarget; -#endif -uniform vec4 renderTargetParams; +uniform vec4 rtParams0; uniform vec3 lightPosition; uniform vec4 lightColor; -uniform float lightBrightness; -uniform float lightRange; +uniform float lightBrightness; +uniform float lightRange; uniform vec2 lightAttenuation; uniform vec3 lightDirection; uniform vec4 lightSpotParams; uniform vec4 lightMapParams; -uniform vec3 eyePosWorld; -uniform vec4 farPlane; -uniform float negFarPlaneDotEye; -uniform mat4x4 worldToLightProj; +uniform vec4 vsFarPlane; +uniform mat4 viewToLightProj; uniform vec4 lightParams; uniform float shadowSoftness; -uniform float constantSpecularPower; - void main() -{ +{ // Compute scene UV - vec3 ssPosP = ssPos.xyz / ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); @@ -84,85 +75,92 @@ void main() float depth = prepassSample.a; // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); - - // Get world space pixel position - vec3 worldPos = eyePosWorld + eyeRay * depth; + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; // Build light vec, get length, clip pixel if needed - vec3 lightToPxlVec = worldPos - lightPosition; + vec3 lightToPxlVec = viewSpacePos - lightPosition; float lenLightV = length( lightToPxlVec ); lightToPxlVec /= lenLightV; - //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); + //lightDirection = vec3( -lightDirection.xy, lightDirection.z ); //vec3( 0, 0, -1 ); float cosAlpha = dot( lightDirection, lightToPxlVec ); - if ( cosAlpha - lightSpotParams.x < 0.0 ) discard; - if ( lightRange - lenLightV < 0.0 ) discard; + clip( cosAlpha - lightSpotParams.x ); + clip( lightRange - lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV ); atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; - if ( atten - 1e-6 < 0.0 ) discard; + clip( atten - 1e-6 ); + atten = saturate( atten ); float nDotL = dot( normal, -lightToPxlVec ); + // Get the shadow texture coordinate + vec4 pxlPosLightProj = tMul( viewToLightProj, vec4( viewSpacePos, 1 ) ); + vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; + #ifdef NO_SHADOW float shadowed = 1.0; #else - // Find Shadow coordinate - vec4 pxlPosLightProj = vec4( worldToLightProj * vec4( worldPos, 1.0 ) ); - vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); - // Get a linear depth from the light source. float distToLight = pxlPosLightProj.z / lightRange; - #ifdef SOFTSHADOW_SM3 - - float shadowed = softShadow_filter( shadowMap, - gTapRotationTex, - ssPosP.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - #else // !SOFTSHADOW_SM3 - - // Simple exponential shadow map. - float occluder = decodeShadowMap( texture2DLod( shadowMap, shadowCoord, 0.0 ) ); - float esmFactor = lightParams.y; - float shadowed = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); - - #endif + float shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); #endif // !NO_SHADOW - + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, shadowCoord ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + // NOTE: Do not clip on fully shadowed pixels as it would // cause the hardware occlusion query to disable the shadow. // Specular term - float specular = calcSpecular( -lightToPxlVec, - normal, - normalize( -eyeRay ), - constantSpecularPower, - shadowed * atten * lightBrightness ); - - // N.L * Attenuation - float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); - - // In LUV color mode we need to blend in the - // output from the previous target. - vec4 previousPix = vec4(0.0); - #ifdef ACCUMULATE_LUV - previousPix = texture2DLod( scratchTarget, uvScene, 0.0 ); - #endif + float specular = AL_CalcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, - Sat_NL_Att, - specular, - previousPix ) * lightMapParams; + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); } diff --git a/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl b/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl index bbd567fd0..0178c35ea 100644 --- a/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl @@ -22,40 +22,32 @@ #include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "../../../gl/torque.glsl" +#include "../../../gl/lighting.glsl" #include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" -varying vec2 uv0; -varying vec3 wsEyeRay; +in vec4 hpos; +in vec2 uv0; +in vec3 wsEyeRay; +in vec3 vsEyeRay; -uniform sampler2D prePassBuffer; -uniform sampler2D ShadowMap; +uniform sampler2D ShadowMap ; -#if TORQUE_SM >= 30 - - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else - - - +#ifdef USE_SSAO_MASK +uniform sampler2D ssaoMask ; +uniform vec4 rtParams2; #endif - + +uniform sampler2D prePassBuffer; uniform vec3 lightDirection; uniform vec4 lightColor; -uniform float lightBrightness; -uniform vec4 lightAmbient; -uniform vec4 lightTrilight; - -uniform vec3 eyePosWorld; - -uniform mat4 worldToLightProj; -uniform vec4 splitDistStart; -uniform vec4 splitDistEnd; +uniform float lightBrightness; +uniform vec4 lightAmbient; +uniform vec3 eyePosWorld; +uniform mat4x4 worldToLightProj; uniform vec4 scaleX; uniform vec4 scaleY; uniform vec4 offsetX; @@ -65,16 +57,12 @@ uniform vec4 atlasYOffset; uniform vec2 atlasScale; uniform vec4 zNearFarInvNearFar; uniform vec4 lightMapParams; - -uniform float constantSpecularPower; uniform vec2 fadeStartLength; uniform vec4 farPlaneScalePSSM; -uniform vec4 splitFade; uniform vec4 overDarkPSSM; uniform float shadowSoftness; - -void main() +void main() { // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 ); @@ -83,148 +71,162 @@ void main() // Use eye ray to get ws pos vec4 worldPos = vec4(eyePosWorld + wsEyeRay * depth, 1.0f); - + // Get the light attenuation. float dotNL = dot(-lightDirection, normal); + + #ifdef PSSM_DEBUG_RENDER + vec3 debugColor = vec3(0); + #endif #ifdef NO_SHADOW // Fully unshadowed. float shadowed = 1.0; + #ifdef PSSM_DEBUG_RENDER + debugColor = vec3(1.0); + #endif + #else - + // Compute shadow map coordinate - vec4 pxlPosLightProj = worldToLightProj * worldPos; + vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos); vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; - - float distOffset = 0.0; - float shadowed = 0.0; - float fadeAmt = 0.0; - vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); - - // Calculate things dependant on the shadowmap split - for ( int i = 0; i < 2; i++ ) - { - float zDistSplit = zDist.x + distOffset; - vec4 mask0; - mask0.x = float(zDistSplit >= splitDistStart.x); - mask0.y = float(zDistSplit >= splitDistStart.y); - mask0.z = float(zDistSplit >= splitDistStart.z); - mask0.w = float(zDistSplit >= splitDistStart.w); + + // Distance to light, in shadowmap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; - vec4 mask1; - mask1.x = float(zDistSplit < splitDistEnd.x); - mask1.y = float(zDistSplit < splitDistEnd.y); - mask1.z = float(zDistSplit < splitDistEnd.z); - mask1.w = float(zDistSplit < splitDistEnd.w); + // Figure out which split to sample from. Basically, we compute the shadowmap sample coord + // for all of the splits and then check if its valid. + vec4 shadowCoordX = vec4( baseShadowCoord.x ); + vec4 shadowCoordY = vec4( baseShadowCoord.y ); + vec4 farPlaneDists = vec4( distToLight ); + shadowCoordX *= scaleX; + shadowCoordY *= scaleY; + shadowCoordX += offsetX; + shadowCoordY += offsetY; + farPlaneDists *= farPlaneScalePSSM; + + // If the shadow sample is within -1..1 and the distance + // to the light for this pixel is less than the far plane + // of the split, use it. + vec4 finalMask; + if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 && + shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 && + farPlaneDists.x < 1.0 ) + finalMask = vec4(1, 0, 0, 0); + + else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 && + shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 && + farPlaneDists.y < 1.0 ) + finalMask = vec4(0, 1, 0, 0); + + else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 && + shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 && + farPlaneDists.z < 1.0 ) + finalMask = vec4(0, 0, 1, 0); - vec4 finalMask = mask0 * mask1; + else + finalMask = vec4(0, 0, 0, 1); - float splitFadeDist = dot( finalMask, splitFade ); - vec2 finalScale; - finalScale.x = dot(finalMask, scaleX); - finalScale.y = dot(finalMask, scaleY); + #ifdef PSSM_DEBUG_RENDER + if ( finalMask.x > 0 ) + debugColor += vec3( 1, 0, 0 ); + else if ( finalMask.y > 0 ) + debugColor += vec3( 0, 1, 0 ); + else if ( finalMask.z > 0 ) + debugColor += vec3( 0, 0, 1 ); + else if ( finalMask.w > 0 ) + debugColor += vec3( 1, 1, 0 ); + #endif - vec2 finalOffset; - finalOffset.x = dot(finalMask, offsetX); - finalOffset.y = dot(finalMask, offsetY); - - vec2 shadowCoord; - shadowCoord = baseShadowCoord * finalScale; - shadowCoord += finalOffset; + // Here we know what split we're sampling from, so recompute the texcoord location + // Yes, we could just use the result from above, but doing it this way actually saves + // shader instructions. + vec2 finalScale; + finalScale.x = dot(finalMask, scaleX); + finalScale.y = dot(finalMask, scaleY); - // Convert to texcoord space - shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); - //shadowCoord.y = 1.0f - shadowCoord.y; + vec2 finalOffset; + finalOffset.x = dot(finalMask, offsetX); + finalOffset.y = dot(finalMask, offsetY); - // Move around inside of atlas - vec2 aOffset; - aOffset.x = dot(finalMask, atlasXOffset); - aOffset.y = dot(finalMask, atlasYOffset); + vec2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; - shadowCoord *= atlasScale; - shadowCoord += aOffset; - - // Distance to light, in shadowmap space - float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; - - // Each split has a different far plane, take this into account. - float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); - distToLight *= farPlaneScale; - - #ifdef SOFTSHADOW_SM3 + // Convert to texcoord space + shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); + shadowCoord.y = 1.0f - shadowCoord.y; - float esmShadow = softShadow_filter( ShadowMap, - gTapRotationTex, - uv0.xy, - shadowCoord, - farPlaneScale * shadowSoftness, - distToLight, - dotNL, - dot( finalMask, overDarkPSSM ) ); - - #else // !SOFTSHADOW_SM3 + // Move around inside of atlas + vec2 aOffset; + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); - float occluder = decodeShadowMap( texture2DLod( ShadowMap, shadowCoord, 0.0 ) ); - float overDark = dot( finalMask, overDarkPSSM ); - float esmShadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); - - #endif - - if ( i == 0 ) - { - float endDist = dot(splitDistEnd, finalMask); - fadeAmt = smoothstep(endDist - splitFadeDist, endDist, zDist).x; - shadowed = esmShadow * ( 1.0 - fadeAmt ); - } - else - shadowed += esmShadow * fadeAmt; - - distOffset += splitFadeDist; - } + shadowCoord *= atlasScale; + shadowCoord += aOffset; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + float shadowed = softShadow_filter( ShadowMap, + uv0.xy, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + dotNL, + dot( finalMask, overDarkPSSM ) ); // Fade out the shadow at the end of the range. + vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; - shadowed = mix( shadowed, 1.0, clamp( fadeOutAmt, 0.0, 1.0 ) ); + shadowed = mix( shadowed, 1.0, saturate( fadeOutAmt ) ); + + #ifdef PSSM_DEBUG_RENDER + if ( fadeOutAmt > 1.0 ) + debugColor = vec3(1.0); + #endif #endif // !NO_SHADOW - - // Calc lighting coefficents - float specular = calcSpecular( -lightDirection, - normal, - normalize(-wsEyeRay), - constantSpecularPower, - shadowed * lightBrightness ); - - float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed; - - // Trilight, described by Tom Forsyth - // http://home.comcast.net/~tom_forsyth/papers/trilight/trilight.html -#ifdef ACCUMULATE_LUV - // In LUV multiply in the brightness of the light color (normaly done in the attenuate function) - Sat_NL_Att *= lightColor.a; + // Specular term + float specular = AL_CalcSpecular( -lightDirection, + normal, + normalize(-vsEyeRay) ) * lightBrightness * shadowed; - vec4 ambientBlend = lightAmbient; - ambientBlend.b *= clamp(-dotNL, 0.0, 1.0); - - vec3 trilight = lightTrilight.rgb; - trilight.b *= clamp(1.0 - abs(dotNL), 0.0, 1.0); - - ambientBlend.rg = mix(ambientBlend.rg, trilight.rg, clamp(0.5 * trilight.b / lightAmbient.b, 0.0, 1.0)); - ambientBlend.b += trilight.b; + float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = lightAmbient; -#else + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = dotNL < 0.0f ? 1.0f : shadowed; - // RGB - // TODO: Trilight seems broken... it does lighting in shadows! - //vec4 ambientBlend = vec4(lightTrilight.rgb * clamp(1.0 - abs(dotNL), 0.0, 1.0) + lightAmbient.rgb * clamp(-dotNL, 0.0, 1.0), 0.0); - vec4 ambientBlend = vec4(lightAmbient.rgb, 0.0); + Sat_NL_Att = 1.0f; + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } -#endif + // Sample the AO texture. + #ifdef USE_SSAO_MASK + float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams2 ) ).r; + addToResult *= ao; + #endif + + #ifdef PSSM_DEBUG_RENDER + lightColorOut = debugColor; + #endif + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, Sat_NL_Att, specular, ambientBlend) * lightMapParams; } diff --git a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl index 238721e5e..4e97fa347 100644 --- a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl @@ -20,35 +20,27 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" + uniform sampler2D diffuseMap; -varying vec2 uv; +in vec2 uv; uniform vec2 oneOverTargetSize; +const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 ); +const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 ); + void main() { - vec2 sNonUniformTaps[8]; - - sNonUniformTaps[0] = vec2(0.992833, 0.979309); - sNonUniformTaps[1] = vec2(-0.998585, 0.985853); - sNonUniformTaps[2] = vec2(0.949299, -0.882562); - sNonUniformTaps[3] = vec2(-0.941358, -0.893924); - sNonUniformTaps[4] = vec2(0.545055, -0.589072); - sNonUniformTaps[5] = vec2(0.346526, 0.385821); - sNonUniformTaps[6] = vec2(-0.260183, 0.334412); - sNonUniformTaps[7] = vec2(0.248676, -0.679605); + vec4 OUT = texture( diffuseMap, uv ) * weight[0]; - gl_FragColor = vec4(0.0); - - vec2 texScale = vec2(1.0); - - for ( int i=0; i < 4; i++ ) + for ( int i=1; i < 3; i++ ) { - vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i]; - gl_FragColor += texture2D( diffuseMap, uv + offset ); + vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize; + OUT += texture( diffuseMap, uv + _sample ) * weight[i]; + OUT += texture( diffuseMap, uv - _sample ) * weight[i]; } - - gl_FragColor /= vec4(4.0); - gl_FragColor.rgb = vec3(0.0); + + OUT_FragColor0 = OUT; } diff --git a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl index cbf3696be..0eeb2e0fd 100644 --- a/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl +++ b/Templates/Empty/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl @@ -22,13 +22,16 @@ #include "../../../../../../shaders/common/gl/torque.glsl" -uniform vec2 oneOverTargetSize; +in vec4 vPosition; +in vec2 vTexCoord0; + uniform vec4 rtParams0; -varying vec2 uv; +out vec2 uv; void main() { - gl_Position = gl_Vertex; - uv = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); + gl_Position = vPosition; + uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 ); + gl_Position.y *= -1; //correct ssp } diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl index 2800a3f17..0f568c716 100644 --- a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl @@ -26,7 +26,7 @@ uniform sampler2D diffuseMap0; uniform float texSize; uniform vec2 blurDimension; -varying vec2 tex0; +in vec2 tex0; void main() { @@ -40,8 +40,8 @@ void main() vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); for(int i = 0; i < int(blurSamples); i++) { - accum += texture2D(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); + accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); } accum /= blurSamples; - gl_FragColor = accum; + OUT_FragColor0 = accum; } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl index 3850f83c7..9fc436f6c 100644 --- a/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl +++ b/Templates/Empty/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl @@ -20,12 +20,15 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 tex0; +out vec2 tex0; void main() { - gl_Position = modelview * gl_Vertex; - tex0 = gl_MultiTexCoord0.st; + gl_Position = modelview * vPosition; + tex0 = vTexCoord0.st; } \ No newline at end of file diff --git a/Templates/Empty/game/shaders/common/postFx/postFxV.glsl b/Templates/Empty/game/shaders/common/postFx/postFxV.glsl index 3aded2e0f..96a5ec819 100644 --- a/Templates/Empty/game/shaders/common/postFx/postFxV.glsl +++ b/Templates/Empty/game/shaders/common/postFx/postFxV.glsl @@ -22,27 +22,30 @@ #include "./../gl/torque.glsl" +in vec4 vPosition; +in vec2 vTexCoord0; +in vec3 vTexCoord1; uniform vec4 rtParams0; uniform vec4 rtParams1; uniform vec4 rtParams2; uniform vec4 rtParams3; -varying vec2 uv0; -varying vec2 uv1; -varying vec2 uv2; -varying vec2 uv3; -varying vec3 wsEyeRay; +out vec2 uv0; +out vec2 uv1; +out vec2 uv2; +out vec2 uv3; +out vec3 wsEyeRay; void main() { - gl_Position = gl_Vertex; + gl_Position = vPosition; - uv0 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); - uv1 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams1 ); - uv2 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams2 ); - uv3 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams3 ); + uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 ); + uv1 = viewportCoordToRenderTarget( vTexCoord0, rtParams1 ); + uv2 = viewportCoordToRenderTarget( vTexCoord0, rtParams2 ); + uv3 = viewportCoordToRenderTarget( vTexCoord0, rtParams3 ); - wsEyeRay = gl_MultiTexCoord1.xyz; + wsEyeRay = vTexCoord1; } diff --git a/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl b/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl index 3817e1de2..a2e4af787 100644 --- a/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl +++ b/Templates/Empty/game/shaders/common/terrain/gl/blendP.glsl @@ -23,8 +23,10 @@ #include "../terrain.glsl" #include "../../gl/hlslCompat.glsl" -varying vec2 layerCoord; -varying vec2 texCoord; +in vec2 layerCoord; +#define IN_layerCoord layerCoord +in vec2 texCoord; +#define IN_texCoord texCoord uniform sampler2D layerTex; uniform sampler2D textureMap; @@ -33,12 +35,12 @@ uniform float layerSize; void main() { - vec4 layerSample = round(texture2D( layerTex, layerCoord ) * 255.0); + vec4 layerSample = round(texture( layerTex, IN_layerCoord ) * 255.0); - float blend = calcBlend( texId, layerCoord, layerSize, layerSample ); + float blend = calcBlend( texId, IN_layerCoord, layerSize, layerSample ); if(blend - 0.0001 < 0.0) discard; - gl_FragColor = vec4( texture2D( textureMap, texCoord ).rgb, blend ); + OUT_FragColor0 = vec4( texture( textureMap, IN_texCoord ).rgb, blend ); } diff --git a/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl b/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl index 44362085b..dc7b7befa 100644 --- a/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl +++ b/Templates/Empty/game/shaders/common/terrain/gl/blendV.glsl @@ -23,14 +23,19 @@ /// The vertex shader used in the generation and caching of the /// base terrain texture. -varying vec2 layerCoord; -varying vec2 texCoord; +in vec4 vPosition; +in vec2 vTexCoord0; + +out vec2 layerCoord; +out vec2 texCoord; uniform vec2 texScale; void main() { - gl_Position = vec4(gl_Vertex.xyz, 1.0); - layerCoord = gl_MultiTexCoord0.st; - texCoord = gl_MultiTexCoord0.st * texScale; + gl_Position = vec4(vPosition.xyz, 1.0); + layerCoord = vTexCoord0.st; + texCoord = vTexCoord0.st * texScale; + + gl_Position.y *= -1; } diff --git a/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl b/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl index 72232622a..44207dea9 100644 --- a/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl +++ b/Templates/Empty/game/shaders/common/water/gl/waterBasicP.glsl @@ -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 } diff --git a/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl b/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl index bb2a0c954..1634fd2de 100644 --- a/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl +++ b/Templates/Empty/game/shaders/common/water/gl/waterBasicV.glsl @@ -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); } diff --git a/Templates/Empty/game/shaders/common/water/gl/waterP.glsl b/Templates/Empty/game/shaders/common/water/gl/waterP.glsl index bf482d724..3e15fe576 100644 --- a/Templates/Empty/game/shaders/common/water/gl/waterP.glsl +++ b/Templates/Empty/game/shaders/common/water/gl/waterP.glsl @@ -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 ); } diff --git a/Templates/Empty/game/shaders/common/water/gl/waterV.glsl b/Templates/Empty/game/shaders/common/water/gl/waterV.glsl index d4337476f..490af63a7 100644 --- a/Templates/Empty/game/shaders/common/water/gl/waterV.glsl +++ b/Templates/Empty/game/shaders/common/water/gl/waterV.glsl @@ -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); } + diff --git a/Templates/Full/game/shaders/common/gl/blurP.glsl b/Templates/Full/game/shaders/common/gl/blurP.glsl index bc05b992f..5c37ebc6b 100644 --- a/Templates/Full/game/shaders/common/gl/blurP.glsl +++ b/Templates/Full/game/shaders/common/gl/blurP.glsl @@ -26,12 +26,12 @@ uniform vec4 kernel; uniform sampler2D diffuseMap; -varying vec2 texc0, texc1, texc2, texc3; +in vec2 texc0, texc1, texc2, texc3; void main() { - gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x; - gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y; - gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z; - gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w; + OUT_FragColor0 = texture(diffuseMap, texc0) * kernel.x; + OUT_FragColor0 += texture(diffuseMap, texc1) * kernel.y; + OUT_FragColor0 += texture(diffuseMap, texc2) * kernel.z; + OUT_FragColor0 += texture(diffuseMap, texc3) * kernel.w; } diff --git a/Templates/Full/game/shaders/common/gl/blurV.glsl b/Templates/Full/game/shaders/common/gl/blurV.glsl index d5d615fb9..1bfb0cd1b 100644 --- a/Templates/Full/game/shaders/common/gl/blurV.glsl +++ b/Templates/Full/game/shaders/common/gl/blurV.glsl @@ -24,20 +24,25 @@ // Glow shader //***************************************************************************** +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + uniform mat4 modelview; uniform vec2 offset0, offset1, offset2, offset3; -varying vec2 texc0, texc1, texc2, texc3; +out vec2 texc0, texc1, texc2, texc3; void main() { - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - vec2 tc = gl_MultiTexCoord0.st; + vec2 tc = vTexCoord0.st; tc.y = 1.0 - tc.y; texc0 = tc + offset0; texc1 = tc + offset1; texc2 = tc + offset2; texc3 = tc + offset3; + gl_Position.y *= -1; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/gl/cloudLayerP.glsl b/Templates/Full/game/shaders/common/gl/cloudLayerP.glsl index 326f2d3c6..da3996d58 100644 --- a/Templates/Full/game/shaders/common/gl/cloudLayerP.glsl +++ b/Templates/Full/game/shaders/common/gl/cloudLayerP.glsl @@ -22,12 +22,20 @@ #include "hlslCompat.glsl" -varying vec4 texCoord12; -varying vec4 texCoord34; -varying vec3 vLightTS; // light vector in tangent space, denormalized -varying vec3 vViewTS; // view vector in tangent space, denormalized -varying vec3 vNormalWS; // Normal vector in world space -varying float worldDist; +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +//ConnectData +in vec4 texCoord12; +#define IN_texCoord12 texCoord12 +in vec4 texCoord34; +#define IN_texCoord34 texCoord34 +in vec3 vLightTS; // light vector in tangent space, denormalized +#define IN_vLightTS vLightTS +in vec3 vViewTS; // view vector in tangent space, denormalized +#define IN_vViewTS vViewTS +in float worldDist; +#define IN_worldDist worldDist //----------------------------------------------------------------------------- // Uniforms @@ -37,6 +45,7 @@ uniform vec3 ambientColor; uniform vec3 sunColor; uniform float cloudCoverage; uniform vec3 cloudBaseColor; +uniform float cloudExposure; //----------------------------------------------------------------------------- // Globals @@ -97,26 +106,25 @@ void main() // Normalize the interpolated vectors: vec3 vViewTS = normalize( vViewTS ); vec3 vLightTS = normalize( vLightTS ); - vec3 vNormalWS = normalize( vNormalWS ); - vec4 cResultColor = float4( 0, 0, 0, 1 ); + vec4 cResultColor = vec4( 0, 0, 0, 1 ); - vec2 texSample = texCoord12.xy; + vec2 texSample = IN_texCoord12.xy; - vec4 noise1 = texture2D( normalHeightMap, texCoord12.zw ); + vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw ); noise1 = normalize( ( noise1 - 0.5 ) * 2.0 ); //return noise1; - vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy ); + vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy ); noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); //return noise2; vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; - //return float4( noiseNormal, 1.0 ); + //return vec4( noiseNormal, 1.0 ); float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 ); - vec3 vNormalTS = normalize( texture2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); + vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 ); vNormalTS += noiseNormal; vNormalTS = normalize( vNormalTS ); @@ -124,16 +132,14 @@ void main() cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); float coverage = ( cloudCoverage - 0.5 ) * 2.0; - cResultColor.a = texture2D( normalHeightMap, texSample ).a + coverage + noiseHeight; + cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight; if ( cloudCoverage > -1.0 ) cResultColor.a /= 1.0 + coverage; - cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) ); + cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 ); - cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(worldDist,2.0) ); + cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) ); - // If using HDR rendering, make sure to tonemap the resuld color prior to outputting it. - // But since this example isn't doing that, we just output the computed result color here: - gl_FragColor = cResultColor; + OUT_FragColor0 = cResultColor; } diff --git a/Templates/Full/game/shaders/common/gl/cloudLayerV.glsl b/Templates/Full/game/shaders/common/gl/cloudLayerV.glsl index 39a6f4ba8..395c6f286 100644 --- a/Templates/Full/game/shaders/common/gl/cloudLayerV.glsl +++ b/Templates/Full/game/shaders/common/gl/cloudLayerV.glsl @@ -20,12 +20,24 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 texCoord12; -varying vec4 texCoord34; -varying vec3 vLightTS; // light vector in tangent space, denormalized -varying vec3 vViewTS; // view vector in tangent space, denormalized -varying vec3 vNormalWS; // Normal vector in world space -varying float worldDist; +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec3 vNormal; +in vec3 vBinormal; +in vec3 vTangent; +in vec2 vTexCoord0; + +out vec4 texCoord12; +#define OUT_texCoord12 texCoord12 +out vec4 texCoord34; +#define OUT_texCoord34 texCoord34 +out vec3 vLightTS; // light vector in tangent space, denormalized +#define OUT_vLightTS vLightTS +out vec3 vViewTS; // view vector in tangent space, denormalized +#define OUT_vViewTS vViewTS +out float worldDist; +#define OUT_worldDist worldDist //----------------------------------------------------------------------------- // Uniforms @@ -43,37 +55,37 @@ uniform vec3 texScale; //----------------------------------------------------------------------------- void main() { - vec4 pos = gl_Vertex; - vec3 normal = gl_Normal; - vec3 binormal = gl_MultiTexCoord0.xyz; - vec3 tangent = gl_MultiTexCoord1.xyz; - vec2 uv0 = gl_MultiTexCoord2.st; + vec4 IN_pos = vPosition; + vec3 IN_normal = vNormal; + vec3 IN_binormal = vBinormal; + vec3 IN_tangent = vTangent; + vec2 IN_uv0 = vTexCoord0.st; - gl_Position = modelview * pos; + gl_Position = modelview * IN_pos; // Offset the uv so we don't have a seam directly over our head. - vec2 uv = uv0 + vec2( 0.5, 0.5 ); + vec2 uv = IN_uv0 + vec2( 0.5, 0.5 ); - texCoord12.xy = uv * texScale.x; - texCoord12.xy += texOffset0; + OUT_texCoord12.xy = uv * texScale.x; + OUT_texCoord12.xy += texOffset0; - texCoord12.zw = uv * texScale.y; - texCoord12.zw += texOffset1; + OUT_texCoord12.zw = uv * texScale.y; + OUT_texCoord12.zw += texOffset1; - texCoord34.xy = uv * texScale.z; - texCoord34.xy += texOffset2; + OUT_texCoord34.xy = uv * texScale.z; + OUT_texCoord34.xy += texOffset2; - texCoord34.z = pos.z; - texCoord34.w = 0.0; + OUT_texCoord34.z = IN_pos.z; + OUT_texCoord34.w = 0.0; // Transform the normal, tangent and binormal vectors from object space to // homogeneous projection space: - vNormalWS = -normal; - vec3 vTangentWS = -tangent; - vec3 vBinormalWS = -binormal; + vec3 vNormalWS = -IN_normal; + vec3 vTangentWS = -IN_tangent; + vec3 vBinormalWS = -IN_binormal; // Compute position in world space: - vec4 vPositionWS = pos + vec4( eyePosWorld, 1 ); //mul( pos, objTrans ); + vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans ); // Compute and output the world view vector (unnormalized): vec3 vViewWS = eyePosWorld - vPositionWS.xyz; @@ -81,12 +93,14 @@ void main() // Compute denormalized light vector in world space: vec3 vLightWS = -sunVec; - // Normalize the light and view vectors and transform it to the tangent space: + // Normalize the light and view vectors and transform it to the IN_tangent space: mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS ); // Propagate the view and the light vectors (in tangent space): - vLightTS = mWorldToTangent * vLightWS; - vViewTS = vViewWS * mWorldToTangent; - - worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 ); + OUT_vLightTS = vLightWS * mWorldToTangent; + OUT_vViewTS = mWorldToTangent * vViewWS; + + OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 ); + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/gl/foliage.glsl b/Templates/Full/game/shaders/common/gl/foliage.glsl index 2fee902e3..38b66e767 100644 --- a/Templates/Full/game/shaders/common/gl/foliage.glsl +++ b/Templates/Full/game/shaders/common/gl/foliage.glsl @@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo; uniform vec2 gc_turbInfo; -//static float sMovableCorner[4] = { 0.0, 0.0, 1.0, 1.0 }; +const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 ); + +const float sCornerUp[4] = float[]( 0, 0, 1, 1 ); + +const float sMovableCorner[4] = float[]( 0, 0, 1, 1 ); + +const vec2 sUVCornerExtent[4] = vec2[] +( + vec2( 0, 1 ), + vec2( 1, 1 ), + vec2( 1, 0 ), + vec2( 0, 0 ) +); /////////////////////////////////////////////////////////////////////////////// @@ -106,34 +118,13 @@ vec2 windEffect( float bbPhase, void foliageProcessVert( inout vec3 position, inout vec4 diffuse, - in vec4 texCoord, - out vec2 outTexCoord, + inout vec4 texCoord, inout vec3 normal, inout vec3 T, in vec3 eyePos ) { - - float sCornerRight[4]; - sCornerRight[0] = -0.5; - sCornerRight[1] = 0.5; - sCornerRight[2] = 0.5; - sCornerRight[3] = -0.5; - - float sCornerUp[4]; - sCornerUp[0] = 0.0; - sCornerUp[1] = 0.0; - sCornerUp[2] = 1.0; - sCornerUp[3] = 1.0; - - vec2 sUVCornerExtent[4]; - sUVCornerExtent[0] = vec2( 0.0, 1.0 ); - sUVCornerExtent[1] = vec2( 1.0, 1.0 ); - sUVCornerExtent[2] = vec2( 1.0, 0.0 ); - sUVCornerExtent[3] = vec2( 0.0, 0.0 ); - - // Assign the normal and tagent values. - //normal = cross( gc_camUp, gc_camRight ); + //normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight ); T = gc_camRight; // Pull out local vars we need for work. @@ -172,8 +163,8 @@ void foliageProcessVert( inout vec3 position, // Grab the uv set and setup the texture coord. vec4 uvSet = gc_typeRects[type]; - outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); - outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); + texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); + texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); // Animate the normal to get lighting changes // across the the wind swept foliage. @@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position, normal.xy += wind.xy * ( 10.0 * texCoord.w ); normal = normalize( normal ); - // Get the alpha fade value. float fadeStart = gc_fadeParams.x; diff --git a/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorP.glsl b/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorP.glsl index 9e5b34caa..fb5abb91e 100644 --- a/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorP.glsl +++ b/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorP.glsl @@ -26,15 +26,15 @@ uniform sampler2D diffuseMap, alphaMap; uniform vec4 groundAlpha; -varying vec4 color, groundAlphaCoeff; -varying vec2 outTexCoord, alphaLookup; +in vec4 color, groundAlphaCoeff; +in vec2 outTexCoord, alphaLookup; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - vec4 alpha = texture2D(alphaMap, alphaLookup); - gl_FragColor = color * texture2D(diffuseMap, outTexCoord); - gl_FragColor.a = gl_FragColor.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; + vec4 alpha = texture(alphaMap, alphaLookup); + OUT_FragColor0 = color * texture(diffuseMap, outTexCoord); + OUT_FragColor0.a = OUT_FragColor0.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; } diff --git a/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorV.glsl b/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorV.glsl index 94a7af2b0..c8dcf1ddb 100644 --- a/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorV.glsl +++ b/Templates/Full/game/shaders/common/gl/fxFoliageReplicatorV.glsl @@ -23,13 +23,20 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec3 vNormal; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; +in vec2 vTexCoord2; + uniform mat4 projection, world; uniform vec3 CameraPos; uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; -varying vec4 color, groundAlphaCoeff; -varying vec2 outTexCoord, alphaLookup; +out vec4 color, groundAlphaCoeff; +out vec2 outTexCoord, alphaLookup; //----------------------------------------------------------------------------- // Main @@ -42,9 +49,9 @@ void main() trans[1][1] = 1.0; trans[2][2] = 1.0; trans[3][3] = 1.0; - trans[3][0] = gl_Vertex.x; - trans[3][1] = gl_Vertex.y; - trans[3][2] = gl_Vertex.z; + trans[3][0] = vPosition.x; + trans[3][1] = vPosition.y; + trans[3][2] = vPosition.z; // Billboard transform * world matrix mat4 o = world; @@ -64,28 +71,29 @@ void main() // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier, // the y coordinate determines if this vertex actually sways or not. float xSway, ySway; - float wavePhase = GlobalSwayPhase * gl_MultiTexCoord1.x; + float wavePhase = GlobalSwayPhase * vTexCoord1.x; ySway = sin(wavePhase); xSway = cos(wavePhase); - xSway = xSway * gl_MultiTexCoord1.y * SwayMagnitudeSide; - ySway = ySway * gl_MultiTexCoord1.y * SwayMagnitudeFront; + xSway = xSway * vTexCoord1.y * SwayMagnitudeSide; + ySway = ySway * vTexCoord1.y * SwayMagnitudeFront; vec4 p; - p = o * vec4(gl_Normal.x + xSway, ySway, gl_Normal.z, 1.0); + p = o * vec4(vNormal.x + xSway, ySway, vNormal.z, 1.0); // Project the point gl_Position = projection * p; // Lighting - float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + gl_Normal.y); + float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y); // Alpha - vec3 worldPos = vec3(gl_Vertex.x, gl_Vertex.y, gl_Vertex.z); + vec3 worldPos = vec3(vPosition.x, vPosition.y, vPosition.z); float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange; alpha = clamp(alpha, 0.0, 1.0); //pass it through alphaLookup = vec2(alpha, 0.0); - bool alphaCoeff = bool(gl_Normal.z); + bool alphaCoeff = bool(vNormal.z); groundAlphaCoeff = vec4(float(alphaCoeff)); - outTexCoord = gl_MultiTexCoord0.st; + outTexCoord = vTexCoord0.st; color = vec4(Luminance, Luminance, Luminance, 1.0); + gl_Position.y *= -1; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/gl/guiMaterialV.glsl b/Templates/Full/game/shaders/common/gl/guiMaterialV.glsl index cd44de2f2..de3845ee7 100644 --- a/Templates/Full/game/shaders/common/gl/guiMaterialV.glsl +++ b/Templates/Full/game/shaders/common/gl/guiMaterialV.glsl @@ -20,16 +20,20 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4x4 modelview; -varying vec4 hpos; -varying vec2 uv0; +out vec4 hpos; +out vec2 uv0; void main() { - hpos = vec4( modelview * gl_Vertex ); + hpos = vec4( modelview * vPosition ); gl_Position = hpos; - uv0 = gl_MultiTexCoord0.st; + uv0 = vTexCoord0.st; + gl_Position.y *= -1; } diff --git a/Templates/Full/game/shaders/common/gl/hlslCompat.glsl b/Templates/Full/game/shaders/common/gl/hlslCompat.glsl index be5c63340..0815df51f 100644 --- a/Templates/Full/game/shaders/common/gl/hlslCompat.glsl +++ b/Templates/Full/game/shaders/common/gl/hlslCompat.glsl @@ -27,17 +27,79 @@ #define float3 vec3 #define float2 vec2 -#define texCUBE textureCube -#define tex2D texture2D +#define half float +#define half2 vec2 +#define half3 vec3 +#define half4 vec4 + +#define float4x4 mat4 +#define float3x3 mat3 +#define float2x2 mat2 + +#define texCUBE texture +#define tex2D texture +#define tex1D texture +#define tex2Dproj textureProj +#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w) + +#define samplerCUBE samplerCube + +#define frac fract #define lerp mix -float saturate( float val ) { return clamp( val, 0.0, 1.0 ); } -vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); } -vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); } -vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); } +void tSetMatrixRow(out float3x3 m, int row, float3 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; +} -float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } -vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } +void tSetMatrixRow(out float4x4 m, int row, float4 value) +{ + m[0][row] = value.x; + m[1][row] = value.y; + m[2][row] = value.z; + m[3][row] = value.w; +} + +#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row]) +#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row]) + +float3x3 float4x4to3x3(float4x4 m) +{ + return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz); +} + +float3x3 float4x4to3x3_(float4x4 m) +{ + return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz); +} + +mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3, + float r1c0, float r1c1, float r1c2, float r1c3, + float r2c0, float r2c1, float r2c2, float r2c3, + float r3c0, float r3c1, float r3c2, float r3c3 ) +{ + return mat4( r0c0, r1c0, r2c0, r3c0, + r0c1, r1c1, r2c1, r3c1, + r0c2, r1c2, r2c2, r3c2, + r0c3, r1c3, r2c3, r3c3 ); +} + + +#define saturate( val ) clamp( val, 0.0, 1.0 ) + +#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 )) + +#define tMul(a, b) (a*b) + +#define inversesqrt( n ) inversesqrt( n ) + +#define correctSSP(vec) vec.y *= -1 + +#ifdef TORQUE_PIXEL_SHADER + void clip(float a) { if(a < 0) discard;} + + out vec4 OUT_FragColor0; +#endif diff --git a/Templates/Full/game/shaders/common/gl/lighting.glsl b/Templates/Full/game/shaders/common/gl/lighting.glsl index 3f8867d3b..4483c7526 100644 --- a/Templates/Full/game/shaders/common/gl/lighting.glsl +++ b/Templates/Full/game/shaders/common/gl/lighting.glsl @@ -20,73 +20,181 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- + +#ifndef TORQUE_SHADERGEN + // These are the uniforms used by most lighting shaders. -uniform vec3 inLightPos[4]; +uniform vec4 inLightPos[3]; uniform vec4 inLightInvRadiusSq; uniform vec4 inLightColor[4]; + +#ifndef TORQUE_BL_NOSPOTLIGHT + uniform vec4 inLightSpotDir[3]; + uniform vec4 inLightSpotAngle; + uniform vec4 inLightSpotFalloff; +#endif + uniform vec4 ambient; uniform float specularPower; uniform vec4 specularColor; - -// This is used to limit the maximum processed -// lights in the compute4Lights down for really -// low end GPUs. -// -// NOTE: If you want to support 10.5.x, this needs to be changed to 2. -#define C4L_MAX_LIGHTS 4 +#endif // !TORQUE_SHADERGEN void compute4Lights( vec3 wsView, vec3 wsPosition, - vec3 wsNormal, + vec3 wsNormal, + vec4 shadowMask, + + #ifdef TORQUE_SHADERGEN + + vec4 inLightPos[3], + vec4 inLightInvRadiusSq, + vec4 inLightColor[4], + vec4 inLightSpotDir[3], + vec4 inLightSpotAngle, + vec4 inLightSpotFalloff, + float specularPower, + vec4 specularColor, + + #endif // TORQUE_SHADERGEN + out vec4 outDiffuse, out vec4 outSpecular ) { - #ifdef PHONG_SPECULAR - // (R.V)^c - float reflected = reflect( wsView, wsNormal ); - #endif - - vec4 nDotL = vec4( 0.0 ); - vec4 rDotL = vec4( 0.0 ); - vec4 sqDists = vec4( 0.0 ); + // NOTE: The light positions and spotlight directions + // are stored in SoA order, so inLightPos[0] is the + // x coord for all 4 lights... inLightPos[1] is y... etc. + // + // This is the key to fully utilizing the vector units and + // saving a huge amount of instructions. + // + // For example this change saved more than 10 instructions + // over a simple for loop for each light. + int i; - for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) - { - vec3 lightVector = inLightPos[i] - wsPosition; - vec3 lightDirection = normalize( lightVector ); + vec4 lightVectors[3]; + for ( i = 0; i < 3; i++ ) + lightVectors[i] = wsPosition[i] - inLightPos[i]; - nDotL[i] = max( dot( lightDirection, wsNormal ), 0.0 ); + vec4 squareDists = vec4(0); + for ( i = 0; i < 3; i++ ) + squareDists += lightVectors[i] * lightVectors[i]; - #ifdef PHONG_SPECULAR - rDotL[i] = saturate( dot( lightDirection, reflected ) ); - #else - // (N.H)^c [Blinn-Phong, TGEA style, default] - rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) ); - #endif + // Accumulate the dot product between the light + // vector and the normal. + // + // The normal is negated because it faces away from + // the surface and the light faces towards the + // surface... this keeps us from needing to flip + // the light vector direction which complicates + // the spot light calculations. + // + // We normalize the result a little later. + // + vec4 nDotL = vec4(0); + for ( i = 0; i < 3; i++ ) + nDotL += lightVectors[i] * -wsNormal[i]; - sqDists[i] = dot( lightVector, lightVector ); - } + vec4 rDotL = vec4(0); + #ifndef TORQUE_BL_NOSPECULAR - // Attenuation - vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq ); + // We're using the Phong specular reflection model + // here where traditionally Torque has used Blinn-Phong + // which has proven to be more accurate to real materials. + // + // We do so because its cheaper as do not need to + // calculate the half angle for all 4 lights. + // + // Advanced Lighting still uses Blinn-Phong, but the + // specular reconstruction it does looks fairly similar + // to this. + // + vec3 R = reflect( wsView, -wsNormal ); + + for ( i = 0; i < 3; i++ ) + rDotL += lightVectors[i] * R[i]; + + #endif + + // Normalize the dots. + // + // Notice we're using the half type here to get a + // much faster sqrt via the rsq_pp instruction at + // the loss of some precision. + // + // Unless we have some extremely large point lights + // i don't believe the precision loss will matter. + // + half4 correction = half4(inversesqrt( squareDists )); + nDotL = saturate( nDotL * correction ); + rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); + + // First calculate a simple point light linear + // attenuation factor. + // + // If this is a directional light the inverse + // radius should be greater than the distance + // causing the attenuation to have no affect. + // + vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); + + #ifndef TORQUE_BL_NOSPOTLIGHT + + // The spotlight attenuation factor. This is really + // fast for what it does... 6 instructions for 4 spots. + + vec4 spotAtten = vec4(0); + for ( i = 0; i < 3; i++ ) + spotAtten += lightVectors[i] * inLightSpotDir[i]; + + vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; + atten *= saturate( cosAngle * inLightSpotFalloff ); + + #endif + + // Finally apply the shadow masking on the attenuation. + atten *= shadowMask; + + // Get the final light intensity. + vec4 intensity = nDotL * atten; // Combine the light colors for output. - vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) ); - outDiffuse = vec4( 0.0 ); - for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) - outDiffuse += vec4( diffuse[i] ) * inLightColor[i]; + outDiffuse = vec4(0); + for ( i = 0; i < 4; i++ ) + outDiffuse += intensity[i] * inLightColor[i]; // Output the specular power. - rDotL = max( rDotL, vec4( 0.00001 ) ); - outSpecular = pow( rDotL, vec4( specularPower ) ); + vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten; + + // Apply the per-light specular attenuation. + vec4 specular = vec4(0,0,0,1); + for ( i = 0; i < 4; i++ ) + specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); + + // Add the final specular intensity values together + // using a single dot product operation then get the + // final specular lighting color. + outSpecular = specularColor * specular; } -/// The standard specular calculation. +// This value is used in AL as a constant power to raise specular values +// to, before storing them into the light info buffer. The per-material +// specular value is then computer by using the integer identity of +// exponentiation: +// +// (a^m)^n = a^(m*n) +// +// or +// +// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) +// +#define AL_ConstantSpecularPower 12.0f + +/// The specular calculation used in Advanced Lighting. /// /// @param toLight Normalized vector representing direction from the pixel /// being lit, to the light source, in world space. @@ -96,11 +204,7 @@ void compute4Lights( vec3 wsView, /// @param toEye The normalized vector representing direction from the pixel /// being lit to the camera. /// -/// @param specPwr The specular exponent. -/// -/// @param specScale A scalar on the specular output used in RGB accumulation. -/// -float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr ) +float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye ) { #ifdef PHONG_SPECULAR // (R.V)^c @@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr ) #endif // Return the specular factor. - return pow( max( specVal, 0.00001f ), specPwr ); + return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); } diff --git a/Templates/Full/game/shaders/common/gl/particleCompositeP.glsl b/Templates/Full/game/shaders/common/gl/particleCompositeP.glsl index 4f2d9b359..6971e1013 100644 --- a/Templates/Full/game/shaders/common/gl/particleCompositeP.glsl +++ b/Templates/Full/game/shaders/common/gl/particleCompositeP.glsl @@ -21,6 +21,13 @@ //----------------------------------------------------------------------------- #include "torque.glsl" +#include "hlslCompat.glsl" + +in vec4 offscreenPos; +in vec4 backbufferPos; + +#define IN_offscreenPos offscreenPos +#define IN_backbufferPos backbufferPos uniform sampler2D colorSource; uniform vec4 offscreenTargetParams; @@ -31,8 +38,6 @@ uniform sampler2D edgeSource; uniform vec4 edgeTargetParams; #endif -varying vec4 backbufferPos; -varying vec4 offscreenPos; void main() { @@ -47,11 +52,10 @@ void main() #ifdef REJECT_EDGES // Cut out particles along the edges, this will create the stencil mask uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); - float edge = texture2D( edgeSource, uvScene.zw ).r; - if (-edge < 0.0) - discard; + float edge = texture( edgeSource, uvScene.zw ).r; + clip( -edge ); #endif // Sample offscreen target and return - gl_FragColor = texture2D( colorSource, uvScene.xy ); -} + OUT_FragColor0 = texture( colorSource, uvScene.xy ); +} \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/gl/particleCompositeV.glsl b/Templates/Full/game/shaders/common/gl/particleCompositeV.glsl index 88a9431d1..8c8f840d1 100644 --- a/Templates/Full/game/shaders/common/gl/particleCompositeV.glsl +++ b/Templates/Full/game/shaders/common/gl/particleCompositeV.glsl @@ -20,16 +20,29 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -uniform mat4 modelViewProj; -uniform mat4 targetModelViewProj; +#include "hlslCompat.glsl" -varying vec4 offscreenPos; -varying vec4 backbufferPos; +in vec2 vTexCoord0; +#define uvCoord vTexCoord0 + +out vec4 offscreenPos; +out vec4 backbufferPos; + +#define OUT_hpos gl_Position +#define OUT_offscreenPos offscreenPos +#define OUT_backbufferPos backbufferPos + +uniform vec4 screenRect; // point, extent void main() { - gl_Position = modelViewProj * gl_Vertex; - backbufferPos = gl_Position; - offscreenPos = targetModelViewProj * gl_Vertex; + OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0); + OUT_hpos.xy *= screenRect.zw; + OUT_hpos.xy += screenRect.xy; + + OUT_backbufferPos = OUT_hpos; + OUT_offscreenPos = OUT_hpos; + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/gl/particlesP.glsl b/Templates/Full/game/shaders/common/gl/particlesP.glsl index 66a3fee28..efd930302 100644 --- a/Templates/Full/game/shaders/common/gl/particlesP.glsl +++ b/Templates/Full/game/shaders/common/gl/particlesP.glsl @@ -20,63 +20,92 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -#include "hlslCompat.glsl" #include "torque.glsl" - +#include "hlslCompat.glsl" + // With advanced lighting we get soft particles. #ifdef TORQUE_LINEAR_DEPTH #define SOFTPARTICLES #endif -#define CLIP_Z // TODO: Make this a proper macro - -uniform sampler2D diffuseMap; - #ifdef SOFTPARTICLES #include "shadergen:/autogenConditioners.h" uniform float oneOverSoftness; uniform float oneOverFar; - uniform sampler2D prepassTex; + uniform sampler2D prepassTex; //uniform vec3 vEye; uniform vec4 prePassTargetParams; #endif +#define CLIP_Z // TODO: Make this a proper macro + +in vec4 color; +in vec2 uv0; +in vec4 pos; + +#define IN_color color +#define IN_uv0 uv0 +#define IN_pos pos + +uniform sampler2D diffuseMap; + +uniform sampler2D paraboloidLightMap; + +vec4 lmSample( vec3 nrm ) +{ + bool calcBack = (nrm.z < 0.0); + if ( calcBack ) + nrm.z = nrm.z * -1.0; + + vec2 lmCoord; + lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5; + lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5); + + + // If this is the back, offset in the atlas + if ( calcBack ) + lmCoord.x += 1.0; + + // Atlasing front and back maps, so scale + lmCoord.x *= 0.5; + + return texture(paraboloidLightMap, lmCoord); +} + + uniform float alphaFactor; uniform float alphaScale; -varying vec4 color; -varying vec2 uv0; -varying vec4 pos; - - void main() { - float softBlend = 1.0; + float softBlend = 1; #ifdef SOFTPARTICLES - float2 tc = pos.xy * vec2(1.0, -1.0 ) / pos.w; + vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w; tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams); float sceneDepth = prepassUncondition( prepassTex, tc ).w; - float depth = pos.w * oneOverFar; - float diff = sceneDepth - depth; + float depth = IN_pos.w * oneOverFar; + float diff = sceneDepth - depth; #ifdef CLIP_Z // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer // When drawing high-res, though, we want to be able to take advantage of hi-z // so this is #ifdef'd out - if (diff < 0.0) - discard; + //clip(diff); #endif softBlend = saturate( diff * oneOverSoftness ); #endif - - vec4 diffuse = texture2D( diffuseMap, uv0 ); + + vec4 diffuse = texture( diffuseMap, IN_uv0 ); + + //OUT_FragColor0 = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale); // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha) - vec3 colorScale = ( alphaFactor < 0.0 ? color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? vec3(color.a * alphaFactor * diffuse.a * softBlend) : vec3(softBlend) ) ); + vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) ); - gl_FragColor = hdrEncode( vec4(color.rgb * diffuse.rgb * colorScale, softBlend * color.a * diffuse.a * alphaScale) ); + OUT_FragColor0 = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale, + IN_color.a * diffuse.a * softBlend * alphaScale ) ); } diff --git a/Templates/Full/game/shaders/common/gl/particlesV.glsl b/Templates/Full/game/shaders/common/gl/particlesV.glsl index da896431f..3d75a6fb6 100644 --- a/Templates/Full/game/shaders/common/gl/particlesV.glsl +++ b/Templates/Full/game/shaders/common/gl/particlesV.glsl @@ -20,18 +20,35 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 color; -varying vec2 uv0; -varying vec4 pos; +#include "hlslCompat.glsl" + +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; + +#define In_pos vPosition +#define In_color vColor +#define In_uv0 vTexCoord0 + +out vec4 color; +out vec2 uv0; +out vec4 pos; + +#define OUT_hpos gl_Position +#define OUT_color color +#define OUT_uv0 uv0 +#define OUT_pos pos uniform mat4 modelViewProj; uniform mat4 fsModelViewProj; void main() { - gl_Position = modelViewProj * gl_Vertex; - pos = fsModelViewProj * gl_Vertex; - color = gl_Color; - uv0 = gl_MultiTexCoord0.st; + OUT_hpos = tMul( modelViewProj, In_pos ); + OUT_pos = tMul( fsModelViewProj, In_pos ); + OUT_color = In_color; + OUT_uv0 = In_uv0; + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/gl/planarReflectBumpP.glsl b/Templates/Full/game/shaders/common/gl/planarReflectBumpP.glsl index 00413aa3b..334c70a70 100644 --- a/Templates/Full/game/shaders/common/gl/planarReflectBumpP.glsl +++ b/Templates/Full/game/shaders/common/gl/planarReflectBumpP.glsl @@ -26,8 +26,8 @@ uniform sampler2D diffuseMap, refractMap, bumpMap; uniform vec4 shadeColor; -varying vec2 TEX0; -varying vec4 TEX1; +in vec2 TEX0; +in vec4 TEX1; //----------------------------------------------------------------------------- // Fade edges of axis for texcoord passed in @@ -49,7 +49,7 @@ float fadeAxis( float val ) //----------------------------------------------------------------------------- void main() { - vec3 bumpNorm = texture2D( bumpMap, TEX0 ).rgb * 2.0 - 1.0; + vec3 bumpNorm = texture( bumpMap, TEX0 ).rgb * 2.0 - 1.0; vec2 offset = vec2( bumpNorm.x, bumpNorm.y ); vec4 texIndex = TEX1; @@ -61,8 +61,8 @@ void main() const float distortion = 0.2; texIndex.xy += offset * distortion * fadeVal; - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - vec4 reflectColor = texture2DProj( refractMap, texIndex ); + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, texIndex ); - gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; + OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a; } diff --git a/Templates/Full/game/shaders/common/gl/planarReflectBumpV.glsl b/Templates/Full/game/shaders/common/gl/planarReflectBumpV.glsl index 820bdf698..90bcd27d8 100644 --- a/Templates/Full/game/shaders/common/gl/planarReflectBumpV.glsl +++ b/Templates/Full/game/shaders/common/gl/planarReflectBumpV.glsl @@ -23,10 +23,13 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 TEX0; -varying vec4 TEX1; +out vec2 TEX0; +out vec4 TEX1; //----------------------------------------------------------------------------- // Main @@ -38,11 +41,11 @@ void main() 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0); - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - TEX0 = gl_MultiTexCoord0.st; + TEX0 = vTexCoord0.st; TEX1 = texGenTest * gl_Position; TEX1.y = -TEX1.y; - + gl_Position.y *= -1; } diff --git a/Templates/Full/game/shaders/common/gl/planarReflectP.glsl b/Templates/Full/game/shaders/common/gl/planarReflectP.glsl index b4f4fab39..77914b80e 100644 --- a/Templates/Full/game/shaders/common/gl/planarReflectP.glsl +++ b/Templates/Full/game/shaders/common/gl/planarReflectP.glsl @@ -26,16 +26,16 @@ uniform sampler2D diffuseMap, refractMap; uniform vec4 shadeColor; -varying vec2 TEX0; -varying vec4 TEX1; +in vec2 TEX0; +in vec4 TEX1; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - vec4 reflectColor = texture2DProj( refractMap, TEX1 ); + vec4 diffuseColor = texture( diffuseMap, TEX0 ); + vec4 reflectColor = textureProj( refractMap, TEX1 ); - gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; + OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a; } diff --git a/Templates/Full/game/shaders/common/gl/planarReflectV.glsl b/Templates/Full/game/shaders/common/gl/planarReflectV.glsl index 820bdf698..ba2484f66 100644 --- a/Templates/Full/game/shaders/common/gl/planarReflectV.glsl +++ b/Templates/Full/game/shaders/common/gl/planarReflectV.glsl @@ -23,10 +23,13 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 TEX0; -varying vec4 TEX1; +out vec2 TEX0; +out vec4 TEX1; //----------------------------------------------------------------------------- // Main @@ -38,9 +41,9 @@ void main() 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0); - gl_Position = modelview * gl_Vertex; + gl_Position = modelview * vPosition; - TEX0 = gl_MultiTexCoord0.st; + TEX0 = vTexCoord0; TEX1 = texGenTest * gl_Position; TEX1.y = -TEX1.y; diff --git a/Templates/Full/game/shaders/common/gl/precipP.glsl b/Templates/Full/game/shaders/common/gl/precipP.glsl index a04f16e4b..3c669517d 100644 --- a/Templates/Full/game/shaders/common/gl/precipP.glsl +++ b/Templates/Full/game/shaders/common/gl/precipP.glsl @@ -25,13 +25,13 @@ //----------------------------------------------------------------------------- uniform sampler2D diffuseMap; -varying vec4 color; -varying vec2 texCoord; +in vec4 color; +in vec2 texCoord; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - gl_FragColor = texture2D(diffuseMap, texCoord) * color; + OUT_FragColor0 = texture(diffuseMap, texCoord) * color; } diff --git a/Templates/Full/game/shaders/common/gl/precipV.glsl b/Templates/Full/game/shaders/common/gl/precipV.glsl index 3535f2f38..29f921630 100644 --- a/Templates/Full/game/shaders/common/gl/precipV.glsl +++ b/Templates/Full/game/shaders/common/gl/precipV.glsl @@ -23,28 +23,32 @@ //----------------------------------------------------------------------------- // Data //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; uniform vec3 cameraPos, ambient; uniform vec2 fadeStartEnd; -varying vec4 color; -varying vec2 texCoord; +out vec4 color; +out vec2 texCoord; //----------------------------------------------------------------------------- // Main //----------------------------------------------------------------------------- void main() { - gl_Position = modelview * gl_Vertex; - texCoord = gl_MultiTexCoord0.st; + gl_Position = modelview * vPosition; + texCoord = vTexCoord0.st; color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); // Do we need to do a distance fade? if ( fadeStartEnd.x < fadeStartEnd.y ) { - float distance = length( cameraPos - gl_Vertex.xyz ); + float distance = length( cameraPos - vPosition.xyz ); color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 ); } + gl_Position.y *= -1; } diff --git a/Templates/Full/game/shaders/common/gl/projectedShadowP.glsl b/Templates/Full/game/shaders/common/gl/projectedShadowP.glsl index 1dc963a4f..8ce0fba13 100644 --- a/Templates/Full/game/shaders/common/gl/projectedShadowP.glsl +++ b/Templates/Full/game/shaders/common/gl/projectedShadowP.glsl @@ -20,9 +20,11 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec2 texCoord; -varying vec4 color; -varying float fade; +in vec2 texCoord; +in vec4 color; +in float fade; + +out vec4 OUT_FragColor0; uniform sampler2D inputTex; uniform vec4 ambient; @@ -30,17 +32,6 @@ uniform vec4 ambient; void main() { - vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f); - float esmFactor = 200.0; - - float lum = dot( ambient.rgb, LUMINANCE_VECTOR ); - - gl_FragColor.rgb = ambient.rgb * lum; - gl_FragColor.a = 0.0; - float depth = texture2D(inputTex, texCoord).a; - - depth = depth * exp(depth - 10.0); - depth = exp(esmFactor * depth) - 1.0; - - gl_FragColor.a = clamp(depth * 300.0, 0.0, 1.0) * (1.0 - lum) * fade * color.a; + float shadow = texture( inputTex, texCoord ).a * color.a; + OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow ); } diff --git a/Templates/Full/game/shaders/common/gl/projectedShadowV.glsl b/Templates/Full/game/shaders/common/gl/projectedShadowV.glsl index c8abde742..b5de84181 100644 --- a/Templates/Full/game/shaders/common/gl/projectedShadowV.glsl +++ b/Templates/Full/game/shaders/common/gl/projectedShadowV.glsl @@ -20,13 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -//***************************************************************************** -// Precipitation vertex shader -//***************************************************************************** +#include "hlslCompat.glsl" -varying vec2 texCoord; -varying vec4 color; -varying float fade; +in vec4 vPosition; +in vec4 vColor; +in vec2 vTexCoord0; +in vec2 vTexCoord1; + +out vec2 texCoord; +out vec4 color; +out float fade; uniform mat4 modelview; uniform float shadowLength; @@ -34,11 +37,13 @@ uniform vec3 shadowCasterPosition; void main() { - gl_Position = modelview * vec4(gl_Vertex.xyz, 1.0); + gl_Position = modelview * vec4(vPosition.xyz, 1.0); - color = gl_Color; - texCoord = gl_MultiTexCoord1.st; + color = vColor; + texCoord = vTexCoord1.st; - float fromCasterDist = length(gl_Vertex.xyz - shadowCasterPosition) - shadowLength; - fade = 1.0 - clamp(fromCasterDist/shadowLength, 0.0, 1.0); + float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength; + fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 ); + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/gl/scatterSkyP.glsl b/Templates/Full/game/shaders/common/gl/scatterSkyP.glsl index 6a6b9b97c..691567a37 100644 --- a/Templates/Full/game/shaders/common/gl/scatterSkyP.glsl +++ b/Templates/Full/game/shaders/common/gl/scatterSkyP.glsl @@ -21,36 +21,32 @@ //----------------------------------------------------------------------------- #include "torque.glsl" +#include "hlslCompat.glsl" -// Calculates the Mie phase function -float getMiePhase(float fCos, float fCos2, float g, float g2) -{ - return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); -} -// Calculates the Rayleigh phase function -float getRayleighPhase(float fCos2) -{ - //return 1.0; - return 0.75 + 0.75*fCos2; -} +// Conn +in vec4 rayleighColor; +#define IN_rayleighColor rayleighColor +in vec4 mieColor; +#define IN_mieColor mieColor +in vec3 v3Direction; +#define IN_v3Direction v3Direction +in float zPosition; +#define IN_zPosition zPosition +in vec3 pos; +#define IN_pos pos -varying vec4 rayleighColor; -varying vec4 mieColor; -varying vec3 v3Direction; -varying float zPosition; -varying vec3 pos; - -uniform samplerCube nightSky; +uniform samplerCube nightSky ; uniform vec4 nightColor; uniform vec2 nightInterpAndExposure; uniform float useCubemap; uniform vec3 lightDir; uniform vec3 sunDir; -void main() +void main() { - float fCos = dot( lightDir, v3Direction ) / length(v3Direction); + + float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction); float fCos2 = fCos*fCos; float g = -0.991; @@ -58,15 +54,15 @@ void main() float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5); - vec4 color = rayleighColor + fMiePhase * mieColor; + vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor; color.a = color.b; - vec4 nightSkyColor = textureCube(nightSky, -v3Direction); + vec4 nightSkyColor = texture(nightSky, -v3Direction); nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); float fac = dot( normalize( pos ), sunDir ); fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); - gl_FragColor = mix( color, nightSkyColor, nightInterpAndExposure.y ); + OUT_FragColor0 = mix( color, nightSkyColor, nightInterpAndExposure.y ); // Clip based on the camera-relative // z position of the vertex, passed through @@ -74,6 +70,6 @@ void main() if(zPosition < 0.0) discard; - gl_FragColor.a = 1; - gl_FragColor = hdrEncode( gl_FragColor ); + OUT_FragColor0.a = 1; + OUT_FragColor0 = hdrEncode( OUT_FragColor0 ); } diff --git a/Templates/Full/game/shaders/common/gl/scatterSkyV.glsl b/Templates/Full/game/shaders/common/gl/scatterSkyV.glsl index 53abd5a6b..61580d785 100644 --- a/Templates/Full/game/shaders/common/gl/scatterSkyV.glsl +++ b/Templates/Full/game/shaders/common/gl/scatterSkyV.glsl @@ -20,12 +20,7 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -const int nSamples = 4; -const float fSamples = 4.0; - -// The scale depth (the altitude at which the average atmospheric density is found) -const float fScaleDepth = 0.25; -const float fInvScaleDepth = 1.0 / 0.25; +#include "hlslCompat.glsl" // The scale equation calculated by Vernier's Graphical Analysis float vernierScale(float fCos) @@ -40,12 +35,27 @@ float vernierScale(float fCos) return 0.25 * outx; } +in vec4 vPosition; +in vec3 vNormal; +in vec4 vColor; +in vec2 vTexCoord0; + +// This is the shader input vertex structure. +#define IN_position vPosition +#define IN_normal vNormal +#define IN_color vColor + // This is the shader output data. -varying vec4 rayleighColor; -varying vec4 mieColor; -varying vec3 v3Direction; -varying float zPosition; -varying vec3 pos; +out vec4 rayleighColor; +#define OUT_rayleighColor rayleighColor +out vec4 mieColor; +#define OUT_mieColor mieColor +out vec3 v3Direction; +#define OUT_v3Direction v3Direction +out float zPosition; +#define OUT_zPosition zPosition +out vec3 pos; +#define OUT_pos pos uniform mat4 modelView; uniform vec4 misc; @@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs; uniform vec3 camPos; uniform vec3 lightDir; uniform vec4 invWaveLength; - -void main() -{ - vec4 position = gl_Vertex.xyzw; - vec3 normal = gl_Normal.xyz; - vec4 color = gl_MultiTexCoord0.xyzw; +uniform vec4 colorize; +vec3 desaturate(const vec3 color, const float desaturation) +{ + const vec3 gray_conv = vec3 (0.30, 0.59, 0.11); + return mix(color, vec3(dot(gray_conv , color)), desaturation); +} + +void main() +{ // Pull some variables out: float camHeight = misc.x; float camHeightSqr = misc.y; @@ -83,7 +96,7 @@ void main() // Get the ray from the camera to the vertex, // and its length (which is the far point of the ray // passing through the atmosphere). - vec3 v3Pos = position.xyz / 6378000.0;// / outerRadius; + vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius; vec3 newCamPos = vec3( 0, 0, camHeight ); v3Pos.z += innerRadius; vec3 v3Ray = v3Pos.xyz - newCamPos; @@ -97,16 +110,7 @@ void main() float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); float fStartAngle = dot(v3Ray, v3Start) / fHeight; - float x = 1.0 - fStartAngle; - float x5 = x * 5.25; - float x5p6 = (-6.80 + x5); - float xnew = (3.83 + x * x5p6); - float xfinal = (0.459 + x * xnew); - float xfinal2 = -0.00287 + x * xfinal; - float othx = exp( xfinal2 ); - float vscale1 = 0.25 * othx; - - float fStartOffset = fDepth * vscale1;//vernierScale(fStartAngle); + float fStartOffset = fDepth * vernierScale( fStartAngle ); // Initialize the scattering loop variables. float fSampleLength = fFar / 2.0; @@ -123,24 +127,8 @@ void main() float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; - x = 1.0 - fCameraAngle; - x5 = x * 5.25; - x5p6 = (-6.80 + x5); - xnew = (3.83 + x * x5p6); - xfinal = (0.459 + x * xnew); - xfinal2 = -0.00287 + x * xfinal; - othx = exp( xfinal2 ); - float vscale3 = 0.25 * othx; - - - x = 1.0 - fLightAngle; - x5 = x * 5.25; - x5p6 = (-6.80 + x5); - xnew = (3.83 + x * x5p6); - xfinal = (0.459 + x * xnew); - xfinal2 = -0.00287 + x * xfinal; - othx = exp( xfinal2 ); - float vscale2 = 0.25 * othx; + float vscale3 = vernierScale( fCameraAngle ); + float vscale2 = vernierScale( fLightAngle ); float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); @@ -150,16 +138,24 @@ void main() // Finally, scale the Mie and Rayleigh colors // and set up the varying variables for the pixel shader. - gl_Position = modelView * position; - mieColor.rgb = v3FrontColor * mieBrightness; - mieColor.a = 1.0; - rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); - rayleighColor.a = 1.0; - v3Direction = newCamPos - v3Pos.xyz; + gl_Position = modelView * IN_position; + OUT_mieColor.rgb = v3FrontColor * mieBrightness; + OUT_mieColor.a = 1.0; + OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); + OUT_rayleighColor.a = 1.0; + OUT_v3Direction = newCamPos - v3Pos.xyz; + OUT_pos = IN_position.xyz; - // This offset is to get rid of the black line between the atmosky and the waterPlane - // along the horizon. - zPosition = position.z + 4000.0; - pos = position.xyz; +#ifdef USE_COLORIZE + + OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a; + + OUT_rayleighColor.r *= colorize.r; + OUT_rayleighColor.g *= colorize.g; + OUT_rayleighColor.b *= colorize.b; + +#endif + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/gl/torque.glsl b/Templates/Full/game/shaders/common/gl/torque.glsl index dc73a706f..a98ef859f 100644 --- a/Templates/Full/game/shaders/common/gl/torque.glsl +++ b/Templates/Full/game/shaders/common/gl/torque.glsl @@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat ) return mat; } + /// The number of additional substeps we take when refining /// the results of the offset parallax mapping function below. /// @@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat ) /// Performs fast parallax offset mapping using /// multiple refinement steps. -////// @param texMap The texture map whos alpha channel we sample the parallax depth. +/// +/// @param texMap The texture map whos alpha channel we sample the parallax depth. /// @param texCoord The incoming texture coordinate for sampling the parallax depth. /// @param negViewTS The negative view vector in tangent space. /// @param depthScale The parallax factor used to scale the depth result. /// vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) { - float depth = texture2D( texMap, texCoord ).a; + float depth = texture( texMap, texCoord ).a; vec2 offset = negViewTS.xy * ( depth * depthScale ); for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) { - depth = ( depth + texture2D( texMap, texCoord + offset ).a ) * 0.5; + depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5; offset = negViewTS.xy * ( depth * depthScale ); } @@ -151,59 +153,61 @@ vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float dept /// The maximum value for 16bit per component integer HDR encoding. const float HDR_RGB16_MAX = 100.0; -/// The maximum value for 10bit per component integer HDR encoding.const float HDR_RGB10_MAX = 4.0; +/// The maximum value for 10bit per component integer HDR encoding. +const float HDR_RGB10_MAX = 4.0; /// Encodes an HDR color for storage into a target. -vec3 hdrEncode( vec3 sample ){ +vec3 hdrEncode( vec3 _sample ) +{ #if defined( TORQUE_HDR_RGB16 ) - return sample / HDR_RGB16_MAX; + return _sample / HDR_RGB16_MAX; #elif defined( TORQUE_HDR_RGB10 ) - return sample / HDR_RGB10_MAX; + return _sample / HDR_RGB10_MAX; #else // No encoding. - return sample; + return _sample; #endif } /// Encodes an HDR color for storage into a target. -vec4 hdrEncode( vec4 sample ) +vec4 hdrEncode( vec4 _sample ) { - return vec4( hdrEncode( sample.rgb ), sample.a ); + return vec4( hdrEncode( _sample.rgb ), _sample.a ); } /// Decodes an HDR color from a target. -vec3 hdrDecode( vec3 sample ) +vec3 hdrDecode( vec3 _sample ) { #if defined( TORQUE_HDR_RGB16 ) - return sample * HDR_RGB16_MAX; + return _sample * HDR_RGB16_MAX; #elif defined( TORQUE_HDR_RGB10 ) - return sample * HDR_RGB10_MAX; + return _sample * HDR_RGB10_MAX; #else // No encoding. - return sample; + return _sample; #endif } /// Decodes an HDR color from a target. -vec4 hdrDecode( vec4 sample ) +vec4 hdrDecode( vec4 _sample ) { - return vec4( hdrDecode( sample.rgb ), sample.a ); + return vec4( hdrDecode( _sample.rgb ), _sample.a ); } /// Returns the luminance for an HDR pixel. -float hdrLuminance( vec3 sample ) +float hdrLuminance( vec3 _sample ) { // There are quite a few different ways to // calculate luminance from an rgb value. @@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample ) // // Max component luminance. // - //float lum = max( sample.r, max( sample.g, sample.b ) ); + //float lum = max( _sample.r, max( _sample.g, _sample.b ) ); //////////////////////////////////////////////////////////////////////////// // The perceptual relative luminance. @@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample ) // See http://en.wikipedia.org/wiki/Luminance_(relative) // const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); - float lum = dot( sample, RELATIVE_LUMINANCE ); + float lum = dot( _sample, RELATIVE_LUMINANCE ); //////////////////////////////////////////////////////////////////////////// // // The average component luminance. // //const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); - //float lum = dot( sample, AVERAGE_LUMINANCE ); + //float lum = dot( _sample, AVERAGE_LUMINANCE ); return lum; } +#ifdef TORQUE_PIXEL_SHADER +/// Called from the visibility feature to do screen +/// door transparency for fading of objects. +void fizzle(vec2 vpos, float visibility) +{ + // NOTE: The magic values below are what give us + // the nice even pattern during the fizzle. + // + // These values can be changed to get different + // patterns... some better than others. + // + // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 } + // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 } + // + // I'm sure there are many more patterns here to + // discover for different effects. + + mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 ); + if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard; + discard; +} +#endif //TORQUE_PIXEL_SHADER /// Basic assert macro. If the condition fails, then the shader will output color. /// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail. /// @param color The color that should be outputted if the condition fails. /// @note This macro will only work in the void main() method of a pixel shader. -#define assert(condition, color) { if(!any(condition)) { gl_FragColor = color; return; } } +#define assert(condition, color) { if(!any(condition)) { OUT_FragColor0 = color; return; } } #endif // _TORQUE_GLSL_ diff --git a/Templates/Full/game/shaders/common/gl/wavesP.glsl b/Templates/Full/game/shaders/common/gl/wavesP.glsl index 24bd8cbb4..ddb683947 100644 --- a/Templates/Full/game/shaders/common/gl/wavesP.glsl +++ b/Templates/Full/game/shaders/common/gl/wavesP.glsl @@ -28,10 +28,10 @@ uniform float specularPower; uniform vec4 ambient; uniform float accumTime; -varying vec2 TEX0; -varying vec4 outLightVec; -varying vec3 outPos; -varying vec3 outEyePos; +in vec2 TEX0; +in vec4 outLightVec; +in vec3 outPos; +in vec3 outEyePos; void main() { @@ -42,14 +42,14 @@ void main() texOffset.x = TEX0.x + sinOffset1 + sinOffset2; texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; - vec4 bumpNorm = texture2D(bumpMap, texOffset) * 2.0 - 1.0; - vec4 diffuse = texture2D(diffMap, texOffset); + vec4 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0; + vec4 diffuse = texture(diffMap, texOffset); - gl_FragColor = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); + OUT_FragColor0 = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient); vec3 eyeVec = normalize(outEyePos - outPos); vec3 halfAng = normalize(eyeVec + outLightVec.xyz); float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; specular = pow(specular, specularPower); - gl_FragColor += specularColor * specular; + OUT_FragColor0 += specularColor * specular; } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl index 6d3e36e7e..1807ac43f 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/convexGeometryV.glsl @@ -20,16 +20,33 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- -varying vec4 wsEyeDir; -varying vec4 ssPos; +#include "../../../gl/hlslCompat.glsl" + +in vec4 vPosition; + +#define IN_pos vPosition + +out vec4 wsEyeDir; +out vec4 ssPos; +out vec4 vsEyeDir; + +#define OUT_hpos gl_Position +#define OUT_wsEyeDir wsEyeDir +#define OUT_ssPos ssPos +#define OUT_vsEyeDir vsEyeDir uniform mat4 modelview; uniform mat4 objTrans; +uniform mat4 worldViewOnly; uniform vec3 eyePosWorld; void main() { - gl_Position = modelview * gl_Vertex; - wsEyeDir = objTrans * gl_Vertex - vec4( eyePosWorld, 0.0 ); - ssPos = gl_Position; + OUT_hpos = tMul( modelview, IN_pos ); + OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 ); + OUT_vsEyeDir = tMul( worldViewOnly, IN_pos ); + OUT_ssPos = OUT_hpos; + + correctSSP(gl_Position); } + diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl index 4a954ae84..e3ee59c8a 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgDepthVisualizeP.glsl @@ -20,14 +20,15 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D prepassBuffer; uniform sampler1D depthViz; void main() { float depth = prepassUncondition( prepassBuffer, uv0 ).w; - gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1 ); + OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1.0 ); } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl index 580204487..aa17df4d6 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightColorVisualizeP.glsl @@ -20,15 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D lightInfoBuffer; void main() { - vec3 lightcolor; + vec3 lightcolor; float nl_Att, specular; - lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); - gl_FragColor = vec4( lightcolor, 1.0 ); + lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + OUT_FragColor0 = vec4( lightcolor, 1.0 ); } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl index 6f7c52486..e549922ff 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgLightSpecularVisualizeP.glsl @@ -20,15 +20,16 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D lightInfoBuffer; void main() { - vec3 lightcolor; + vec3 lightcolor; float nl_Att, specular; - lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); - gl_FragColor = vec4( specular, specular, specular, 1.0 ); + lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); + OUT_FragColor0 = vec4( specular, specular, specular, 1.0 ); } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl index 96b645524..f61706393 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgNormalVisualizeP.glsl @@ -20,14 +20,14 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" - -varying vec2 uv0; -uniform sampler2D prepassTex; +in vec2 uv0; +uniform sampler2D prepassBuffer; void main() { - vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; - gl_FragColor = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); + vec3 normal = prepassUncondition( prepassBuffer, uv0 ).xyz; + OUT_FragColor0 = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl index 51609fc6b..e997950ab 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/dbgShadowVisualizeP.glsl @@ -19,13 +19,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" -varying vec2 uv0; +in vec2 uv0; uniform sampler2D shadowMap; uniform sampler1D depthViz; void main() { - float depth = clamp( texture2DLod( shadowMap, uv0, 0 ).r, 0.0, 1.0 ); - gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1.0 ); + float depth = saturate( texture( shadowMap, uv0 ).r ); + OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1 ); } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl index 866a39b0b..76054eb09 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuad.glsl @@ -24,7 +24,7 @@ vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) { vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; + outPos.y = 1.0 - outPos.y; outPos = ( outPos * rtParams.zw ) + rtParams.xy; - //outPos.y = 1.0 - outPos.y; return outPos; } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl index ce5c2ad81..a80e856ed 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/farFrustumQuadV.glsl @@ -20,24 +20,32 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" #include "farFrustumQuad.glsl" -uniform vec4 renderTargetParams; - -varying vec4 hpos; -varying vec2 uv0; -varying vec3 wsEyeRay; +in vec4 vPosition; +in vec3 vNormal; +in vec3 vTangent; +in vec2 vTexCoord0; +uniform vec4 rtParams0; +out vec4 hpos; +out vec2 uv0; +out vec3 wsEyeRay; +out vec3 vsEyeRay; void main() -{ - // Expand the SS coordinate (stored in uv0) - hpos = vec4( gl_MultiTexCoord0.st * 2.0 - 1.0, 1.0, 1.0 ); - gl_Position = hpos; - +{ + hpos = vec4( vTexCoord0, 0, 1 ); + // Get a RT-corrected UV from the SS coord - uv0 = getUVFromSSPos( hpos.xyz, renderTargetParams ); + uv0 = getUVFromSSPos( hpos.xyz, rtParams0 ); + gl_Position = hpos; - // Interpolators will generate eye ray from far-frustum corners - wsEyeRay = gl_Vertex.xyz; + // Interpolators will generate eye rays the + // from far-frustum corners. + wsEyeRay = vTangent; + vsEyeRay = vNormal; + + correctSSP(gl_Position); } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl index b135f1aa8..c0610508b 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/pointLightP.glsl @@ -21,34 +21,26 @@ //----------------------------------------------------------------------------- #include "../../../gl/hlslCompat.glsl" -#include "farFrustumQuad.glsl" -#include "lightingUtils.glsl" -#include "../../shadowMap/shadowMapIO_GLSL.h" #include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "lightingUtils.glsl" +#include "../../../gl/lighting.glsl" +#include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" -#if TORQUE_SM >= 30 +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else +#ifdef USE_COOKIE_TEX +/// The texture for cookie rendering. +uniform samplerCube cookieMap ; #endif - -// I am not sure if we should do this in a better way -//#define SHADOW_CUBE -//#define SHADOW_PARABOLOID -#define SHADOW_DUALPARABOLOID -#define SHADOW_DUALPARABOLOID_SINGLE_PASS - - #ifdef SHADOW_CUBE vec3 decodeShadowCoord( vec3 shadowCoord ) @@ -56,39 +48,47 @@ return shadowCoord; } - vec4 shadowSample( samplerCUBE shadowMap, vec3 shadowCoord ) + vec4 shadowSample( samplerCube shadowMap, vec3 shadowCoord ) { - return textureCUBE( shadowMap, shadowCoord ); + return texture( shadowMap, shadowCoord ); } - -#elif defined( SHADOW_DUALPARABOLOID ) + +#else vec3 decodeShadowCoord( vec3 paraVec ) { - // Swizzle z and y + // Flip y and z paraVec = paraVec.xzy; - #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + #ifndef SHADOW_PARABOLOID bool calcBack = (paraVec.z < 0.0); - if(calcBack) + if ( calcBack ) + { paraVec.z = paraVec.z * -1.0; + + #ifdef SHADOW_DUALPARABOLOID + paraVec.x = -paraVec.x; + #endif + } #endif vec3 shadowCoord; - shadowCoord.x = (paraVec.x / (2.0*(1.0 + paraVec.z))) + 0.5; - shadowCoord.y = ((paraVec.y / (2.0*(1.0 + paraVec.z))) + 0.5); + shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5; + shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5); shadowCoord.z = 0; // adjust the co-ordinate slightly if it is near the extent of the paraboloid // this value was found via experementation - shadowCoord.xy *= 0.997; + // NOTE: this is wrong, it only biases in one direction, not towards the uv + // center ( 0.5 0.5 ). + //shadowCoord.xy *= 0.997; - #ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS + #ifndef SHADOW_PARABOLOID // If this is the back, offset in the atlas - if(calcBack) + if ( calcBack ) shadowCoord.x += 1.0; // Atlasing front and back maps, so scale @@ -99,51 +99,35 @@ return shadowCoord; } -#else - - #error Unknown shadow type! - #endif -varying vec4 wsEyeDir; -varying vec4 ssPos; - - uniform sampler2D prePassBuffer; #ifdef SHADOW_CUBE - uniform samplerCube shadowMap; + uniform samplerCube shadowMap; #else - uniform sampler2D shadowMap; -#endif -#ifdef ACCUMULATE_LUV - uniform sampler2D scratchTarget; + uniform sampler2D shadowMap; #endif -uniform vec4 renderTargetParams; +uniform vec4 rtParams0; uniform vec3 lightPosition; uniform vec4 lightColor; -uniform float lightBrightness; -uniform float lightRange; +uniform float lightBrightness; +uniform float lightRange; uniform vec2 lightAttenuation; uniform vec4 lightMapParams; - -uniform vec3 eyePosWorld; -uniform vec4 farPlane; -uniform float negFarPlaneDotEye; -uniform mat3x3 worldToLightProj; - +uniform vec4 vsFarPlane; +uniform mat3 viewToLightProj; uniform vec4 lightParams; uniform float shadowSoftness; -uniform float constantSpecularPower; + - -void main() -{ +void main() +{ // Compute scene UV - vec3 ssPosP = ssPos.xyz / ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + vec3 ssPos = ssPos.xyz / ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); @@ -151,21 +135,17 @@ void main() float depth = prepassSample.a; // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); - - // Get world space pixel position - vec3 worldPos = eyePosWorld + eyeRay * depth; + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; // Build light vec, get length, clip pixel if needed - vec3 lightVec = lightPosition - worldPos; + vec3 lightVec = lightPosition - viewSpacePos; float lenLightV = length( lightVec ); - if ( lightRange - lenLightV < 0.0 ) - discard; - + clip( lightRange - lenLightV ); + // Get the attenuated falloff. float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - if ( atten - 1e-6 < 0.0 ) - discard; + clip( atten - 1e-6 ); // Normalize lightVec lightVec /= lenLightV; @@ -181,61 +161,73 @@ void main() #else - // Convert the light vector into a shadow map - // here once instead of in the filtering loop. - vec4 shadowCoord = vec4(0.0); - #ifdef SHADOW_CUBE - shadowCoord.xy = decodeShadowCoord( -lightVec ); - #else - shadowCoord.xy = decodeShadowCoord( worldToLightProj * -lightVec ).xy; - #endif - // Get a linear depth from the light source. - float distToLight = lenLightV / lightRange; + float distToLight = lenLightV / lightRange; - #ifdef SOFTSHADOW_SM3 + #ifdef SHADOW_CUBE + + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = texture( shadowMap, tMul( viewToLightProj, -lightVec ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + + #else + vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy; + float shadowed = softShadow_filter( shadowMap, - gTapRotationTex, - ssPosP.xy, - shadowCoord.xy, + ssPos.xy, + shadowCoord, shadowSoftness, distToLight, nDotL, lightParams.y ); - - #else // !SOFTSHADOW_SM3 - - // TODO: Implement the SM2 lower quality - // shadow filtering method. #endif #endif // !NO_SHADOW - + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + // NOTE: Do not clip on fully shadowed pixels as it would // cause the hardware occlusion query to disable the shadow. // Specular term - float specular = calcSpecular( lightVec, - normal, - normalize( -eyeRay ), - constantSpecularPower, - shadowed * atten * lightBrightness ); - - // N.L * Attenuation - float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); - - // In LUV color mode we need to blend in the - // output from the previous target. - vec4 previousPix = vec4(0.0); - #ifdef ACCUMULATE_LUV - previousPix = texture2DLod( scratchTarget, uvScene, 0 ); - #endif + float specular = AL_CalcSpecular( lightVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, - Sat_NL_Att, - specular, - previousPix ) * lightMapParams; + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/softShadow.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/softShadow.glsl index 8ef09ed2f..a14213946 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/softShadow.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/softShadow.glsl @@ -19,113 +19,141 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- - - -#define NUM_TAPS 12 - -#define NUM_PRE_TAPS 4 - -/// The non-uniform poisson disk used in the -/// high quality shadow filtering. -vec2 sNonUniformTaps[NUM_TAPS]; -void initNonUniformTaps() + +#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) + +#define NUM_PRE_TAPS 4 +#define NUM_TAPS 12 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_TAPS] = vec2[] +( + // These first 4 taps are located around the edges + // of the disk and are used to predict fully shadowed + // or unshadowed areas. + vec2( 0.992833, 0.979309 ), + vec2( -0.998585, 0.985853 ), + vec2( 0.949299, -0.882562 ), + vec2( -0.941358, -0.893924 ), + + // The rest of the samples. + vec2( 0.545055, -0.589072 ), + vec2( 0.346526, 0.385821 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.248676, -0.679605 ), + vec2( -0.569502, -0.390637 ), + vec2( -0.614096, 0.212577 ), + vec2( -0.259178, 0.876272 ), + vec2( 0.649526, 0.864333 ) +); + +#else + +#define NUM_PRE_TAPS 5 + +/// The non-uniform poisson disk used in the +/// high quality shadow filtering. +vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[] +( + vec2( 0.892833, 0.959309 ), + vec2( -0.941358, -0.873924 ), + vec2( -0.260183, 0.334412 ), + vec2( 0.348676, -0.679605 ), + vec2( -0.569502, -0.390637 ) +); + +#endif + + +/// The texture used to do per-pixel pseudorandom +/// rotations of the filter taps. +uniform sampler2D gTapRotationTex ; + + +float softShadow_sampleTaps( sampler2D shadowMap, + vec2 sinCos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float esmFactor, + int startTap, + int endTap ) { - // These first 4 taps are located around the edges - // of the disk and are used to predict fully shadowed - // or unshadowed areas. - sNonUniformTaps[0] = vec2( 0.992833, 0.979309 ); - sNonUniformTaps[1] = vec2( -0.998585, 0.985853 ); - sNonUniformTaps[2] = vec2( 0.949299, -0.882562 ); - sNonUniformTaps[3] = vec2( -0.941358, -0.893924 ); - - // The rest of the samples. - sNonUniformTaps[4] = vec2( 0.545055, -0.589072 ); - sNonUniformTaps[5] = vec2( 0.346526, 0.385821 ); - sNonUniformTaps[6] = vec2( -0.260183, 0.334412 ); - sNonUniformTaps[7] = vec2( 0.248676, -0.679605 ); - sNonUniformTaps[8] = vec2( -0.569502, -0.390637 ); - sNonUniformTaps[9] = vec2( -0.014096, 0.012577 ); - sNonUniformTaps[10] = vec2( -0.259178, 0.876272 ); - sNonUniformTaps[11] = vec2( 0.649526, 0.664333 ); + float shadow = 0; + + vec2 tap = vec2(0); + for ( int t = startTap; t < endTap; t++ ) + { + tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; + tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; + float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r; + + float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + shadow += esm / float( endTap - startTap ); + } + + return shadow; } - -/// The texture used to do per-pixel pseudorandom -/// rotations of the filter taps. -uniform sampler2D gTapRotationTex; - - -float softShadow_sampleTaps( sampler2D shadowMap, - vec2 sinCos, - vec2 shadowPos, - float filterRadius, - float distToLight, - float esmFactor, - int startTap, - int endTap ) -{ - initNonUniformTaps(); - float shadow = 0.0; - - vec2 tap = vec2(0.0); - for ( int t = startTap; t < endTap; t++ ) - { - tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; - tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; - float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r; - - float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); - shadow += esm / float( endTap - startTap ); - } - - return shadow; -} - - -// HACK! HACK! HACK! -// We take the noise texture directly as the second parameter to ensure that it -// is the "last used" sampler, and thus doesn't collide with the prepass buffer -// or shadow map. If we use gTapRotationTex directly here, then it is the first -// used sampler and will collide with the prepass buffer. -float softShadow_filter( sampler2D shadowMap, - sampler2D noiseTexture, - vec2 vpos, - vec2 shadowPos, - float filterRadius, - float distToLight, - float dotNL, - float esmFactor ) -{ - // Lookup the random rotation for this screen pixel. - vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0; - - // Do the prediction taps first. - float shadow = softShadow_sampleTaps( shadowMap, - sinCos, - shadowPos, - filterRadius, - distToLight, - esmFactor, - 0, - NUM_PRE_TAPS ); - - // Only do the expensive filtering if we're really - // in a partially shadowed area. - if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0.0 ) > 0.06 ) - { - shadow += softShadow_sampleTaps( shadowMap, - sinCos, - shadowPos, - filterRadius, - distToLight, - esmFactor, - NUM_PRE_TAPS, - NUM_TAPS ); - - // This averages the taps above with the results - // of the prediction samples. - shadow *= 0.5; - } - - return shadow; -} \ No newline at end of file + + +float softShadow_filter( sampler2D shadowMap, + vec2 vpos, + vec2 shadowPos, + float filterRadius, + float distToLight, + float dotNL, + float esmFactor ) +{ + #ifndef SOFTSHADOW + + // If softshadow is undefined then we skip any complex + // filtering... just do a single sample ESM. + + float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r; + float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); + + #else + + // Lookup the random rotation for this screen pixel. + vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2; + + // Do the prediction taps first. + float shadow = softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + 0, + NUM_PRE_TAPS ); + + // We live with only the pretap results if we don't + // have high quality shadow filtering enabled. + #ifdef SOFTSHADOW_HIGH_QUALITY + + // Only do the expensive filtering if we're really + // in a partially shadowed area. + if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) + { + shadow += softShadow_sampleTaps( shadowMap, + sinCos, + shadowPos, + filterRadius, + distToLight, + esmFactor, + NUM_PRE_TAPS, + NUM_TAPS ); + + // This averages the taps above with the results + // of the prediction samples. + shadow *= 0.5; + } + + #endif // SOFTSHADOW_HIGH_QUALITY + + #endif // SOFTSHADOW + + return shadow; +} \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl index d29f5edb0..c07be1f34 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/spotLightP.glsl @@ -25,58 +25,49 @@ #include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" #include "shadergen:/autogenConditioners.h" +#include "softShadow.glsl" +#include "../../../gl/lighting.glsl" +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; -#if TORQUE_SM >= 30 +#define IN_wsEyeDir wsEyeDir +#define IN_ssPos ssPos +#define IN_vsEyeDir vsEyeDir - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else +#ifdef USE_COOKIE_TEX +/// The texture for cookie rendering. +uniform sampler2D cookieMap; #endif - -varying vec4 ssPos; -varying vec4 wsEyeDir; - - uniform sampler2D prePassBuffer; uniform sampler2D shadowMap; -#ifdef ACCUMULATE_LUV - uniform sampler2D scratchTarget; -#endif -uniform vec4 renderTargetParams; +uniform vec4 rtParams0; uniform vec3 lightPosition; uniform vec4 lightColor; -uniform float lightBrightness; -uniform float lightRange; +uniform float lightBrightness; +uniform float lightRange; uniform vec2 lightAttenuation; uniform vec3 lightDirection; uniform vec4 lightSpotParams; uniform vec4 lightMapParams; -uniform vec3 eyePosWorld; -uniform vec4 farPlane; -uniform float negFarPlaneDotEye; -uniform mat4x4 worldToLightProj; +uniform vec4 vsFarPlane; +uniform mat4 viewToLightProj; uniform vec4 lightParams; uniform float shadowSoftness; -uniform float constantSpecularPower; - void main() -{ +{ // Compute scene UV - vec3 ssPosP = ssPos.xyz / ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); + vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w; + vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); @@ -84,85 +75,92 @@ void main() float depth = prepassSample.a; // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); - - // Get world space pixel position - vec3 worldPos = eyePosWorld + eyeRay * depth; + vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane ); + vec3 viewSpacePos = eyeRay * depth; // Build light vec, get length, clip pixel if needed - vec3 lightToPxlVec = worldPos - lightPosition; + vec3 lightToPxlVec = viewSpacePos - lightPosition; float lenLightV = length( lightToPxlVec ); lightToPxlVec /= lenLightV; - //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); + //lightDirection = vec3( -lightDirection.xy, lightDirection.z ); //vec3( 0, 0, -1 ); float cosAlpha = dot( lightDirection, lightToPxlVec ); - if ( cosAlpha - lightSpotParams.x < 0.0 ) discard; - if ( lightRange - lenLightV < 0.0 ) discard; + clip( cosAlpha - lightSpotParams.x ); + clip( lightRange - lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV ); atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; - if ( atten - 1e-6 < 0.0 ) discard; + clip( atten - 1e-6 ); + atten = saturate( atten ); float nDotL = dot( normal, -lightToPxlVec ); + // Get the shadow texture coordinate + vec4 pxlPosLightProj = tMul( viewToLightProj, vec4( viewSpacePos, 1 ) ); + vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; + #ifdef NO_SHADOW float shadowed = 1.0; #else - // Find Shadow coordinate - vec4 pxlPosLightProj = vec4( worldToLightProj * vec4( worldPos, 1.0 ) ); - vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); - // Get a linear depth from the light source. float distToLight = pxlPosLightProj.z / lightRange; - #ifdef SOFTSHADOW_SM3 - - float shadowed = softShadow_filter( shadowMap, - gTapRotationTex, - ssPosP.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - #else // !SOFTSHADOW_SM3 - - // Simple exponential shadow map. - float occluder = decodeShadowMap( texture2DLod( shadowMap, shadowCoord, 0.0 ) ); - float esmFactor = lightParams.y; - float shadowed = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); - - #endif + float shadowed = softShadow_filter( shadowMap, + ssPos.xy, + shadowCoord, + shadowSoftness, + distToLight, + nDotL, + lightParams.y ); #endif // !NO_SHADOW - + + #ifdef USE_COOKIE_TEX + + // Lookup the cookie sample. + vec4 cookie = texture( cookieMap, shadowCoord ); + + // Multiply the light with the cookie tex. + lightColor.rgb *= cookie.rgb; + + // Use a maximum channel luminance to attenuate + // the lighting else we get specular in the dark + // regions of the cookie texture. + atten *= max( cookie.r, max( cookie.g, cookie.b ) ); + + #endif + // NOTE: Do not clip on fully shadowed pixels as it would // cause the hardware occlusion query to disable the shadow. // Specular term - float specular = calcSpecular( -lightToPxlVec, - normal, - normalize( -eyeRay ), - constantSpecularPower, - shadowed * atten * lightBrightness ); - - // N.L * Attenuation - float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); - - // In LUV color mode we need to blend in the - // output from the previous target. - vec4 previousPix = vec4(0.0); - #ifdef ACCUMULATE_LUV - previousPix = texture2DLod( scratchTarget, uvScene, 0.0 ); - #endif + float specular = AL_CalcSpecular( -lightToPxlVec, + normal, + normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, - Sat_NL_Att, - specular, - previousPix ) * lightMapParams; + float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = vec4(0.0); + + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = nDotL < 0.0f ? 1.0f : shadowed; + + Sat_NL_Att = 1.0f; + shadowed = mix( 1.0f, shadowed, atten ); + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); } diff --git a/Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl b/Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl index bbd567fd0..0178c35ea 100644 --- a/Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl +++ b/Templates/Full/game/shaders/common/lighting/advanced/gl/vectorLightP.glsl @@ -22,40 +22,32 @@ #include "../../../gl/hlslCompat.glsl" #include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "../../../gl/torque.glsl" +#include "../../../gl/lighting.glsl" #include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" +#include "softShadow.glsl" -varying vec2 uv0; -varying vec3 wsEyeRay; +in vec4 hpos; +in vec2 uv0; +in vec3 wsEyeRay; +in vec3 vsEyeRay; -uniform sampler2D prePassBuffer; -uniform sampler2D ShadowMap; +uniform sampler2D ShadowMap ; -#if TORQUE_SM >= 30 - - // Enables high quality soft shadow - // filtering for SM3.0 and above. - #define SOFTSHADOW_SM3 - - #include "softShadow.glsl" - -#else - - - +#ifdef USE_SSAO_MASK +uniform sampler2D ssaoMask ; +uniform vec4 rtParams2; #endif - + +uniform sampler2D prePassBuffer; uniform vec3 lightDirection; uniform vec4 lightColor; -uniform float lightBrightness; -uniform vec4 lightAmbient; -uniform vec4 lightTrilight; - -uniform vec3 eyePosWorld; - -uniform mat4 worldToLightProj; -uniform vec4 splitDistStart; -uniform vec4 splitDistEnd; +uniform float lightBrightness; +uniform vec4 lightAmbient; +uniform vec3 eyePosWorld; +uniform mat4x4 worldToLightProj; uniform vec4 scaleX; uniform vec4 scaleY; uniform vec4 offsetX; @@ -65,16 +57,12 @@ uniform vec4 atlasYOffset; uniform vec2 atlasScale; uniform vec4 zNearFarInvNearFar; uniform vec4 lightMapParams; - -uniform float constantSpecularPower; uniform vec2 fadeStartLength; uniform vec4 farPlaneScalePSSM; -uniform vec4 splitFade; uniform vec4 overDarkPSSM; uniform float shadowSoftness; - -void main() +void main() { // Sample/unpack the normal/z data vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 ); @@ -83,148 +71,162 @@ void main() // Use eye ray to get ws pos vec4 worldPos = vec4(eyePosWorld + wsEyeRay * depth, 1.0f); - + // Get the light attenuation. float dotNL = dot(-lightDirection, normal); + + #ifdef PSSM_DEBUG_RENDER + vec3 debugColor = vec3(0); + #endif #ifdef NO_SHADOW // Fully unshadowed. float shadowed = 1.0; + #ifdef PSSM_DEBUG_RENDER + debugColor = vec3(1.0); + #endif + #else - + // Compute shadow map coordinate - vec4 pxlPosLightProj = worldToLightProj * worldPos; + vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos); vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; - - float distOffset = 0.0; - float shadowed = 0.0; - float fadeAmt = 0.0; - vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); - - // Calculate things dependant on the shadowmap split - for ( int i = 0; i < 2; i++ ) - { - float zDistSplit = zDist.x + distOffset; - vec4 mask0; - mask0.x = float(zDistSplit >= splitDistStart.x); - mask0.y = float(zDistSplit >= splitDistStart.y); - mask0.z = float(zDistSplit >= splitDistStart.z); - mask0.w = float(zDistSplit >= splitDistStart.w); + + // Distance to light, in shadowmap space + float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; - vec4 mask1; - mask1.x = float(zDistSplit < splitDistEnd.x); - mask1.y = float(zDistSplit < splitDistEnd.y); - mask1.z = float(zDistSplit < splitDistEnd.z); - mask1.w = float(zDistSplit < splitDistEnd.w); + // Figure out which split to sample from. Basically, we compute the shadowmap sample coord + // for all of the splits and then check if its valid. + vec4 shadowCoordX = vec4( baseShadowCoord.x ); + vec4 shadowCoordY = vec4( baseShadowCoord.y ); + vec4 farPlaneDists = vec4( distToLight ); + shadowCoordX *= scaleX; + shadowCoordY *= scaleY; + shadowCoordX += offsetX; + shadowCoordY += offsetY; + farPlaneDists *= farPlaneScalePSSM; + + // If the shadow sample is within -1..1 and the distance + // to the light for this pixel is less than the far plane + // of the split, use it. + vec4 finalMask; + if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 && + shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 && + farPlaneDists.x < 1.0 ) + finalMask = vec4(1, 0, 0, 0); + + else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 && + shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 && + farPlaneDists.y < 1.0 ) + finalMask = vec4(0, 1, 0, 0); + + else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 && + shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 && + farPlaneDists.z < 1.0 ) + finalMask = vec4(0, 0, 1, 0); - vec4 finalMask = mask0 * mask1; + else + finalMask = vec4(0, 0, 0, 1); - float splitFadeDist = dot( finalMask, splitFade ); - vec2 finalScale; - finalScale.x = dot(finalMask, scaleX); - finalScale.y = dot(finalMask, scaleY); + #ifdef PSSM_DEBUG_RENDER + if ( finalMask.x > 0 ) + debugColor += vec3( 1, 0, 0 ); + else if ( finalMask.y > 0 ) + debugColor += vec3( 0, 1, 0 ); + else if ( finalMask.z > 0 ) + debugColor += vec3( 0, 0, 1 ); + else if ( finalMask.w > 0 ) + debugColor += vec3( 1, 1, 0 ); + #endif - vec2 finalOffset; - finalOffset.x = dot(finalMask, offsetX); - finalOffset.y = dot(finalMask, offsetY); - - vec2 shadowCoord; - shadowCoord = baseShadowCoord * finalScale; - shadowCoord += finalOffset; + // Here we know what split we're sampling from, so recompute the texcoord location + // Yes, we could just use the result from above, but doing it this way actually saves + // shader instructions. + vec2 finalScale; + finalScale.x = dot(finalMask, scaleX); + finalScale.y = dot(finalMask, scaleY); - // Convert to texcoord space - shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); - //shadowCoord.y = 1.0f - shadowCoord.y; + vec2 finalOffset; + finalOffset.x = dot(finalMask, offsetX); + finalOffset.y = dot(finalMask, offsetY); - // Move around inside of atlas - vec2 aOffset; - aOffset.x = dot(finalMask, atlasXOffset); - aOffset.y = dot(finalMask, atlasYOffset); + vec2 shadowCoord; + shadowCoord = baseShadowCoord * finalScale; + shadowCoord += finalOffset; - shadowCoord *= atlasScale; - shadowCoord += aOffset; - - // Distance to light, in shadowmap space - float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; - - // Each split has a different far plane, take this into account. - float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); - distToLight *= farPlaneScale; - - #ifdef SOFTSHADOW_SM3 + // Convert to texcoord space + shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); + shadowCoord.y = 1.0f - shadowCoord.y; - float esmShadow = softShadow_filter( ShadowMap, - gTapRotationTex, - uv0.xy, - shadowCoord, - farPlaneScale * shadowSoftness, - distToLight, - dotNL, - dot( finalMask, overDarkPSSM ) ); - - #else // !SOFTSHADOW_SM3 + // Move around inside of atlas + vec2 aOffset; + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); - float occluder = decodeShadowMap( texture2DLod( ShadowMap, shadowCoord, 0.0 ) ); - float overDark = dot( finalMask, overDarkPSSM ); - float esmShadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); - - #endif - - if ( i == 0 ) - { - float endDist = dot(splitDistEnd, finalMask); - fadeAmt = smoothstep(endDist - splitFadeDist, endDist, zDist).x; - shadowed = esmShadow * ( 1.0 - fadeAmt ); - } - else - shadowed += esmShadow * fadeAmt; - - distOffset += splitFadeDist; - } + shadowCoord *= atlasScale; + shadowCoord += aOffset; + + // Each split has a different far plane, take this into account. + float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); + distToLight *= farPlaneScale; + + float shadowed = softShadow_filter( ShadowMap, + uv0.xy, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + dotNL, + dot( finalMask, overDarkPSSM ) ); // Fade out the shadow at the end of the range. + vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; - shadowed = mix( shadowed, 1.0, clamp( fadeOutAmt, 0.0, 1.0 ) ); + shadowed = mix( shadowed, 1.0, saturate( fadeOutAmt ) ); + + #ifdef PSSM_DEBUG_RENDER + if ( fadeOutAmt > 1.0 ) + debugColor = vec3(1.0); + #endif #endif // !NO_SHADOW - - // Calc lighting coefficents - float specular = calcSpecular( -lightDirection, - normal, - normalize(-wsEyeRay), - constantSpecularPower, - shadowed * lightBrightness ); - - float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed; - - // Trilight, described by Tom Forsyth - // http://home.comcast.net/~tom_forsyth/papers/trilight/trilight.html -#ifdef ACCUMULATE_LUV - // In LUV multiply in the brightness of the light color (normaly done in the attenuate function) - Sat_NL_Att *= lightColor.a; + // Specular term + float specular = AL_CalcSpecular( -lightDirection, + normal, + normalize(-vsEyeRay) ) * lightBrightness * shadowed; - vec4 ambientBlend = lightAmbient; - ambientBlend.b *= clamp(-dotNL, 0.0, 1.0); - - vec3 trilight = lightTrilight.rgb; - trilight.b *= clamp(1.0 - abs(dotNL), 0.0, 1.0); - - ambientBlend.rg = mix(ambientBlend.rg, trilight.rg, clamp(0.5 * trilight.b / lightAmbient.b, 0.0, 1.0)); - ambientBlend.b += trilight.b; + float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; + vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; + vec4 addToResult = lightAmbient; -#else + // TODO: This needs to be removed when lightmapping is disabled + // as its extra work per-pixel on dynamic lit scenes. + // + // Special lightmapping pass. + if ( lightMapParams.a < 0.0 ) + { + // This disables shadows on the backsides of objects. + shadowed = dotNL < 0.0f ? 1.0f : shadowed; - // RGB - // TODO: Trilight seems broken... it does lighting in shadows! - //vec4 ambientBlend = vec4(lightTrilight.rgb * clamp(1.0 - abs(dotNL), 0.0, 1.0) + lightAmbient.rgb * clamp(-dotNL, 0.0, 1.0), 0.0); - vec4 ambientBlend = vec4(lightAmbient.rgb, 0.0); + Sat_NL_Att = 1.0f; + lightColorOut = vec3(shadowed); + specular *= lightBrightness; + addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + } -#endif + // Sample the AO texture. + #ifdef USE_SSAO_MASK + float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams2 ) ).r; + addToResult *= ao; + #endif + + #ifdef PSSM_DEBUG_RENDER + lightColorOut = debugColor; + #endif + + OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult ); - // Output - gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, Sat_NL_Att, specular, ambientBlend) * lightMapParams; } diff --git a/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl b/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl index 238721e5e..4e97fa347 100644 --- a/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl +++ b/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterP.glsl @@ -20,35 +20,27 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" + uniform sampler2D diffuseMap; -varying vec2 uv; +in vec2 uv; uniform vec2 oneOverTargetSize; +const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 ); +const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 ); + void main() { - vec2 sNonUniformTaps[8]; - - sNonUniformTaps[0] = vec2(0.992833, 0.979309); - sNonUniformTaps[1] = vec2(-0.998585, 0.985853); - sNonUniformTaps[2] = vec2(0.949299, -0.882562); - sNonUniformTaps[3] = vec2(-0.941358, -0.893924); - sNonUniformTaps[4] = vec2(0.545055, -0.589072); - sNonUniformTaps[5] = vec2(0.346526, 0.385821); - sNonUniformTaps[6] = vec2(-0.260183, 0.334412); - sNonUniformTaps[7] = vec2(0.248676, -0.679605); + vec4 OUT = texture( diffuseMap, uv ) * weight[0]; - gl_FragColor = vec4(0.0); - - vec2 texScale = vec2(1.0); - - for ( int i=0; i < 4; i++ ) + for ( int i=1; i < 3; i++ ) { - vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i]; - gl_FragColor += texture2D( diffuseMap, uv + offset ); + vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize; + OUT += texture( diffuseMap, uv + _sample ) * weight[i]; + OUT += texture( diffuseMap, uv - _sample ) * weight[i]; } - - gl_FragColor /= vec4(4.0); - gl_FragColor.rgb = vec3(0.0); + + OUT_FragColor0 = OUT; } diff --git a/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl b/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl index cbf3696be..0eeb2e0fd 100644 --- a/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl +++ b/Templates/Full/game/shaders/common/lighting/basic/gl/shadowFilterV.glsl @@ -22,13 +22,16 @@ #include "../../../../../../shaders/common/gl/torque.glsl" -uniform vec2 oneOverTargetSize; +in vec4 vPosition; +in vec2 vTexCoord0; + uniform vec4 rtParams0; -varying vec2 uv; +out vec2 uv; void main() { - gl_Position = gl_Vertex; - uv = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); + gl_Position = vPosition; + uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 ); + gl_Position.y *= -1; //correct ssp } diff --git a/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl b/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl index 2800a3f17..0f568c716 100644 --- a/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl +++ b/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterP.glsl @@ -26,7 +26,7 @@ uniform sampler2D diffuseMap0; uniform float texSize; uniform vec2 blurDimension; -varying vec2 tex0; +in vec2 tex0; void main() { @@ -40,8 +40,8 @@ void main() vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); for(int i = 0; i < int(blurSamples); i++) { - accum += texture2D(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); + accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); } accum /= blurSamples; - gl_FragColor = accum; + OUT_FragColor0 = accum; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl b/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl index 3850f83c7..9fc436f6c 100644 --- a/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl +++ b/Templates/Full/game/shaders/common/lighting/shadowMap/gl/boxFilterV.glsl @@ -20,12 +20,15 @@ // IN THE SOFTWARE. //----------------------------------------------------------------------------- +in vec4 vPosition; +in vec2 vTexCoord0; + uniform mat4 modelview; -varying vec2 tex0; +out vec2 tex0; void main() { - gl_Position = modelview * gl_Vertex; - tex0 = gl_MultiTexCoord0.st; + gl_Position = modelview * vPosition; + tex0 = vTexCoord0.st; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/postFx/postFxV.glsl b/Templates/Full/game/shaders/common/postFx/postFxV.glsl index 3aded2e0f..96a5ec819 100644 --- a/Templates/Full/game/shaders/common/postFx/postFxV.glsl +++ b/Templates/Full/game/shaders/common/postFx/postFxV.glsl @@ -22,27 +22,30 @@ #include "./../gl/torque.glsl" +in vec4 vPosition; +in vec2 vTexCoord0; +in vec3 vTexCoord1; uniform vec4 rtParams0; uniform vec4 rtParams1; uniform vec4 rtParams2; uniform vec4 rtParams3; -varying vec2 uv0; -varying vec2 uv1; -varying vec2 uv2; -varying vec2 uv3; -varying vec3 wsEyeRay; +out vec2 uv0; +out vec2 uv1; +out vec2 uv2; +out vec2 uv3; +out vec3 wsEyeRay; void main() { - gl_Position = gl_Vertex; + gl_Position = vPosition; - uv0 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); - uv1 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams1 ); - uv2 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams2 ); - uv3 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams3 ); + uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 ); + uv1 = viewportCoordToRenderTarget( vTexCoord0, rtParams1 ); + uv2 = viewportCoordToRenderTarget( vTexCoord0, rtParams2 ); + uv3 = viewportCoordToRenderTarget( vTexCoord0, rtParams3 ); - wsEyeRay = gl_MultiTexCoord1.xyz; + wsEyeRay = vTexCoord1; } diff --git a/Templates/Full/game/shaders/common/terrain/gl/blendP.glsl b/Templates/Full/game/shaders/common/terrain/gl/blendP.glsl index 3817e1de2..a2e4af787 100644 --- a/Templates/Full/game/shaders/common/terrain/gl/blendP.glsl +++ b/Templates/Full/game/shaders/common/terrain/gl/blendP.glsl @@ -23,8 +23,10 @@ #include "../terrain.glsl" #include "../../gl/hlslCompat.glsl" -varying vec2 layerCoord; -varying vec2 texCoord; +in vec2 layerCoord; +#define IN_layerCoord layerCoord +in vec2 texCoord; +#define IN_texCoord texCoord uniform sampler2D layerTex; uniform sampler2D textureMap; @@ -33,12 +35,12 @@ uniform float layerSize; void main() { - vec4 layerSample = round(texture2D( layerTex, layerCoord ) * 255.0); + vec4 layerSample = round(texture( layerTex, IN_layerCoord ) * 255.0); - float blend = calcBlend( texId, layerCoord, layerSize, layerSample ); + float blend = calcBlend( texId, IN_layerCoord, layerSize, layerSample ); if(blend - 0.0001 < 0.0) discard; - gl_FragColor = vec4( texture2D( textureMap, texCoord ).rgb, blend ); + OUT_FragColor0 = vec4( texture( textureMap, IN_texCoord ).rgb, blend ); } diff --git a/Templates/Full/game/shaders/common/terrain/gl/blendV.glsl b/Templates/Full/game/shaders/common/terrain/gl/blendV.glsl index 44362085b..dc7b7befa 100644 --- a/Templates/Full/game/shaders/common/terrain/gl/blendV.glsl +++ b/Templates/Full/game/shaders/common/terrain/gl/blendV.glsl @@ -23,14 +23,19 @@ /// The vertex shader used in the generation and caching of the /// base terrain texture. -varying vec2 layerCoord; -varying vec2 texCoord; +in vec4 vPosition; +in vec2 vTexCoord0; + +out vec2 layerCoord; +out vec2 texCoord; uniform vec2 texScale; void main() { - gl_Position = vec4(gl_Vertex.xyz, 1.0); - layerCoord = gl_MultiTexCoord0.st; - texCoord = gl_MultiTexCoord0.st * texScale; + gl_Position = vec4(vPosition.xyz, 1.0); + layerCoord = vTexCoord0.st; + texCoord = vTexCoord0.st * texScale; + + gl_Position.y *= -1; } diff --git a/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl b/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl index 72232622a..44207dea9 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl @@ -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 } diff --git a/Templates/Full/game/shaders/common/water/gl/waterBasicV.glsl b/Templates/Full/game/shaders/common/water/gl/waterBasicV.glsl index bb2a0c954..1634fd2de 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterBasicV.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterBasicV.glsl @@ -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); } diff --git a/Templates/Full/game/shaders/common/water/gl/waterP.glsl b/Templates/Full/game/shaders/common/water/gl/waterP.glsl index bf482d724..3e15fe576 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterP.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterP.glsl @@ -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 ); } diff --git a/Templates/Full/game/shaders/common/water/gl/waterV.glsl b/Templates/Full/game/shaders/common/water/gl/waterV.glsl index d4337476f..490af63a7 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterV.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterV.glsl @@ -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); } +