Changes to GLSL files for OpenGL

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

View file

@ -26,12 +26,12 @@
uniform vec4 kernel; uniform vec4 kernel;
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec2 texc0, texc1, texc2, texc3; in vec2 texc0, texc1, texc2, texc3;
void main() void main()
{ {
gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x; OUT_FragColor0 = texture(diffuseMap, texc0) * kernel.x;
gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y; OUT_FragColor0 += texture(diffuseMap, texc1) * kernel.y;
gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z; OUT_FragColor0 += texture(diffuseMap, texc2) * kernel.z;
gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w; OUT_FragColor0 += texture(diffuseMap, texc3) * kernel.w;
} }

View file

@ -24,20 +24,25 @@
// Glow shader // Glow shader
//***************************************************************************** //*****************************************************************************
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
uniform vec2 offset0, offset1, offset2, offset3; uniform vec2 offset0, offset1, offset2, offset3;
varying vec2 texc0, texc1, texc2, texc3; out vec2 texc0, texc1, texc2, texc3;
void main() 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; tc.y = 1.0 - tc.y;
texc0 = tc + offset0; texc0 = tc + offset0;
texc1 = tc + offset1; texc1 = tc + offset1;
texc2 = tc + offset2; texc2 = tc + offset2;
texc3 = tc + offset3; texc3 = tc + offset3;
gl_Position.y *= -1;
} }

View file

@ -22,12 +22,20 @@
#include "hlslCompat.glsl" #include "hlslCompat.glsl"
varying vec4 texCoord12; //-----------------------------------------------------------------------------
varying vec4 texCoord34; // Structures
varying vec3 vLightTS; // light vector in tangent space, denormalized //-----------------------------------------------------------------------------
varying vec3 vViewTS; // view vector in tangent space, denormalized //ConnectData
varying vec3 vNormalWS; // Normal vector in world space in vec4 texCoord12;
varying float worldDist; #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 // Uniforms
@ -37,6 +45,7 @@ uniform vec3 ambientColor;
uniform vec3 sunColor; uniform vec3 sunColor;
uniform float cloudCoverage; uniform float cloudCoverage;
uniform vec3 cloudBaseColor; uniform vec3 cloudBaseColor;
uniform float cloudExposure;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Globals // Globals
@ -97,26 +106,25 @@ void main()
// Normalize the interpolated vectors: // Normalize the interpolated vectors:
vec3 vViewTS = normalize( vViewTS ); vec3 vViewTS = normalize( vViewTS );
vec3 vLightTS = normalize( vLightTS ); 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 ); noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
//return noise1; //return noise1;
vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy ); vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy );
noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
//return noise2; //return noise2;
vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; 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 ); 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 += noiseNormal;
vNormalTS = normalize( vNormalTS ); vNormalTS = normalize( vNormalTS );
@ -124,16 +132,14 @@ void main()
cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
float coverage = ( cloudCoverage - 0.5 ) * 2.0; 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 ) if ( cloudCoverage > -1.0 )
cResultColor.a /= 1.0 + coverage; 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. OUT_FragColor0 = cResultColor;
// But since this example isn't doing that, we just output the computed result color here:
gl_FragColor = cResultColor;
} }

View file

@ -20,12 +20,24 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 texCoord12; #include "hlslCompat.glsl"
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized in vec4 vPosition;
varying vec3 vViewTS; // view vector in tangent space, denormalized in vec3 vNormal;
varying vec3 vNormalWS; // Normal vector in world space in vec3 vBinormal;
varying float worldDist; 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 // Uniforms
@ -43,37 +55,37 @@ uniform vec3 texScale;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 pos = gl_Vertex; vec4 IN_pos = vPosition;
vec3 normal = gl_Normal; vec3 IN_normal = vNormal;
vec3 binormal = gl_MultiTexCoord0.xyz; vec3 IN_binormal = vBinormal;
vec3 tangent = gl_MultiTexCoord1.xyz; vec3 IN_tangent = vTangent;
vec2 uv0 = gl_MultiTexCoord2.st; 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. // 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; OUT_texCoord12.xy = uv * texScale.x;
texCoord12.xy += texOffset0; OUT_texCoord12.xy += texOffset0;
texCoord12.zw = uv * texScale.y; OUT_texCoord12.zw = uv * texScale.y;
texCoord12.zw += texOffset1; OUT_texCoord12.zw += texOffset1;
texCoord34.xy = uv * texScale.z; OUT_texCoord34.xy = uv * texScale.z;
texCoord34.xy += texOffset2; OUT_texCoord34.xy += texOffset2;
texCoord34.z = pos.z; OUT_texCoord34.z = IN_pos.z;
texCoord34.w = 0.0; OUT_texCoord34.w = 0.0;
// Transform the normal, tangent and binormal vectors from object space to // Transform the normal, tangent and binormal vectors from object space to
// homogeneous projection space: // homogeneous projection space:
vNormalWS = -normal; vec3 vNormalWS = -IN_normal;
vec3 vTangentWS = -tangent; vec3 vTangentWS = -IN_tangent;
vec3 vBinormalWS = -binormal; vec3 vBinormalWS = -IN_binormal;
// Compute position in world space: // 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): // Compute and output the world view vector (unnormalized):
vec3 vViewWS = eyePosWorld - vPositionWS.xyz; vec3 vViewWS = eyePosWorld - vPositionWS.xyz;
@ -81,12 +93,14 @@ void main()
// Compute denormalized light vector in world space: // Compute denormalized light vector in world space:
vec3 vLightWS = -sunVec; 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 ); mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS );
// Propagate the view and the light vectors (in tangent space): // Propagate the view and the light vectors (in tangent space):
vLightTS = mWorldToTangent * vLightWS; OUT_vLightTS = vLightWS * mWorldToTangent;
vViewTS = vViewWS * mWorldToTangent; OUT_vViewTS = mWorldToTangent * vViewWS;
worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 ); OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 );
correctSSP(gl_Position);
} }

View file

@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo;
uniform vec2 gc_turbInfo; 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, void foliageProcessVert( inout vec3 position,
inout vec4 diffuse, inout vec4 diffuse,
in vec4 texCoord, inout vec4 texCoord,
out vec2 outTexCoord,
inout vec3 normal, inout vec3 normal,
inout vec3 T, inout vec3 T,
in vec3 eyePos ) 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. // 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; T = gc_camRight;
// Pull out local vars we need for work. // 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. // Grab the uv set and setup the texture coord.
vec4 uvSet = gc_typeRects[type]; vec4 uvSet = gc_typeRects[type];
outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
// Animate the normal to get lighting changes // Animate the normal to get lighting changes
// across the the wind swept foliage. // across the the wind swept foliage.
@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position,
normal.xy += wind.xy * ( 10.0 * texCoord.w ); normal.xy += wind.xy * ( 10.0 * texCoord.w );
normal = normalize( normal ); normal = normalize( normal );
// Get the alpha fade value. // Get the alpha fade value.
float fadeStart = gc_fadeParams.x; float fadeStart = gc_fadeParams.x;

View file

@ -26,15 +26,15 @@
uniform sampler2D diffuseMap, alphaMap; uniform sampler2D diffuseMap, alphaMap;
uniform vec4 groundAlpha; uniform vec4 groundAlpha;
varying vec4 color, groundAlphaCoeff; in vec4 color, groundAlphaCoeff;
varying vec2 outTexCoord, alphaLookup; in vec2 outTexCoord, alphaLookup;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 alpha = texture2D(alphaMap, alphaLookup); vec4 alpha = texture(alphaMap, alphaLookup);
gl_FragColor = color * texture2D(diffuseMap, outTexCoord); OUT_FragColor0 = color * texture(diffuseMap, outTexCoord);
gl_FragColor.a = gl_FragColor.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; OUT_FragColor0.a = OUT_FragColor0.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x;
} }

View file

@ -23,13 +23,20 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec3 vNormal;
in vec4 vColor;
in vec2 vTexCoord0;
in vec2 vTexCoord1;
in vec2 vTexCoord2;
uniform mat4 projection, world; uniform mat4 projection, world;
uniform vec3 CameraPos; uniform vec3 CameraPos;
uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront,
GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange;
varying vec4 color, groundAlphaCoeff; out vec4 color, groundAlphaCoeff;
varying vec2 outTexCoord, alphaLookup; out vec2 outTexCoord, alphaLookup;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -42,9 +49,9 @@ void main()
trans[1][1] = 1.0; trans[1][1] = 1.0;
trans[2][2] = 1.0; trans[2][2] = 1.0;
trans[3][3] = 1.0; trans[3][3] = 1.0;
trans[3][0] = gl_Vertex.x; trans[3][0] = vPosition.x;
trans[3][1] = gl_Vertex.y; trans[3][1] = vPosition.y;
trans[3][2] = gl_Vertex.z; trans[3][2] = vPosition.z;
// Billboard transform * world matrix // Billboard transform * world matrix
mat4 o = world; 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, // 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. // the y coordinate determines if this vertex actually sways or not.
float xSway, ySway; float xSway, ySway;
float wavePhase = GlobalSwayPhase * gl_MultiTexCoord1.x; float wavePhase = GlobalSwayPhase * vTexCoord1.x;
ySway = sin(wavePhase); ySway = sin(wavePhase);
xSway = cos(wavePhase); xSway = cos(wavePhase);
xSway = xSway * gl_MultiTexCoord1.y * SwayMagnitudeSide; xSway = xSway * vTexCoord1.y * SwayMagnitudeSide;
ySway = ySway * gl_MultiTexCoord1.y * SwayMagnitudeFront; ySway = ySway * vTexCoord1.y * SwayMagnitudeFront;
vec4 p; 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 // Project the point
gl_Position = projection * p; gl_Position = projection * p;
// Lighting // Lighting
float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + gl_Normal.y); float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y);
// Alpha // 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; float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange;
alpha = clamp(alpha, 0.0, 1.0); //pass it through alpha = clamp(alpha, 0.0, 1.0); //pass it through
alphaLookup = vec2(alpha, 0.0); alphaLookup = vec2(alpha, 0.0);
bool alphaCoeff = bool(gl_Normal.z); bool alphaCoeff = bool(vNormal.z);
groundAlphaCoeff = vec4(float(alphaCoeff)); groundAlphaCoeff = vec4(float(alphaCoeff));
outTexCoord = gl_MultiTexCoord0.st; outTexCoord = vTexCoord0.st;
color = vec4(Luminance, Luminance, Luminance, 1.0); color = vec4(Luminance, Luminance, Luminance, 1.0);
gl_Position.y *= -1;
} }

View file

@ -20,16 +20,20 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4x4 modelview; uniform mat4x4 modelview;
varying vec4 hpos; out vec4 hpos;
varying vec2 uv0; out vec2 uv0;
void main() void main()
{ {
hpos = vec4( modelview * gl_Vertex ); hpos = vec4( modelview * vPosition );
gl_Position = hpos; gl_Position = hpos;
uv0 = gl_MultiTexCoord0.st; uv0 = vTexCoord0.st;
gl_Position.y *= -1;
} }

View file

@ -27,17 +27,79 @@
#define float3 vec3 #define float3 vec3
#define float2 vec2 #define float2 vec2
#define texCUBE textureCube #define half float
#define tex2D texture2D #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 #define lerp mix
float saturate( float val ) { return clamp( val, 0.0, 1.0 ); } void tSetMatrixRow(out float3x3 m, int row, float3 value)
vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); } {
vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); } m[0][row] = value.x;
vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); } m[1][row] = value.y;
m[2][row] = value.z;
}
float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } void tSetMatrixRow(out float4x4 m, int row, float4 value)
vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } {
vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } m[0][row] = value.x;
vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } 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

View file

@ -20,73 +20,181 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef TORQUE_SHADERGEN
// These are the uniforms used by most lighting shaders. // These are the uniforms used by most lighting shaders.
uniform vec3 inLightPos[4]; uniform vec4 inLightPos[3];
uniform vec4 inLightInvRadiusSq; uniform vec4 inLightInvRadiusSq;
uniform vec4 inLightColor[4]; uniform vec4 inLightColor[4];
#ifndef TORQUE_BL_NOSPOTLIGHT
uniform vec4 inLightSpotDir[3];
uniform vec4 inLightSpotAngle;
uniform vec4 inLightSpotFalloff;
#endif
uniform vec4 ambient; uniform vec4 ambient;
uniform float specularPower; uniform float specularPower;
uniform vec4 specularColor; uniform vec4 specularColor;
#endif // !TORQUE_SHADERGEN
// 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
void compute4Lights( vec3 wsView, void compute4Lights( vec3 wsView,
vec3 wsPosition, 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 outDiffuse,
out vec4 outSpecular ) out vec4 outSpecular )
{ {
#ifdef PHONG_SPECULAR // NOTE: The light positions and spotlight directions
// (R.V)^c // are stored in SoA order, so inLightPos[0] is the
float reflected = reflect( wsView, wsNormal ); // x coord for all 4 lights... inLightPos[1] is y... etc.
#endif //
// 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.
vec4 nDotL = vec4( 0.0 );
vec4 rDotL = vec4( 0.0 );
vec4 sqDists = vec4( 0.0 );
int i; int i;
for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) vec4 lightVectors[3];
{ for ( i = 0; i < 3; i++ )
vec3 lightVector = inLightPos[i] - wsPosition; lightVectors[i] = wsPosition[i] - inLightPos[i];
vec3 lightDirection = normalize( lightVector );
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 // Accumulate the dot product between the light
rDotL[i] = saturate( dot( lightDirection, reflected ) ); // vector and the normal.
#else //
// (N.H)^c [Blinn-Phong, TGEA style, default] // The normal is negated because it faces away from
rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) ); // the surface and the light faces towards the
#endif // 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 // We're using the Phong specular reflection model
vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq ); // 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. // Combine the light colors for output.
vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) ); outDiffuse = vec4(0);
outDiffuse = vec4( 0.0 ); for ( i = 0; i < 4; i++ )
for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) outDiffuse += intensity[i] * inLightColor[i];
outDiffuse += vec4( diffuse[i] ) * inLightColor[i];
// Output the specular power. // Output the specular power.
rDotL = max( rDotL, vec4( 0.00001 ) ); vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten;
outSpecular = pow( rDotL, vec4( specularPower ) );
// 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 /// @param toLight Normalized vector representing direction from the pixel
/// being lit, to the light source, in world space. /// 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 /// @param toEye The normalized vector representing direction from the pixel
/// being lit to the camera. /// being lit to the camera.
/// ///
/// @param specPwr The specular exponent. float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye )
///
/// @param specScale A scalar on the specular output used in RGB accumulation.
///
float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
{ {
#ifdef PHONG_SPECULAR #ifdef PHONG_SPECULAR
// (R.V)^c // (R.V)^c
@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
#endif #endif
// Return the specular factor. // Return the specular factor.
return pow( max( specVal, 0.00001f ), specPwr ); return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
} }

View file

@ -21,6 +21,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "torque.glsl" #include "torque.glsl"
#include "hlslCompat.glsl"
in vec4 offscreenPos;
in vec4 backbufferPos;
#define IN_offscreenPos offscreenPos
#define IN_backbufferPos backbufferPos
uniform sampler2D colorSource; uniform sampler2D colorSource;
uniform vec4 offscreenTargetParams; uniform vec4 offscreenTargetParams;
@ -31,8 +38,6 @@ uniform sampler2D edgeSource;
uniform vec4 edgeTargetParams; uniform vec4 edgeTargetParams;
#endif #endif
varying vec4 backbufferPos;
varying vec4 offscreenPos;
void main() void main()
{ {
@ -47,11 +52,10 @@ void main()
#ifdef REJECT_EDGES #ifdef REJECT_EDGES
// Cut out particles along the edges, this will create the stencil mask // Cut out particles along the edges, this will create the stencil mask
uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams);
float edge = texture2D( edgeSource, uvScene.zw ).r; float edge = texture( edgeSource, uvScene.zw ).r;
if (-edge < 0.0) clip( -edge );
discard;
#endif #endif
// Sample offscreen target and return // Sample offscreen target and return
gl_FragColor = texture2D( colorSource, uvScene.xy ); OUT_FragColor0 = texture( colorSource, uvScene.xy );
} }

View file

@ -20,16 +20,29 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform mat4 modelViewProj; #include "hlslCompat.glsl"
uniform mat4 targetModelViewProj;
varying vec4 offscreenPos; in vec2 vTexCoord0;
varying vec4 backbufferPos; #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() void main()
{ {
gl_Position = modelViewProj * gl_Vertex; OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0);
backbufferPos = gl_Position; OUT_hpos.xy *= screenRect.zw;
offscreenPos = targetModelViewProj * gl_Vertex; OUT_hpos.xy += screenRect.xy;
OUT_backbufferPos = OUT_hpos;
OUT_offscreenPos = OUT_hpos;
correctSSP(gl_Position);
} }

View file

@ -20,18 +20,14 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "hlslCompat.glsl"
#include "torque.glsl" #include "torque.glsl"
#include "hlslCompat.glsl"
// With advanced lighting we get soft particles. // With advanced lighting we get soft particles.
#ifdef TORQUE_LINEAR_DEPTH #ifdef TORQUE_LINEAR_DEPTH
#define SOFTPARTICLES #define SOFTPARTICLES
#endif #endif
#define CLIP_Z // TODO: Make this a proper macro
uniform sampler2D diffuseMap;
#ifdef SOFTPARTICLES #ifdef SOFTPARTICLES
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
@ -43,40 +39,73 @@ uniform sampler2D diffuseMap;
uniform vec4 prePassTargetParams; uniform vec4 prePassTargetParams;
#endif #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 alphaFactor;
uniform float alphaScale; uniform float alphaScale;
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
void main() void main()
{ {
float softBlend = 1.0; float softBlend = 1;
#ifdef SOFTPARTICLES #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); tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams);
float sceneDepth = prepassUncondition( prepassTex, tc ).w; float sceneDepth = prepassUncondition( prepassTex, tc ).w;
float depth = pos.w * oneOverFar; float depth = IN_pos.w * oneOverFar;
float diff = sceneDepth - depth; float diff = sceneDepth - depth;
#ifdef CLIP_Z #ifdef CLIP_Z
// If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer // 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 // When drawing high-res, though, we want to be able to take advantage of hi-z
// so this is #ifdef'd out // so this is #ifdef'd out
if (diff < 0.0) //clip(diff);
discard;
#endif #endif
softBlend = saturate( diff * oneOverSoftness ); softBlend = saturate( diff * oneOverSoftness );
#endif #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) // 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 ) );
} }

View file

@ -20,18 +20,35 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 color; #include "hlslCompat.glsl"
varying vec2 uv0;
varying vec4 pos; 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 modelViewProj;
uniform mat4 fsModelViewProj; uniform mat4 fsModelViewProj;
void main() void main()
{ {
gl_Position = modelViewProj * gl_Vertex; OUT_hpos = tMul( modelViewProj, In_pos );
pos = fsModelViewProj * gl_Vertex; OUT_pos = tMul( fsModelViewProj, In_pos );
color = gl_Color; OUT_color = In_color;
uv0 = gl_MultiTexCoord0.st; OUT_uv0 = In_uv0;
correctSSP(gl_Position);
} }

View file

@ -26,8 +26,8 @@
uniform sampler2D diffuseMap, refractMap, bumpMap; uniform sampler2D diffuseMap, refractMap, bumpMap;
uniform vec4 shadeColor; uniform vec4 shadeColor;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 TEX1; in vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Fade edges of axis for texcoord passed in // Fade edges of axis for texcoord passed in
@ -49,7 +49,7 @@ float fadeAxis( float val )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() 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 ); vec2 offset = vec2( bumpNorm.x, bumpNorm.y );
vec4 texIndex = TEX1; vec4 texIndex = TEX1;
@ -61,8 +61,8 @@ void main()
const float distortion = 0.2; const float distortion = 0.2;
texIndex.xy += offset * distortion * fadeVal; texIndex.xy += offset * distortion * fadeVal;
vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); vec4 diffuseColor = texture( diffuseMap, TEX0 );
vec4 reflectColor = texture2DProj( refractMap, texIndex ); vec4 reflectColor = textureProj( refractMap, texIndex );
gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a;
} }

View file

@ -23,10 +23,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 TEX0; out vec2 TEX0;
varying vec4 TEX1; out vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -38,11 +41,11 @@ void main()
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.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 = texGenTest * gl_Position;
TEX1.y = -TEX1.y; TEX1.y = -TEX1.y;
gl_Position.y *= -1;
} }

View file

@ -26,16 +26,16 @@
uniform sampler2D diffuseMap, refractMap; uniform sampler2D diffuseMap, refractMap;
uniform vec4 shadeColor; uniform vec4 shadeColor;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 TEX1; in vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); vec4 diffuseColor = texture( diffuseMap, TEX0 );
vec4 reflectColor = texture2DProj( refractMap, TEX1 ); vec4 reflectColor = textureProj( refractMap, TEX1 );
gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a;
} }

View file

@ -23,10 +23,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 TEX0; out vec2 TEX0;
varying vec4 TEX1; out vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -38,9 +41,9 @@ void main()
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.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 = texGenTest * gl_Position;
TEX1.y = -TEX1.y; TEX1.y = -TEX1.y;

View file

@ -25,13 +25,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec4 color; in vec4 color;
varying vec2 texCoord; in vec2 texCoord;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
gl_FragColor = texture2D(diffuseMap, texCoord) * color; OUT_FragColor0 = texture(diffuseMap, texCoord) * color;
} }

View file

@ -23,28 +23,32 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
uniform vec3 cameraPos, ambient; uniform vec3 cameraPos, ambient;
uniform vec2 fadeStartEnd; uniform vec2 fadeStartEnd;
varying vec4 color; out vec4 color;
varying vec2 texCoord; out vec2 texCoord;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; gl_Position = modelview * vPosition;
texCoord = gl_MultiTexCoord0.st; texCoord = vTexCoord0.st;
color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); color = vec4( ambient.r, ambient.g, ambient.b, 1.0 );
// Do we need to do a distance fade? // Do we need to do a distance fade?
if ( fadeStartEnd.x < fadeStartEnd.y ) 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 ); color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 );
} }
gl_Position.y *= -1;
} }

View file

@ -20,9 +20,11 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec2 texCoord; in vec2 texCoord;
varying vec4 color; in vec4 color;
varying float fade; in float fade;
out vec4 OUT_FragColor0;
uniform sampler2D inputTex; uniform sampler2D inputTex;
uniform vec4 ambient; uniform vec4 ambient;
@ -30,17 +32,6 @@ uniform vec4 ambient;
void main() void main()
{ {
vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f); float shadow = texture( inputTex, texCoord ).a * color.a;
float esmFactor = 200.0; OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow );
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;
} }

View file

@ -20,13 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//***************************************************************************** #include "hlslCompat.glsl"
// Precipitation vertex shader
//*****************************************************************************
varying vec2 texCoord; in vec4 vPosition;
varying vec4 color; in vec4 vColor;
varying float fade; in vec2 vTexCoord0;
in vec2 vTexCoord1;
out vec2 texCoord;
out vec4 color;
out float fade;
uniform mat4 modelview; uniform mat4 modelview;
uniform float shadowLength; uniform float shadowLength;
@ -34,11 +37,13 @@ uniform vec3 shadowCasterPosition;
void main() void main()
{ {
gl_Position = modelview * vec4(gl_Vertex.xyz, 1.0); gl_Position = modelview * vec4(vPosition.xyz, 1.0);
color = gl_Color; color = vColor;
texCoord = gl_MultiTexCoord1.st; texCoord = vTexCoord1.st;
float fromCasterDist = length(gl_Vertex.xyz - shadowCasterPosition) - shadowLength; float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength;
fade = 1.0 - clamp(fromCasterDist/shadowLength, 0.0, 1.0); fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 );
correctSSP(gl_Position);
} }

View file

@ -21,27 +21,22 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "torque.glsl" #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 // Conn
float getRayleighPhase(float fCos2) in vec4 rayleighColor;
{ #define IN_rayleighColor rayleighColor
//return 1.0; in vec4 mieColor;
return 0.75 + 0.75*fCos2; #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; uniform samplerCube nightSky ;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
uniform samplerCube nightSky;
uniform vec4 nightColor; uniform vec4 nightColor;
uniform vec2 nightInterpAndExposure; uniform vec2 nightInterpAndExposure;
uniform float useCubemap; uniform float useCubemap;
@ -50,7 +45,8 @@ 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 fCos2 = fCos*fCos;
float g = -0.991; 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); 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; color.a = color.b;
vec4 nightSkyColor = textureCube(nightSky, -v3Direction); vec4 nightSkyColor = texture(nightSky, -v3Direction);
nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); nightSkyColor = mix(nightColor, nightSkyColor, useCubemap);
float fac = dot( normalize( pos ), sunDir ); float fac = dot( normalize( pos ), sunDir );
fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); 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 // Clip based on the camera-relative
// z position of the vertex, passed through // z position of the vertex, passed through
@ -74,6 +70,6 @@ void main()
if(zPosition < 0.0) if(zPosition < 0.0)
discard; discard;
gl_FragColor.a = 1; OUT_FragColor0.a = 1;
gl_FragColor = hdrEncode( gl_FragColor ); OUT_FragColor0 = hdrEncode( OUT_FragColor0 );
} }

View file

@ -20,12 +20,7 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const int nSamples = 4; #include "hlslCompat.glsl"
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;
// The scale equation calculated by Vernier's Graphical Analysis // The scale equation calculated by Vernier's Graphical Analysis
float vernierScale(float fCos) float vernierScale(float fCos)
@ -40,12 +35,27 @@ float vernierScale(float fCos)
return 0.25 * outx; 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. // This is the shader output data.
varying vec4 rayleighColor; out vec4 rayleighColor;
varying vec4 mieColor; #define OUT_rayleighColor rayleighColor
varying vec3 v3Direction; out vec4 mieColor;
varying float zPosition; #define OUT_mieColor mieColor
varying vec3 pos; 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 mat4 modelView;
uniform vec4 misc; uniform vec4 misc;
@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs;
uniform vec3 camPos; uniform vec3 camPos;
uniform vec3 lightDir; uniform vec3 lightDir;
uniform vec4 invWaveLength; uniform vec4 invWaveLength;
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() void main()
{ {
vec4 position = gl_Vertex.xyzw;
vec3 normal = gl_Normal.xyz;
vec4 color = gl_MultiTexCoord0.xyzw;
// Pull some variables out: // Pull some variables out:
float camHeight = misc.x; float camHeight = misc.x;
float camHeightSqr = misc.y; float camHeightSqr = misc.y;
@ -83,7 +96,7 @@ void main()
// Get the ray from the camera to the vertex, // Get the ray from the camera to the vertex,
// and its length (which is the far point of the ray // and its length (which is the far point of the ray
// passing through the atmosphere). // 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 ); vec3 newCamPos = vec3( 0, 0, camHeight );
v3Pos.z += innerRadius; v3Pos.z += innerRadius;
vec3 v3Ray = v3Pos.xyz - newCamPos; vec3 v3Ray = v3Pos.xyz - newCamPos;
@ -97,16 +110,7 @@ void main()
float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
float fStartAngle = dot(v3Ray, v3Start) / fHeight; float fStartAngle = dot(v3Ray, v3Start) / fHeight;
float x = 1.0 - fStartAngle; float fStartOffset = fDepth * vernierScale( 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);
// Initialize the scattering loop variables. // Initialize the scattering loop variables.
float fSampleLength = fFar / 2.0; float fSampleLength = fFar / 2.0;
@ -123,24 +127,8 @@ void main()
float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
x = 1.0 - fCameraAngle; float vscale3 = vernierScale( fCameraAngle );
x5 = x * 5.25; float vscale2 = vernierScale( fLightAngle );
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 fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
@ -150,16 +138,24 @@ void main()
// Finally, scale the Mie and Rayleigh colors // Finally, scale the Mie and Rayleigh colors
// and set up the varying variables for the pixel shader. // and set up the varying variables for the pixel shader.
gl_Position = modelView * position; gl_Position = modelView * IN_position;
mieColor.rgb = v3FrontColor * mieBrightness; OUT_mieColor.rgb = v3FrontColor * mieBrightness;
mieColor.a = 1.0; OUT_mieColor.a = 1.0;
rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
rayleighColor.a = 1.0; OUT_rayleighColor.a = 1.0;
v3Direction = newCamPos - v3Pos.xyz; 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 #ifdef USE_COLORIZE
// along the horizon.
zPosition = position.z + 4000.0; OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a;
pos = position.xyz;
OUT_rayleighColor.r *= colorize.r;
OUT_rayleighColor.g *= colorize.g;
OUT_rayleighColor.b *= colorize.b;
#endif
correctSSP(gl_Position);
} }

View file

@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat )
return mat; return mat;
} }
/// The number of additional substeps we take when refining /// The number of additional substeps we take when refining
/// the results of the offset parallax mapping function below. /// the results of the offset parallax mapping function below.
/// ///
@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat )
/// Performs fast parallax offset mapping using /// Performs fast parallax offset mapping using
/// multiple refinement steps. /// 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 texCoord The incoming texture coordinate for sampling the parallax depth.
/// @param negViewTS The negative view vector in tangent space. /// @param negViewTS The negative view vector in tangent space.
/// @param depthScale The parallax factor used to scale the depth result. /// @param depthScale The parallax factor used to scale the depth result.
/// ///
vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) 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 ); vec2 offset = negViewTS.xy * ( depth * depthScale );
for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) 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 ); 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. /// The maximum value for 16bit per component integer HDR encoding.
const float HDR_RGB16_MAX = 100.0; 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. /// Encodes an HDR color for storage into a target.
vec3 hdrEncode( vec3 sample ){ vec3 hdrEncode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 ) #if defined( TORQUE_HDR_RGB16 )
return sample / HDR_RGB16_MAX; return _sample / HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 ) #elif defined( TORQUE_HDR_RGB10 )
return sample / HDR_RGB10_MAX; return _sample / HDR_RGB10_MAX;
#else #else
// No encoding. // No encoding.
return sample; return _sample;
#endif #endif
} }
/// Encodes an HDR color for storage into a target. /// 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. /// Decodes an HDR color from a target.
vec3 hdrDecode( vec3 sample ) vec3 hdrDecode( vec3 _sample )
{ {
#if defined( TORQUE_HDR_RGB16 ) #if defined( TORQUE_HDR_RGB16 )
return sample * HDR_RGB16_MAX; return _sample * HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 ) #elif defined( TORQUE_HDR_RGB10 )
return sample * HDR_RGB10_MAX; return _sample * HDR_RGB10_MAX;
#else #else
// No encoding. // No encoding.
return sample; return _sample;
#endif #endif
} }
/// Decodes an HDR color from a target. /// 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. /// Returns the luminance for an HDR pixel.
float hdrLuminance( vec3 sample ) float hdrLuminance( vec3 _sample )
{ {
// There are quite a few different ways to // There are quite a few different ways to
// calculate luminance from an rgb value. // calculate luminance from an rgb value.
@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample )
// //
// Max component luminance. // 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. // The perceptual relative luminance.
@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample )
// See http://en.wikipedia.org/wiki/Luminance_(relative) // See http://en.wikipedia.org/wiki/Luminance_(relative)
// //
const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); 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. // The average component luminance.
// //
//const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); //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; 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. /// 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 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. /// @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. /// @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_ #endif // _TORQUE_GLSL_

View file

@ -28,10 +28,10 @@ uniform float specularPower;
uniform vec4 ambient; uniform vec4 ambient;
uniform float accumTime; uniform float accumTime;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 outLightVec; in vec4 outLightVec;
varying vec3 outPos; in vec3 outPos;
varying vec3 outEyePos; in vec3 outEyePos;
void main() void main()
{ {
@ -42,14 +42,14 @@ void main()
texOffset.x = TEX0.x + sinOffset1 + sinOffset2; texOffset.x = TEX0.x + sinOffset1 + sinOffset2;
texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; 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 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0;
vec4 diffuse = texture2D(diffMap, texOffset); 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 eyeVec = normalize(outEyePos - outPos);
vec3 halfAng = normalize(eyeVec + outLightVec.xyz); vec3 halfAng = normalize(eyeVec + outLightVec.xyz);
float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w;
specular = pow(specular, specularPower); specular = pow(specular, specularPower);
gl_FragColor += specularColor * specular; OUT_FragColor0 += specularColor * specular;
} }

View file

@ -20,16 +20,33 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 wsEyeDir; #include "../../../gl/hlslCompat.glsl"
varying vec4 ssPos;
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 modelview;
uniform mat4 objTrans; uniform mat4 objTrans;
uniform mat4 worldViewOnly;
uniform vec3 eyePosWorld; uniform vec3 eyePosWorld;
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; OUT_hpos = tMul( modelview, IN_pos );
wsEyeDir = objTrans * gl_Vertex - vec4( eyePosWorld, 0.0 ); OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 );
ssPos = gl_Position; OUT_vsEyeDir = tMul( worldViewOnly, IN_pos );
OUT_ssPos = OUT_hpos;
correctSSP(gl_Position);
} }

View file

@ -20,14 +20,15 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D prepassBuffer; uniform sampler2D prepassBuffer;
uniform sampler1D depthViz; uniform sampler1D depthViz;
void main() void main()
{ {
float depth = prepassUncondition( prepassBuffer, uv0 ).w; float depth = prepassUncondition( prepassBuffer, uv0 ).w;
gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1 ); OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1.0 );
} }

View file

@ -20,15 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D lightInfoBuffer; uniform sampler2D lightInfoBuffer;
void main() void main()
{ {
vec3 lightcolor; vec3 lightcolor;
float nl_Att, specular; float nl_Att, specular;
lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular );
gl_FragColor = vec4( lightcolor, 1.0 ); OUT_FragColor0 = vec4( lightcolor, 1.0 );
} }

View file

@ -20,15 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D lightInfoBuffer; uniform sampler2D lightInfoBuffer;
void main() void main()
{ {
vec3 lightcolor; vec3 lightcolor;
float nl_Att, specular; float nl_Att, specular;
lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular );
gl_FragColor = vec4( specular, specular, specular, 1.0 ); OUT_FragColor0 = vec4( specular, specular, specular, 1.0 );
} }

View file

@ -20,14 +20,14 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
in vec2 uv0;
varying vec2 uv0; uniform sampler2D prepassBuffer;
uniform sampler2D prepassTex;
void main() void main()
{ {
vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; vec3 normal = prepassUncondition( prepassBuffer, uv0 ).xyz;
gl_FragColor = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); OUT_FragColor0 = vec4( ( normal + 1.0 ) * 0.5, 1.0 );
} }

View file

@ -19,13 +19,14 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
uniform sampler1D depthViz; uniform sampler1D depthViz;
void main() void main()
{ {
float depth = clamp( texture2DLod( shadowMap, uv0, 0 ).r, 0.0, 1.0 ); float depth = saturate( texture( shadowMap, uv0 ).r );
gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1.0 ); OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1 );
} }

View file

@ -24,7 +24,7 @@
vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams )
{ {
vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0;
outPos.y = 1.0 - outPos.y;
outPos = ( outPos * rtParams.zw ) + rtParams.xy; outPos = ( outPos * rtParams.zw ) + rtParams.xy;
//outPos.y = 1.0 - outPos.y;
return outPos; return outPos;
} }

View file

@ -20,24 +20,32 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "farFrustumQuad.glsl" #include "farFrustumQuad.glsl"
uniform vec4 renderTargetParams; in vec4 vPosition;
in vec3 vNormal;
varying vec4 hpos; in vec3 vTangent;
varying vec2 uv0; in vec2 vTexCoord0;
varying vec3 wsEyeRay;
uniform vec4 rtParams0;
out vec4 hpos;
out vec2 uv0;
out vec3 wsEyeRay;
out vec3 vsEyeRay;
void main() void main()
{ {
// Expand the SS coordinate (stored in uv0) hpos = vec4( vTexCoord0, 0, 1 );
hpos = vec4( gl_MultiTexCoord0.st * 2.0 - 1.0, 1.0, 1.0 );
gl_Position = hpos;
// Get a RT-corrected UV from the SS coord // 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 // Interpolators will generate eye rays the
wsEyeRay = gl_Vertex.xyz; // from far-frustum corners.
wsEyeRay = vTangent;
vsEyeRay = vNormal;
correctSSP(gl_Position);
} }

View file

@ -21,34 +21,26 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl" #include "../../../gl/hlslCompat.glsl"
#include "farFrustumQuad.glsl"
#include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h"
#include "shadergen:/autogenConditioners.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 #ifdef USE_COOKIE_TEX
// filtering for SM3.0 and above.
#define SOFTSHADOW_SM3
#include "softShadow.glsl"
#else
/// The texture for cookie rendering.
uniform samplerCube cookieMap ;
#endif #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 #ifdef SHADOW_CUBE
vec3 decodeShadowCoord( vec3 shadowCoord ) vec3 decodeShadowCoord( vec3 shadowCoord )
@ -56,39 +48,47 @@
return shadowCoord; 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 ) vec3 decodeShadowCoord( vec3 paraVec )
{ {
// Swizzle z and y // Flip y and z
paraVec = paraVec.xzy; paraVec = paraVec.xzy;
#ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS #ifndef SHADOW_PARABOLOID
bool calcBack = (paraVec.z < 0.0); bool calcBack = (paraVec.z < 0.0);
if(calcBack) if ( calcBack )
{
paraVec.z = paraVec.z * -1.0; paraVec.z = paraVec.z * -1.0;
#ifdef SHADOW_DUALPARABOLOID
paraVec.x = -paraVec.x;
#endif
}
#endif #endif
vec3 shadowCoord; vec3 shadowCoord;
shadowCoord.x = (paraVec.x / (2.0*(1.0 + paraVec.z))) + 0.5; shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5;
shadowCoord.y = ((paraVec.y / (2.0*(1.0 + paraVec.z))) + 0.5); shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5);
shadowCoord.z = 0; shadowCoord.z = 0;
// adjust the co-ordinate slightly if it is near the extent of the paraboloid // adjust the co-ordinate slightly if it is near the extent of the paraboloid
// this value was found via experementation // 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 this is the back, offset in the atlas
if(calcBack) if ( calcBack )
shadowCoord.x += 1.0; shadowCoord.x += 1.0;
// Atlasing front and back maps, so scale // Atlasing front and back maps, so scale
@ -99,51 +99,35 @@
return shadowCoord; return shadowCoord;
} }
#else
#error Unknown shadow type!
#endif #endif
varying vec4 wsEyeDir;
varying vec4 ssPos;
uniform sampler2D prePassBuffer; uniform sampler2D prePassBuffer;
#ifdef SHADOW_CUBE #ifdef SHADOW_CUBE
uniform samplerCube shadowMap; uniform samplerCube shadowMap;
#else #else
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
#endif
#ifdef ACCUMULATE_LUV
uniform sampler2D scratchTarget;
#endif #endif
uniform vec4 renderTargetParams; uniform vec4 rtParams0;
uniform vec3 lightPosition; uniform vec3 lightPosition;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform float lightRange; uniform float lightRange;
uniform vec2 lightAttenuation; uniform vec2 lightAttenuation;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform vec3 eyePosWorld; uniform mat3 viewToLightProj;
uniform vec4 farPlane;
uniform float negFarPlaneDotEye;
uniform mat3x3 worldToLightProj;
uniform vec4 lightParams; uniform vec4 lightParams;
uniform float shadowSoftness; uniform float shadowSoftness;
uniform float constantSpecularPower;
void main() void main()
{ {
// Compute scene UV // Compute scene UV
vec3 ssPosP = ssPos.xyz / ssPos.w; vec3 ssPos = ssPos.xyz / ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
@ -151,21 +135,17 @@ void main()
float depth = prepassSample.a; float depth = prepassSample.a;
// Eye ray - Eye -> Pixel // Eye ray - Eye -> Pixel
vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane );
vec3 viewSpacePos = eyeRay * depth;
// Get world space pixel position
vec3 worldPos = eyePosWorld + eyeRay * depth;
// Build light vec, get length, clip pixel if needed // Build light vec, get length, clip pixel if needed
vec3 lightVec = lightPosition - worldPos; vec3 lightVec = lightPosition - viewSpacePos;
float lenLightV = length( lightVec ); float lenLightV = length( lightVec );
if ( lightRange - lenLightV < 0.0 ) clip( lightRange - lenLightV );
discard;
// Get the attenuated falloff. // Get the attenuated falloff.
float atten = attenuate( lightColor, lightAttenuation, lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV );
if ( atten - 1e-6 < 0.0 ) clip( atten - 1e-6 );
discard;
// Normalize lightVec // Normalize lightVec
lightVec /= lenLightV; lightVec /= lenLightV;
@ -181,61 +161,73 @@ void main()
#else #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. // 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, float shadowed = softShadow_filter( shadowMap,
gTapRotationTex, ssPos.xy,
ssPosP.xy, shadowCoord,
shadowCoord.xy,
shadowSoftness, shadowSoftness,
distToLight, distToLight,
nDotL, nDotL,
lightParams.y ); lightParams.y );
#else // !SOFTSHADOW_SM3
// TODO: Implement the SM2 lower quality
// shadow filtering method.
#endif #endif
#endif // !NO_SHADOW #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 // NOTE: Do not clip on fully shadowed pixels as it would
// cause the hardware occlusion query to disable the shadow. // cause the hardware occlusion query to disable the shadow.
// Specular term // Specular term
float specular = calcSpecular( lightVec, float specular = AL_CalcSpecular( lightVec,
normal, normal,
normalize( -eyeRay ), normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
constantSpecularPower,
shadowed * atten * lightBrightness );
// N.L * Attenuation float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = vec4(0.0);
// In LUV color mode we need to blend in the // TODO: This needs to be removed when lightmapping is disabled
// output from the previous target. // as its extra work per-pixel on dynamic lit scenes.
vec4 previousPix = vec4(0.0); //
#ifdef ACCUMULATE_LUV // Special lightmapping pass.
previousPix = texture2DLod( scratchTarget, uvScene, 0 ); if ( lightMapParams.a < 0.0 )
#endif {
// This disables shadows on the backsides of objects.
shadowed = nDotL < 0.0f ? 1.0f : shadowed;
// Output Sat_NL_Att = 1.0f;
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, shadowed = mix( 1.0f, shadowed, atten );
Sat_NL_Att, lightColorOut = vec3(shadowed);
specular, specular *= lightBrightness;
previousPix ) * lightMapParams; addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
} }

View file

@ -21,38 +21,55 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define NUM_TAPS 12 #if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
#define NUM_PRE_TAPS 4 #define NUM_PRE_TAPS 4
#define NUM_TAPS 12
/// The non-uniform poisson disk used in the /// The non-uniform poisson disk used in the
/// high quality shadow filtering. /// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS]; vec2 sNonUniformTaps[NUM_TAPS] = vec2[]
(
void initNonUniformTaps()
{
// These first 4 taps are located around the edges // These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed // of the disk and are used to predict fully shadowed
// or unshadowed areas. // or unshadowed areas.
sNonUniformTaps[0] = vec2( 0.992833, 0.979309 ); vec2( 0.992833, 0.979309 ),
sNonUniformTaps[1] = vec2( -0.998585, 0.985853 ); vec2( -0.998585, 0.985853 ),
sNonUniformTaps[2] = vec2( 0.949299, -0.882562 ); vec2( 0.949299, -0.882562 ),
sNonUniformTaps[3] = vec2( -0.941358, -0.893924 ); vec2( -0.941358, -0.893924 ),
// The rest of the samples. // The rest of the samples.
sNonUniformTaps[4] = vec2( 0.545055, -0.589072 ); vec2( 0.545055, -0.589072 ),
sNonUniformTaps[5] = vec2( 0.346526, 0.385821 ); vec2( 0.346526, 0.385821 ),
sNonUniformTaps[6] = vec2( -0.260183, 0.334412 ); vec2( -0.260183, 0.334412 ),
sNonUniformTaps[7] = vec2( 0.248676, -0.679605 ); vec2( 0.248676, -0.679605 ),
sNonUniformTaps[8] = vec2( -0.569502, -0.390637 ); vec2( -0.569502, -0.390637 ),
sNonUniformTaps[9] = vec2( -0.014096, 0.012577 ); vec2( -0.614096, 0.212577 ),
sNonUniformTaps[10] = vec2( -0.259178, 0.876272 ); vec2( -0.259178, 0.876272 ),
sNonUniformTaps[11] = vec2( 0.649526, 0.664333 ); 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 /// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps. /// rotations of the filter taps.
uniform sampler2D gTapRotationTex; uniform sampler2D gTapRotationTex ;
float softShadow_sampleTaps( sampler2D shadowMap, float softShadow_sampleTaps( sampler2D shadowMap,
@ -64,17 +81,16 @@ float softShadow_sampleTaps( sampler2D shadowMap,
int startTap, int startTap,
int endTap ) int endTap )
{ {
initNonUniformTaps(); float shadow = 0;
float shadow = 0.0;
vec2 tap = vec2(0.0); vec2 tap = vec2(0);
for ( int t = startTap; t < endTap; t++ ) for ( int t = startTap; t < endTap; t++ )
{ {
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; 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; tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r; float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r;
float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
shadow += esm / float( endTap - startTap ); shadow += esm / float( endTap - startTap );
} }
@ -82,13 +98,7 @@ float softShadow_sampleTaps( sampler2D shadowMap,
} }
// 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, float softShadow_filter( sampler2D shadowMap,
sampler2D noiseTexture,
vec2 vpos, vec2 vpos,
vec2 shadowPos, vec2 shadowPos,
float filterRadius, float filterRadius,
@ -96,36 +106,54 @@ float softShadow_filter( sampler2D shadowMap,
float dotNL, float dotNL,
float esmFactor ) float esmFactor )
{ {
// Lookup the random rotation for this screen pixel. #ifndef SOFTSHADOW
vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0;
// Do the prediction taps first. // If softshadow is undefined then we skip any complex
float shadow = softShadow_sampleTaps( shadowMap, // filtering... just do a single sample ESM.
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// Only do the expensive filtering if we're really float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r;
// in a partially shadowed area. float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
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 #else
// of the prediction samples.
shadow *= 0.5; // 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; return shadow;
} }

View file

@ -25,58 +25,49 @@
#include "lightingUtils.glsl" #include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h" #include "../../shadowMap/shadowMapIO_GLSL.h"
#include "shadergen:/autogenConditioners.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 #ifdef USE_COOKIE_TEX
// filtering for SM3.0 and above.
#define SOFTSHADOW_SM3
#include "softShadow.glsl"
#else
/// The texture for cookie rendering.
uniform sampler2D cookieMap;
#endif #endif
varying vec4 ssPos;
varying vec4 wsEyeDir;
uniform sampler2D prePassBuffer; uniform sampler2D prePassBuffer;
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
#ifdef ACCUMULATE_LUV
uniform sampler2D scratchTarget;
#endif
uniform vec4 renderTargetParams; uniform vec4 rtParams0;
uniform vec3 lightPosition; uniform vec3 lightPosition;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform float lightRange; uniform float lightRange;
uniform vec2 lightAttenuation; uniform vec2 lightAttenuation;
uniform vec3 lightDirection; uniform vec3 lightDirection;
uniform vec4 lightSpotParams; uniform vec4 lightSpotParams;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform vec3 eyePosWorld; uniform vec4 vsFarPlane;
uniform vec4 farPlane; uniform mat4 viewToLightProj;
uniform float negFarPlaneDotEye;
uniform mat4x4 worldToLightProj;
uniform vec4 lightParams; uniform vec4 lightParams;
uniform float shadowSoftness; uniform float shadowSoftness;
uniform float constantSpecularPower;
void main() void main()
{ {
// Compute scene UV // Compute scene UV
vec3 ssPosP = ssPos.xyz / ssPos.w; vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
@ -84,85 +75,92 @@ void main()
float depth = prepassSample.a; float depth = prepassSample.a;
// Eye ray - Eye -> Pixel // Eye ray - Eye -> Pixel
vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane );
vec3 viewSpacePos = eyeRay * depth;
// Get world space pixel position
vec3 worldPos = eyePosWorld + eyeRay * depth;
// Build light vec, get length, clip pixel if needed // Build light vec, get length, clip pixel if needed
vec3 lightToPxlVec = worldPos - lightPosition; vec3 lightToPxlVec = viewSpacePos - lightPosition;
float lenLightV = length( lightToPxlVec ); float lenLightV = length( lightToPxlVec );
lightToPxlVec /= lenLightV; 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 ); float cosAlpha = dot( lightDirection, lightToPxlVec );
if ( cosAlpha - lightSpotParams.x < 0.0 ) discard; clip( cosAlpha - lightSpotParams.x );
if ( lightRange - lenLightV < 0.0 ) discard; clip( lightRange - lenLightV );
float atten = attenuate( lightColor, lightAttenuation, lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV );
atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; 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 ); 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 #ifdef NO_SHADOW
float shadowed = 1.0; float shadowed = 1.0;
#else #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. // Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange; float distToLight = pxlPosLightProj.z / lightRange;
#ifdef SOFTSHADOW_SM3 float shadowed = softShadow_filter( shadowMap,
ssPos.xy,
float shadowed = softShadow_filter( shadowMap, shadowCoord,
gTapRotationTex, shadowSoftness,
ssPosP.xy, distToLight,
shadowCoord, nDotL,
shadowSoftness, lightParams.y );
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
#endif // !NO_SHADOW #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 // NOTE: Do not clip on fully shadowed pixels as it would
// cause the hardware occlusion query to disable the shadow. // cause the hardware occlusion query to disable the shadow.
// Specular term // Specular term
float specular = calcSpecular( -lightToPxlVec, float specular = AL_CalcSpecular( -lightToPxlVec,
normal, normal,
normalize( -eyeRay ), normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
constantSpecularPower,
shadowed * atten * lightBrightness );
// N.L * Attenuation float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = vec4(0.0);
// In LUV color mode we need to blend in the // TODO: This needs to be removed when lightmapping is disabled
// output from the previous target. // as its extra work per-pixel on dynamic lit scenes.
vec4 previousPix = vec4(0.0); //
#ifdef ACCUMULATE_LUV // Special lightmapping pass.
previousPix = texture2DLod( scratchTarget, uvScene, 0.0 ); if ( lightMapParams.a < 0.0 )
#endif {
// This disables shadows on the backsides of objects.
shadowed = nDotL < 0.0f ? 1.0f : shadowed;
// Output Sat_NL_Att = 1.0f;
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, shadowed = mix( 1.0f, shadowed, atten );
Sat_NL_Att, lightColorOut = vec3(shadowed);
specular, specular *= lightBrightness;
previousPix ) * lightMapParams; addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
} }

View file

@ -22,40 +22,32 @@
#include "../../../gl/hlslCompat.glsl" #include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
#include "farFrustumQuad.glsl"
#include "../../../gl/torque.glsl"
#include "../../../gl/lighting.glsl"
#include "lightingUtils.glsl" #include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h" #include "../../shadowMap/shadowMapIO_GLSL.h"
#include "softShadow.glsl"
varying vec2 uv0; in vec4 hpos;
varying vec3 wsEyeRay; in vec2 uv0;
in vec3 wsEyeRay;
uniform sampler2D prePassBuffer; in vec3 vsEyeRay;
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
uniform sampler2D ShadowMap ;
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask ;
uniform vec4 rtParams2;
#endif #endif
uniform sampler2D prePassBuffer;
uniform vec3 lightDirection; uniform vec3 lightDirection;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform vec4 lightAmbient; uniform vec4 lightAmbient;
uniform vec4 lightTrilight;
uniform vec3 eyePosWorld; uniform vec3 eyePosWorld;
uniform mat4x4 worldToLightProj;
uniform mat4 worldToLightProj;
uniform vec4 splitDistStart;
uniform vec4 splitDistEnd;
uniform vec4 scaleX; uniform vec4 scaleX;
uniform vec4 scaleY; uniform vec4 scaleY;
uniform vec4 offsetX; uniform vec4 offsetX;
@ -65,15 +57,11 @@ uniform vec4 atlasYOffset;
uniform vec2 atlasScale; uniform vec2 atlasScale;
uniform vec4 zNearFarInvNearFar; uniform vec4 zNearFarInvNearFar;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform float constantSpecularPower;
uniform vec2 fadeStartLength; uniform vec2 fadeStartLength;
uniform vec4 farPlaneScalePSSM; uniform vec4 farPlaneScalePSSM;
uniform vec4 splitFade;
uniform vec4 overDarkPSSM; uniform vec4 overDarkPSSM;
uniform float shadowSoftness; uniform float shadowSoftness;
void main() void main()
{ {
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
@ -87,144 +75,158 @@ void main()
// Get the light attenuation. // Get the light attenuation.
float dotNL = dot(-lightDirection, normal); float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
vec3 debugColor = vec3(0);
#endif
#ifdef NO_SHADOW #ifdef NO_SHADOW
// Fully unshadowed. // Fully unshadowed.
float shadowed = 1.0; float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = vec3(1.0);
#endif
#else #else
// Compute shadow map coordinate // Compute shadow map coordinate
vec4 pxlPosLightProj = worldToLightProj * worldPos; vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
float distOffset = 0.0; // Distance to light, in shadowmap space
float shadowed = 0.0; float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
float fadeAmt = 0.0;
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
// Calculate things dependant on the shadowmap split // Figure out which split to sample from. Basically, we compute the shadowmap sample coord
for ( int i = 0; i < 2; i++ ) // for all of the splits and then check if its valid.
{ vec4 shadowCoordX = vec4( baseShadowCoord.x );
float zDistSplit = zDist.x + distOffset; vec4 shadowCoordY = vec4( baseShadowCoord.y );
vec4 mask0; vec4 farPlaneDists = vec4( distToLight );
mask0.x = float(zDistSplit >= splitDistStart.x); shadowCoordX *= scaleX;
mask0.y = float(zDistSplit >= splitDistStart.y); shadowCoordY *= scaleY;
mask0.z = float(zDistSplit >= splitDistStart.z); shadowCoordX += offsetX;
mask0.w = float(zDistSplit >= splitDistStart.w); shadowCoordY += offsetY;
farPlaneDists *= farPlaneScalePSSM;
vec4 mask1; // If the shadow sample is within -1..1 and the distance
mask1.x = float(zDistSplit < splitDistEnd.x); // to the light for this pixel is less than the far plane
mask1.y = float(zDistSplit < splitDistEnd.y); // of the split, use it.
mask1.z = float(zDistSplit < splitDistEnd.z); vec4 finalMask;
mask1.w = float(zDistSplit < splitDistEnd.w); 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);
vec4 finalMask = mask0 * mask1; 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);
float splitFadeDist = dot( finalMask, splitFade ); 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);
vec2 finalScale; else
finalScale.x = dot(finalMask, scaleX); finalMask = vec4(0, 0, 0, 1);
finalScale.y = dot(finalMask, scaleY);
vec2 finalOffset;
finalOffset.x = dot(finalMask, offsetX);
finalOffset.y = dot(finalMask, offsetY);
vec2 shadowCoord; #ifdef PSSM_DEBUG_RENDER
shadowCoord = baseShadowCoord * finalScale; if ( finalMask.x > 0 )
shadowCoord += finalOffset; 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
// Convert to texcoord space // Here we know what split we're sampling from, so recompute the texcoord location
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); // Yes, we could just use the result from above, but doing it this way actually saves
//shadowCoord.y = 1.0f - shadowCoord.y; // shader instructions.
vec2 finalScale;
finalScale.x = dot(finalMask, scaleX);
finalScale.y = dot(finalMask, scaleY);
// Move around inside of atlas vec2 finalOffset;
vec2 aOffset; finalOffset.x = dot(finalMask, offsetX);
aOffset.x = dot(finalMask, atlasXOffset); finalOffset.y = dot(finalMask, offsetY);
aOffset.y = dot(finalMask, atlasYOffset);
shadowCoord *= atlasScale; vec2 shadowCoord;
shadowCoord += aOffset; shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Distance to light, in shadowmap space // Convert to texcoord space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Each split has a different far plane, take this into account. // Move around inside of atlas
float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); vec2 aOffset;
distToLight *= farPlaneScale; aOffset.x = dot(finalMask, atlasXOffset);
aOffset.y = dot(finalMask, atlasYOffset);
#ifdef SOFTSHADOW_SM3 shadowCoord *= atlasScale;
shadowCoord += aOffset;
float esmShadow = softShadow_filter( ShadowMap, // Each split has a different far plane, take this into account.
gTapRotationTex, float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
uv0.xy, distToLight *= farPlaneScale;
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) );
#else // !SOFTSHADOW_SM3 float shadowed = softShadow_filter( ShadowMap,
uv0.xy,
float occluder = decodeShadowMap( texture2DLod( ShadowMap, shadowCoord, 0.0 ) ); shadowCoord,
float overDark = dot( finalMask, overDarkPSSM ); farPlaneScale * shadowSoftness,
float esmShadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); distToLight,
dotNL,
#endif dot( finalMask, overDarkPSSM ) );
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;
}
// Fade out the shadow at the end of the range. // 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; 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 #endif // !NO_SHADOW
// Calc lighting coefficents // Specular term
float specular = calcSpecular( -lightDirection, float specular = AL_CalcSpecular( -lightDirection,
normal, normal,
normalize(-wsEyeRay), normalize(-vsEyeRay) ) * lightBrightness * shadowed;
constantSpecularPower,
shadowed * lightBrightness );
float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed; float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness;
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = lightAmbient;
// Trilight, described by Tom Forsyth // TODO: This needs to be removed when lightmapping is disabled
// http://home.comcast.net/~tom_forsyth/papers/trilight/trilight.html // as its extra work per-pixel on dynamic lit scenes.
#ifdef ACCUMULATE_LUV //
// Special lightmapping pass.
if ( lightMapParams.a < 0.0 )
{
// This disables shadows on the backsides of objects.
shadowed = dotNL < 0.0f ? 1.0f : shadowed;
// In LUV multiply in the brightness of the light color (normaly done in the attenuate function) Sat_NL_Att = 1.0f;
Sat_NL_Att *= lightColor.a; lightColorOut = vec3(shadowed);
specular *= lightBrightness;
addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
vec4 ambientBlend = lightAmbient; // Sample the AO texture.
ambientBlend.b *= clamp(-dotNL, 0.0, 1.0); #ifdef USE_SSAO_MASK
float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams2 ) ).r;
addToResult *= ao;
#endif
vec3 trilight = lightTrilight.rgb; #ifdef PSSM_DEBUG_RENDER
trilight.b *= clamp(1.0 - abs(dotNL), 0.0, 1.0); lightColorOut = debugColor;
#endif
ambientBlend.rg = mix(ambientBlend.rg, trilight.rg, clamp(0.5 * trilight.b / lightAmbient.b, 0.0, 1.0)); OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
ambientBlend.b += trilight.b;
#else
// 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);
#endif
// Output
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, Sat_NL_Att, specular, ambientBlend) * lightMapParams;
} }

View file

@ -20,35 +20,27 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec2 uv; in vec2 uv;
uniform vec2 oneOverTargetSize; 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() void main()
{ {
vec2 sNonUniformTaps[8]; vec4 OUT = texture( diffuseMap, uv ) * weight[0];
sNonUniformTaps[0] = vec2(0.992833, 0.979309); for ( int i=1; i < 3; i++ )
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);
gl_FragColor = vec4(0.0);
vec2 texScale = vec2(1.0);
for ( int i=0; i < 4; i++ )
{ {
vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i]; vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
gl_FragColor += texture2D( diffuseMap, uv + offset ); OUT += texture( diffuseMap, uv + _sample ) * weight[i];
OUT += texture( diffuseMap, uv - _sample ) * weight[i];
} }
gl_FragColor /= vec4(4.0); OUT_FragColor0 = OUT;
gl_FragColor.rgb = vec3(0.0);
} }

View file

@ -22,13 +22,16 @@
#include "../../../../../../shaders/common/gl/torque.glsl" #include "../../../../../../shaders/common/gl/torque.glsl"
uniform vec2 oneOverTargetSize; in vec4 vPosition;
in vec2 vTexCoord0;
uniform vec4 rtParams0; uniform vec4 rtParams0;
varying vec2 uv; out vec2 uv;
void main() void main()
{ {
gl_Position = gl_Vertex; gl_Position = vPosition;
uv = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 );
gl_Position.y *= -1; //correct ssp
} }

View file

@ -26,7 +26,7 @@ uniform sampler2D diffuseMap0;
uniform float texSize; uniform float texSize;
uniform vec2 blurDimension; uniform vec2 blurDimension;
varying vec2 tex0; in vec2 tex0;
void main() void main()
{ {
@ -40,8 +40,8 @@ void main()
vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
for(int i = 0; i < int(blurSamples); i++) for(int i = 0; i < int(blurSamples); i++)
{ {
accum += texture2D(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset);
} }
accum /= blurSamples; accum /= blurSamples;
gl_FragColor = accum; OUT_FragColor0 = accum;
} }

View file

@ -20,12 +20,15 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 tex0; out vec2 tex0;
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; gl_Position = modelview * vPosition;
tex0 = gl_MultiTexCoord0.st; tex0 = vTexCoord0.st;
} }

View file

@ -22,27 +22,30 @@
#include "./../gl/torque.glsl" #include "./../gl/torque.glsl"
in vec4 vPosition;
in vec2 vTexCoord0;
in vec3 vTexCoord1;
uniform vec4 rtParams0; uniform vec4 rtParams0;
uniform vec4 rtParams1; uniform vec4 rtParams1;
uniform vec4 rtParams2; uniform vec4 rtParams2;
uniform vec4 rtParams3; uniform vec4 rtParams3;
varying vec2 uv0; out vec2 uv0;
varying vec2 uv1; out vec2 uv1;
varying vec2 uv2; out vec2 uv2;
varying vec2 uv3; out vec2 uv3;
varying vec3 wsEyeRay; out vec3 wsEyeRay;
void main() void main()
{ {
gl_Position = gl_Vertex; gl_Position = vPosition;
uv0 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 );
uv1 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams1 ); uv1 = viewportCoordToRenderTarget( vTexCoord0, rtParams1 );
uv2 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams2 ); uv2 = viewportCoordToRenderTarget( vTexCoord0, rtParams2 );
uv3 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams3 ); uv3 = viewportCoordToRenderTarget( vTexCoord0, rtParams3 );
wsEyeRay = gl_MultiTexCoord1.xyz; wsEyeRay = vTexCoord1;
} }

View file

@ -23,8 +23,10 @@
#include "../terrain.glsl" #include "../terrain.glsl"
#include "../../gl/hlslCompat.glsl" #include "../../gl/hlslCompat.glsl"
varying vec2 layerCoord; in vec2 layerCoord;
varying vec2 texCoord; #define IN_layerCoord layerCoord
in vec2 texCoord;
#define IN_texCoord texCoord
uniform sampler2D layerTex; uniform sampler2D layerTex;
uniform sampler2D textureMap; uniform sampler2D textureMap;
@ -33,12 +35,12 @@ uniform float layerSize;
void main() 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) if(blend - 0.0001 < 0.0)
discard; discard;
gl_FragColor = vec4( texture2D( textureMap, texCoord ).rgb, blend ); OUT_FragColor0 = vec4( texture( textureMap, IN_texCoord ).rgb, blend );
} }

View file

@ -23,14 +23,19 @@
/// The vertex shader used in the generation and caching of the /// The vertex shader used in the generation and caching of the
/// base terrain texture. /// base terrain texture.
varying vec2 layerCoord; in vec4 vPosition;
varying vec2 texCoord; in vec2 vTexCoord0;
out vec2 layerCoord;
out vec2 texCoord;
uniform vec2 texScale; uniform vec2 texScale;
void main() void main()
{ {
gl_Position = vec4(gl_Vertex.xyz, 1.0); gl_Position = vec4(vPosition.xyz, 1.0);
layerCoord = gl_MultiTexCoord0.st; layerCoord = vTexCoord0.st;
texCoord = gl_MultiTexCoord0.st * texScale; texCoord = vTexCoord0.st * texScale;
gl_Position.y *= -1;
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -26,12 +26,12 @@
uniform vec4 kernel; uniform vec4 kernel;
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec2 texc0, texc1, texc2, texc3; in vec2 texc0, texc1, texc2, texc3;
void main() void main()
{ {
gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x; OUT_FragColor0 = texture(diffuseMap, texc0) * kernel.x;
gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y; OUT_FragColor0 += texture(diffuseMap, texc1) * kernel.y;
gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z; OUT_FragColor0 += texture(diffuseMap, texc2) * kernel.z;
gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w; OUT_FragColor0 += texture(diffuseMap, texc3) * kernel.w;
} }

View file

@ -24,20 +24,25 @@
// Glow shader // Glow shader
//***************************************************************************** //*****************************************************************************
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
uniform vec2 offset0, offset1, offset2, offset3; uniform vec2 offset0, offset1, offset2, offset3;
varying vec2 texc0, texc1, texc2, texc3; out vec2 texc0, texc1, texc2, texc3;
void main() 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; tc.y = 1.0 - tc.y;
texc0 = tc + offset0; texc0 = tc + offset0;
texc1 = tc + offset1; texc1 = tc + offset1;
texc2 = tc + offset2; texc2 = tc + offset2;
texc3 = tc + offset3; texc3 = tc + offset3;
gl_Position.y *= -1;
} }

View file

@ -22,12 +22,20 @@
#include "hlslCompat.glsl" #include "hlslCompat.glsl"
varying vec4 texCoord12; //-----------------------------------------------------------------------------
varying vec4 texCoord34; // Structures
varying vec3 vLightTS; // light vector in tangent space, denormalized //-----------------------------------------------------------------------------
varying vec3 vViewTS; // view vector in tangent space, denormalized //ConnectData
varying vec3 vNormalWS; // Normal vector in world space in vec4 texCoord12;
varying float worldDist; #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 // Uniforms
@ -37,6 +45,7 @@ uniform vec3 ambientColor;
uniform vec3 sunColor; uniform vec3 sunColor;
uniform float cloudCoverage; uniform float cloudCoverage;
uniform vec3 cloudBaseColor; uniform vec3 cloudBaseColor;
uniform float cloudExposure;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Globals // Globals
@ -97,26 +106,25 @@ void main()
// Normalize the interpolated vectors: // Normalize the interpolated vectors:
vec3 vViewTS = normalize( vViewTS ); vec3 vViewTS = normalize( vViewTS );
vec3 vLightTS = normalize( vLightTS ); 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 ); noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
//return noise1; //return noise1;
vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy ); vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy );
noise2 = normalize( ( noise2 - 0.5 ) * 2.0 ); noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
//return noise2; //return noise2;
vec3 noiseNormal = normalize( noise1 + noise2 ).xyz; 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 ); 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 += noiseNormal;
vNormalTS = normalize( vNormalTS ); vNormalTS = normalize( vNormalTS );
@ -124,16 +132,14 @@ void main()
cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS ); cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
float coverage = ( cloudCoverage - 0.5 ) * 2.0; 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 ) if ( cloudCoverage > -1.0 )
cResultColor.a /= 1.0 + coverage; 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. OUT_FragColor0 = cResultColor;
// But since this example isn't doing that, we just output the computed result color here:
gl_FragColor = cResultColor;
} }

View file

@ -20,12 +20,24 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 texCoord12; #include "hlslCompat.glsl"
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized in vec4 vPosition;
varying vec3 vViewTS; // view vector in tangent space, denormalized in vec3 vNormal;
varying vec3 vNormalWS; // Normal vector in world space in vec3 vBinormal;
varying float worldDist; 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 // Uniforms
@ -43,37 +55,37 @@ uniform vec3 texScale;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 pos = gl_Vertex; vec4 IN_pos = vPosition;
vec3 normal = gl_Normal; vec3 IN_normal = vNormal;
vec3 binormal = gl_MultiTexCoord0.xyz; vec3 IN_binormal = vBinormal;
vec3 tangent = gl_MultiTexCoord1.xyz; vec3 IN_tangent = vTangent;
vec2 uv0 = gl_MultiTexCoord2.st; 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. // 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; OUT_texCoord12.xy = uv * texScale.x;
texCoord12.xy += texOffset0; OUT_texCoord12.xy += texOffset0;
texCoord12.zw = uv * texScale.y; OUT_texCoord12.zw = uv * texScale.y;
texCoord12.zw += texOffset1; OUT_texCoord12.zw += texOffset1;
texCoord34.xy = uv * texScale.z; OUT_texCoord34.xy = uv * texScale.z;
texCoord34.xy += texOffset2; OUT_texCoord34.xy += texOffset2;
texCoord34.z = pos.z; OUT_texCoord34.z = IN_pos.z;
texCoord34.w = 0.0; OUT_texCoord34.w = 0.0;
// Transform the normal, tangent and binormal vectors from object space to // Transform the normal, tangent and binormal vectors from object space to
// homogeneous projection space: // homogeneous projection space:
vNormalWS = -normal; vec3 vNormalWS = -IN_normal;
vec3 vTangentWS = -tangent; vec3 vTangentWS = -IN_tangent;
vec3 vBinormalWS = -binormal; vec3 vBinormalWS = -IN_binormal;
// Compute position in world space: // 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): // Compute and output the world view vector (unnormalized):
vec3 vViewWS = eyePosWorld - vPositionWS.xyz; vec3 vViewWS = eyePosWorld - vPositionWS.xyz;
@ -81,12 +93,14 @@ void main()
// Compute denormalized light vector in world space: // Compute denormalized light vector in world space:
vec3 vLightWS = -sunVec; 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 ); mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS );
// Propagate the view and the light vectors (in tangent space): // Propagate the view and the light vectors (in tangent space):
vLightTS = mWorldToTangent * vLightWS; OUT_vLightTS = vLightWS * mWorldToTangent;
vViewTS = vViewWS * mWorldToTangent; OUT_vViewTS = mWorldToTangent * vViewWS;
worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 ); OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 );
correctSSP(gl_Position);
} }

View file

@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo;
uniform vec2 gc_turbInfo; 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, void foliageProcessVert( inout vec3 position,
inout vec4 diffuse, inout vec4 diffuse,
in vec4 texCoord, inout vec4 texCoord,
out vec2 outTexCoord,
inout vec3 normal, inout vec3 normal,
inout vec3 T, inout vec3 T,
in vec3 eyePos ) 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. // 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; T = gc_camRight;
// Pull out local vars we need for work. // 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. // Grab the uv set and setup the texture coord.
vec4 uvSet = gc_typeRects[type]; vec4 uvSet = gc_typeRects[type];
outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x ); texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y ); texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
// Animate the normal to get lighting changes // Animate the normal to get lighting changes
// across the the wind swept foliage. // across the the wind swept foliage.
@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position,
normal.xy += wind.xy * ( 10.0 * texCoord.w ); normal.xy += wind.xy * ( 10.0 * texCoord.w );
normal = normalize( normal ); normal = normalize( normal );
// Get the alpha fade value. // Get the alpha fade value.
float fadeStart = gc_fadeParams.x; float fadeStart = gc_fadeParams.x;

View file

@ -26,15 +26,15 @@
uniform sampler2D diffuseMap, alphaMap; uniform sampler2D diffuseMap, alphaMap;
uniform vec4 groundAlpha; uniform vec4 groundAlpha;
varying vec4 color, groundAlphaCoeff; in vec4 color, groundAlphaCoeff;
varying vec2 outTexCoord, alphaLookup; in vec2 outTexCoord, alphaLookup;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 alpha = texture2D(alphaMap, alphaLookup); vec4 alpha = texture(alphaMap, alphaLookup);
gl_FragColor = color * texture2D(diffuseMap, outTexCoord); OUT_FragColor0 = color * texture(diffuseMap, outTexCoord);
gl_FragColor.a = gl_FragColor.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x; OUT_FragColor0.a = OUT_FragColor0.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x;
} }

View file

@ -23,13 +23,20 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec3 vNormal;
in vec4 vColor;
in vec2 vTexCoord0;
in vec2 vTexCoord1;
in vec2 vTexCoord2;
uniform mat4 projection, world; uniform mat4 projection, world;
uniform vec3 CameraPos; uniform vec3 CameraPos;
uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront, uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront,
GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange; GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange;
varying vec4 color, groundAlphaCoeff; out vec4 color, groundAlphaCoeff;
varying vec2 outTexCoord, alphaLookup; out vec2 outTexCoord, alphaLookup;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -42,9 +49,9 @@ void main()
trans[1][1] = 1.0; trans[1][1] = 1.0;
trans[2][2] = 1.0; trans[2][2] = 1.0;
trans[3][3] = 1.0; trans[3][3] = 1.0;
trans[3][0] = gl_Vertex.x; trans[3][0] = vPosition.x;
trans[3][1] = gl_Vertex.y; trans[3][1] = vPosition.y;
trans[3][2] = gl_Vertex.z; trans[3][2] = vPosition.z;
// Billboard transform * world matrix // Billboard transform * world matrix
mat4 o = world; 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, // 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. // the y coordinate determines if this vertex actually sways or not.
float xSway, ySway; float xSway, ySway;
float wavePhase = GlobalSwayPhase * gl_MultiTexCoord1.x; float wavePhase = GlobalSwayPhase * vTexCoord1.x;
ySway = sin(wavePhase); ySway = sin(wavePhase);
xSway = cos(wavePhase); xSway = cos(wavePhase);
xSway = xSway * gl_MultiTexCoord1.y * SwayMagnitudeSide; xSway = xSway * vTexCoord1.y * SwayMagnitudeSide;
ySway = ySway * gl_MultiTexCoord1.y * SwayMagnitudeFront; ySway = ySway * vTexCoord1.y * SwayMagnitudeFront;
vec4 p; 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 // Project the point
gl_Position = projection * p; gl_Position = projection * p;
// Lighting // Lighting
float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + gl_Normal.y); float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y);
// Alpha // 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; float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange;
alpha = clamp(alpha, 0.0, 1.0); //pass it through alpha = clamp(alpha, 0.0, 1.0); //pass it through
alphaLookup = vec2(alpha, 0.0); alphaLookup = vec2(alpha, 0.0);
bool alphaCoeff = bool(gl_Normal.z); bool alphaCoeff = bool(vNormal.z);
groundAlphaCoeff = vec4(float(alphaCoeff)); groundAlphaCoeff = vec4(float(alphaCoeff));
outTexCoord = gl_MultiTexCoord0.st; outTexCoord = vTexCoord0.st;
color = vec4(Luminance, Luminance, Luminance, 1.0); color = vec4(Luminance, Luminance, Luminance, 1.0);
gl_Position.y *= -1;
} }

View file

@ -20,16 +20,20 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4x4 modelview; uniform mat4x4 modelview;
varying vec4 hpos; out vec4 hpos;
varying vec2 uv0; out vec2 uv0;
void main() void main()
{ {
hpos = vec4( modelview * gl_Vertex ); hpos = vec4( modelview * vPosition );
gl_Position = hpos; gl_Position = hpos;
uv0 = gl_MultiTexCoord0.st; uv0 = vTexCoord0.st;
gl_Position.y *= -1;
} }

View file

@ -27,17 +27,79 @@
#define float3 vec3 #define float3 vec3
#define float2 vec2 #define float2 vec2
#define texCUBE textureCube #define half float
#define tex2D texture2D #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 #define lerp mix
float saturate( float val ) { return clamp( val, 0.0, 1.0 ); } void tSetMatrixRow(out float3x3 m, int row, float3 value)
vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); } {
vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); } m[0][row] = value.x;
vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); } m[1][row] = value.y;
m[2][row] = value.z;
}
float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } void tSetMatrixRow(out float4x4 m, int row, float4 value)
vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } {
vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } m[0][row] = value.x;
vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); } 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

View file

@ -20,73 +20,181 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef TORQUE_SHADERGEN
// These are the uniforms used by most lighting shaders. // These are the uniforms used by most lighting shaders.
uniform vec3 inLightPos[4]; uniform vec4 inLightPos[3];
uniform vec4 inLightInvRadiusSq; uniform vec4 inLightInvRadiusSq;
uniform vec4 inLightColor[4]; uniform vec4 inLightColor[4];
#ifndef TORQUE_BL_NOSPOTLIGHT
uniform vec4 inLightSpotDir[3];
uniform vec4 inLightSpotAngle;
uniform vec4 inLightSpotFalloff;
#endif
uniform vec4 ambient; uniform vec4 ambient;
uniform float specularPower; uniform float specularPower;
uniform vec4 specularColor; uniform vec4 specularColor;
#endif // !TORQUE_SHADERGEN
// 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
void compute4Lights( vec3 wsView, void compute4Lights( vec3 wsView,
vec3 wsPosition, 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 outDiffuse,
out vec4 outSpecular ) out vec4 outSpecular )
{ {
#ifdef PHONG_SPECULAR // NOTE: The light positions and spotlight directions
// (R.V)^c // are stored in SoA order, so inLightPos[0] is the
float reflected = reflect( wsView, wsNormal ); // x coord for all 4 lights... inLightPos[1] is y... etc.
#endif //
// 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.
vec4 nDotL = vec4( 0.0 );
vec4 rDotL = vec4( 0.0 );
vec4 sqDists = vec4( 0.0 );
int i; int i;
for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) vec4 lightVectors[3];
{ for ( i = 0; i < 3; i++ )
vec3 lightVector = inLightPos[i] - wsPosition; lightVectors[i] = wsPosition[i] - inLightPos[i];
vec3 lightDirection = normalize( lightVector );
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 // Accumulate the dot product between the light
rDotL[i] = saturate( dot( lightDirection, reflected ) ); // vector and the normal.
#else //
// (N.H)^c [Blinn-Phong, TGEA style, default] // The normal is negated because it faces away from
rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) ); // the surface and the light faces towards the
#endif // 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 // We're using the Phong specular reflection model
vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq ); // 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. // Combine the light colors for output.
vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) ); outDiffuse = vec4(0);
outDiffuse = vec4( 0.0 ); for ( i = 0; i < 4; i++ )
for ( i = 0; i < C4L_MAX_LIGHTS; ++i ) outDiffuse += intensity[i] * inLightColor[i];
outDiffuse += vec4( diffuse[i] ) * inLightColor[i];
// Output the specular power. // Output the specular power.
rDotL = max( rDotL, vec4( 0.00001 ) ); vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten;
outSpecular = pow( rDotL, vec4( specularPower ) );
// 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 /// @param toLight Normalized vector representing direction from the pixel
/// being lit, to the light source, in world space. /// 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 /// @param toEye The normalized vector representing direction from the pixel
/// being lit to the camera. /// being lit to the camera.
/// ///
/// @param specPwr The specular exponent. float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye )
///
/// @param specScale A scalar on the specular output used in RGB accumulation.
///
float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
{ {
#ifdef PHONG_SPECULAR #ifdef PHONG_SPECULAR
// (R.V)^c // (R.V)^c
@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
#endif #endif
// Return the specular factor. // Return the specular factor.
return pow( max( specVal, 0.00001f ), specPwr ); return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
} }

View file

@ -21,6 +21,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "torque.glsl" #include "torque.glsl"
#include "hlslCompat.glsl"
in vec4 offscreenPos;
in vec4 backbufferPos;
#define IN_offscreenPos offscreenPos
#define IN_backbufferPos backbufferPos
uniform sampler2D colorSource; uniform sampler2D colorSource;
uniform vec4 offscreenTargetParams; uniform vec4 offscreenTargetParams;
@ -31,8 +38,6 @@ uniform sampler2D edgeSource;
uniform vec4 edgeTargetParams; uniform vec4 edgeTargetParams;
#endif #endif
varying vec4 backbufferPos;
varying vec4 offscreenPos;
void main() void main()
{ {
@ -47,11 +52,10 @@ void main()
#ifdef REJECT_EDGES #ifdef REJECT_EDGES
// Cut out particles along the edges, this will create the stencil mask // Cut out particles along the edges, this will create the stencil mask
uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams); uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams);
float edge = texture2D( edgeSource, uvScene.zw ).r; float edge = texture( edgeSource, uvScene.zw ).r;
if (-edge < 0.0) clip( -edge );
discard;
#endif #endif
// Sample offscreen target and return // Sample offscreen target and return
gl_FragColor = texture2D( colorSource, uvScene.xy ); OUT_FragColor0 = texture( colorSource, uvScene.xy );
} }

View file

@ -20,16 +20,29 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform mat4 modelViewProj; #include "hlslCompat.glsl"
uniform mat4 targetModelViewProj;
varying vec4 offscreenPos; in vec2 vTexCoord0;
varying vec4 backbufferPos; #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() void main()
{ {
gl_Position = modelViewProj * gl_Vertex; OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0);
backbufferPos = gl_Position; OUT_hpos.xy *= screenRect.zw;
offscreenPos = targetModelViewProj * gl_Vertex; OUT_hpos.xy += screenRect.xy;
OUT_backbufferPos = OUT_hpos;
OUT_offscreenPos = OUT_hpos;
correctSSP(gl_Position);
} }

View file

@ -20,18 +20,14 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "hlslCompat.glsl"
#include "torque.glsl" #include "torque.glsl"
#include "hlslCompat.glsl"
// With advanced lighting we get soft particles. // With advanced lighting we get soft particles.
#ifdef TORQUE_LINEAR_DEPTH #ifdef TORQUE_LINEAR_DEPTH
#define SOFTPARTICLES #define SOFTPARTICLES
#endif #endif
#define CLIP_Z // TODO: Make this a proper macro
uniform sampler2D diffuseMap;
#ifdef SOFTPARTICLES #ifdef SOFTPARTICLES
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
@ -43,40 +39,73 @@ uniform sampler2D diffuseMap;
uniform vec4 prePassTargetParams; uniform vec4 prePassTargetParams;
#endif #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 alphaFactor;
uniform float alphaScale; uniform float alphaScale;
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
void main() void main()
{ {
float softBlend = 1.0; float softBlend = 1;
#ifdef SOFTPARTICLES #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); tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams);
float sceneDepth = prepassUncondition( prepassTex, tc ).w; float sceneDepth = prepassUncondition( prepassTex, tc ).w;
float depth = pos.w * oneOverFar; float depth = IN_pos.w * oneOverFar;
float diff = sceneDepth - depth; float diff = sceneDepth - depth;
#ifdef CLIP_Z #ifdef CLIP_Z
// If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer // 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 // When drawing high-res, though, we want to be able to take advantage of hi-z
// so this is #ifdef'd out // so this is #ifdef'd out
if (diff < 0.0) //clip(diff);
discard;
#endif #endif
softBlend = saturate( diff * oneOverSoftness ); softBlend = saturate( diff * oneOverSoftness );
#endif #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) // 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 ) );
} }

View file

@ -20,18 +20,35 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 color; #include "hlslCompat.glsl"
varying vec2 uv0;
varying vec4 pos; 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 modelViewProj;
uniform mat4 fsModelViewProj; uniform mat4 fsModelViewProj;
void main() void main()
{ {
gl_Position = modelViewProj * gl_Vertex; OUT_hpos = tMul( modelViewProj, In_pos );
pos = fsModelViewProj * gl_Vertex; OUT_pos = tMul( fsModelViewProj, In_pos );
color = gl_Color; OUT_color = In_color;
uv0 = gl_MultiTexCoord0.st; OUT_uv0 = In_uv0;
correctSSP(gl_Position);
} }

View file

@ -26,8 +26,8 @@
uniform sampler2D diffuseMap, refractMap, bumpMap; uniform sampler2D diffuseMap, refractMap, bumpMap;
uniform vec4 shadeColor; uniform vec4 shadeColor;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 TEX1; in vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Fade edges of axis for texcoord passed in // Fade edges of axis for texcoord passed in
@ -49,7 +49,7 @@ float fadeAxis( float val )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() 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 ); vec2 offset = vec2( bumpNorm.x, bumpNorm.y );
vec4 texIndex = TEX1; vec4 texIndex = TEX1;
@ -61,8 +61,8 @@ void main()
const float distortion = 0.2; const float distortion = 0.2;
texIndex.xy += offset * distortion * fadeVal; texIndex.xy += offset * distortion * fadeVal;
vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); vec4 diffuseColor = texture( diffuseMap, TEX0 );
vec4 reflectColor = texture2DProj( refractMap, texIndex ); vec4 reflectColor = textureProj( refractMap, texIndex );
gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a;
} }

View file

@ -23,10 +23,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 TEX0; out vec2 TEX0;
varying vec4 TEX1; out vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -38,11 +41,11 @@ void main()
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.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 = texGenTest * gl_Position;
TEX1.y = -TEX1.y; TEX1.y = -TEX1.y;
gl_Position.y *= -1;
} }

View file

@ -26,16 +26,16 @@
uniform sampler2D diffuseMap, refractMap; uniform sampler2D diffuseMap, refractMap;
uniform vec4 shadeColor; uniform vec4 shadeColor;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 TEX1; in vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); vec4 diffuseColor = texture( diffuseMap, TEX0 );
vec4 reflectColor = texture2DProj( refractMap, TEX1 ); vec4 reflectColor = textureProj( refractMap, TEX1 );
gl_FragColor = diffuseColor + reflectColor * diffuseColor.a; OUT_FragColor0 = diffuseColor + reflectColor * diffuseColor.a;
} }

View file

@ -23,10 +23,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 TEX0; out vec2 TEX0;
varying vec4 TEX1; out vec4 TEX1;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
@ -38,9 +41,9 @@ void main()
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.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 = texGenTest * gl_Position;
TEX1.y = -TEX1.y; TEX1.y = -TEX1.y;

View file

@ -25,13 +25,13 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec4 color; in vec4 color;
varying vec2 texCoord; in vec2 texCoord;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
gl_FragColor = texture2D(diffuseMap, texCoord) * color; OUT_FragColor0 = texture(diffuseMap, texCoord) * color;
} }

View file

@ -23,28 +23,32 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Data // Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
uniform vec3 cameraPos, ambient; uniform vec3 cameraPos, ambient;
uniform vec2 fadeStartEnd; uniform vec2 fadeStartEnd;
varying vec4 color; out vec4 color;
varying vec2 texCoord; out vec2 texCoord;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Main // Main
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; gl_Position = modelview * vPosition;
texCoord = gl_MultiTexCoord0.st; texCoord = vTexCoord0.st;
color = vec4( ambient.r, ambient.g, ambient.b, 1.0 ); color = vec4( ambient.r, ambient.g, ambient.b, 1.0 );
// Do we need to do a distance fade? // Do we need to do a distance fade?
if ( fadeStartEnd.x < fadeStartEnd.y ) 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 ); color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 );
} }
gl_Position.y *= -1;
} }

View file

@ -20,9 +20,11 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec2 texCoord; in vec2 texCoord;
varying vec4 color; in vec4 color;
varying float fade; in float fade;
out vec4 OUT_FragColor0;
uniform sampler2D inputTex; uniform sampler2D inputTex;
uniform vec4 ambient; uniform vec4 ambient;
@ -30,17 +32,6 @@ uniform vec4 ambient;
void main() void main()
{ {
vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f); float shadow = texture( inputTex, texCoord ).a * color.a;
float esmFactor = 200.0; OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow );
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;
} }

View file

@ -20,13 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//***************************************************************************** #include "hlslCompat.glsl"
// Precipitation vertex shader
//*****************************************************************************
varying vec2 texCoord; in vec4 vPosition;
varying vec4 color; in vec4 vColor;
varying float fade; in vec2 vTexCoord0;
in vec2 vTexCoord1;
out vec2 texCoord;
out vec4 color;
out float fade;
uniform mat4 modelview; uniform mat4 modelview;
uniform float shadowLength; uniform float shadowLength;
@ -34,11 +37,13 @@ uniform vec3 shadowCasterPosition;
void main() void main()
{ {
gl_Position = modelview * vec4(gl_Vertex.xyz, 1.0); gl_Position = modelview * vec4(vPosition.xyz, 1.0);
color = gl_Color; color = vColor;
texCoord = gl_MultiTexCoord1.st; texCoord = vTexCoord1.st;
float fromCasterDist = length(gl_Vertex.xyz - shadowCasterPosition) - shadowLength; float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength;
fade = 1.0 - clamp(fromCasterDist/shadowLength, 0.0, 1.0); fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 );
correctSSP(gl_Position);
} }

View file

@ -21,27 +21,22 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "torque.glsl" #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 // Conn
float getRayleighPhase(float fCos2) in vec4 rayleighColor;
{ #define IN_rayleighColor rayleighColor
//return 1.0; in vec4 mieColor;
return 0.75 + 0.75*fCos2; #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; uniform samplerCube nightSky ;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
uniform samplerCube nightSky;
uniform vec4 nightColor; uniform vec4 nightColor;
uniform vec2 nightInterpAndExposure; uniform vec2 nightInterpAndExposure;
uniform float useCubemap; uniform float useCubemap;
@ -50,7 +45,8 @@ 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 fCos2 = fCos*fCos;
float g = -0.991; 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); 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; color.a = color.b;
vec4 nightSkyColor = textureCube(nightSky, -v3Direction); vec4 nightSkyColor = texture(nightSky, -v3Direction);
nightSkyColor = mix(nightColor, nightSkyColor, useCubemap); nightSkyColor = mix(nightColor, nightSkyColor, useCubemap);
float fac = dot( normalize( pos ), sunDir ); float fac = dot( normalize( pos ), sunDir );
fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) ); 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 // Clip based on the camera-relative
// z position of the vertex, passed through // z position of the vertex, passed through
@ -74,6 +70,6 @@ void main()
if(zPosition < 0.0) if(zPosition < 0.0)
discard; discard;
gl_FragColor.a = 1; OUT_FragColor0.a = 1;
gl_FragColor = hdrEncode( gl_FragColor ); OUT_FragColor0 = hdrEncode( OUT_FragColor0 );
} }

View file

@ -20,12 +20,7 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const int nSamples = 4; #include "hlslCompat.glsl"
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;
// The scale equation calculated by Vernier's Graphical Analysis // The scale equation calculated by Vernier's Graphical Analysis
float vernierScale(float fCos) float vernierScale(float fCos)
@ -40,12 +35,27 @@ float vernierScale(float fCos)
return 0.25 * outx; 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. // This is the shader output data.
varying vec4 rayleighColor; out vec4 rayleighColor;
varying vec4 mieColor; #define OUT_rayleighColor rayleighColor
varying vec3 v3Direction; out vec4 mieColor;
varying float zPosition; #define OUT_mieColor mieColor
varying vec3 pos; 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 mat4 modelView;
uniform vec4 misc; uniform vec4 misc;
@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs;
uniform vec3 camPos; uniform vec3 camPos;
uniform vec3 lightDir; uniform vec3 lightDir;
uniform vec4 invWaveLength; uniform vec4 invWaveLength;
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() void main()
{ {
vec4 position = gl_Vertex.xyzw;
vec3 normal = gl_Normal.xyz;
vec4 color = gl_MultiTexCoord0.xyzw;
// Pull some variables out: // Pull some variables out:
float camHeight = misc.x; float camHeight = misc.x;
float camHeightSqr = misc.y; float camHeightSqr = misc.y;
@ -83,7 +96,7 @@ void main()
// Get the ray from the camera to the vertex, // Get the ray from the camera to the vertex,
// and its length (which is the far point of the ray // and its length (which is the far point of the ray
// passing through the atmosphere). // 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 ); vec3 newCamPos = vec3( 0, 0, camHeight );
v3Pos.z += innerRadius; v3Pos.z += innerRadius;
vec3 v3Ray = v3Pos.xyz - newCamPos; vec3 v3Ray = v3Pos.xyz - newCamPos;
@ -97,16 +110,7 @@ void main()
float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight)); float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
float fStartAngle = dot(v3Ray, v3Start) / fHeight; float fStartAngle = dot(v3Ray, v3Start) / fHeight;
float x = 1.0 - fStartAngle; float fStartOffset = fDepth * vernierScale( 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);
// Initialize the scattering loop variables. // Initialize the scattering loop variables.
float fSampleLength = fFar / 2.0; float fSampleLength = fFar / 2.0;
@ -123,24 +127,8 @@ void main()
float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight; float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight; float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
x = 1.0 - fCameraAngle; float vscale3 = vernierScale( fCameraAngle );
x5 = x * 5.25; float vscale2 = vernierScale( fLightAngle );
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 fScatter = (fStartOffset + fDepth*(vscale2 - vscale3)); float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI)); vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
@ -150,16 +138,24 @@ void main()
// Finally, scale the Mie and Rayleigh colors // Finally, scale the Mie and Rayleigh colors
// and set up the varying variables for the pixel shader. // and set up the varying variables for the pixel shader.
gl_Position = modelView * position; gl_Position = modelView * IN_position;
mieColor.rgb = v3FrontColor * mieBrightness; OUT_mieColor.rgb = v3FrontColor * mieBrightness;
mieColor.a = 1.0; OUT_mieColor.a = 1.0;
rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness); OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
rayleighColor.a = 1.0; OUT_rayleighColor.a = 1.0;
v3Direction = newCamPos - v3Pos.xyz; 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 #ifdef USE_COLORIZE
// along the horizon.
zPosition = position.z + 4000.0; OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a;
pos = position.xyz;
OUT_rayleighColor.r *= colorize.r;
OUT_rayleighColor.g *= colorize.g;
OUT_rayleighColor.b *= colorize.b;
#endif
correctSSP(gl_Position);
} }

View file

@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat )
return mat; return mat;
} }
/// The number of additional substeps we take when refining /// The number of additional substeps we take when refining
/// the results of the offset parallax mapping function below. /// the results of the offset parallax mapping function below.
/// ///
@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat )
/// Performs fast parallax offset mapping using /// Performs fast parallax offset mapping using
/// multiple refinement steps. /// 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 texCoord The incoming texture coordinate for sampling the parallax depth.
/// @param negViewTS The negative view vector in tangent space. /// @param negViewTS The negative view vector in tangent space.
/// @param depthScale The parallax factor used to scale the depth result. /// @param depthScale The parallax factor used to scale the depth result.
/// ///
vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale ) 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 ); vec2 offset = negViewTS.xy * ( depth * depthScale );
for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ ) 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 ); 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. /// The maximum value for 16bit per component integer HDR encoding.
const float HDR_RGB16_MAX = 100.0; 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. /// Encodes an HDR color for storage into a target.
vec3 hdrEncode( vec3 sample ){ vec3 hdrEncode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 ) #if defined( TORQUE_HDR_RGB16 )
return sample / HDR_RGB16_MAX; return _sample / HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 ) #elif defined( TORQUE_HDR_RGB10 )
return sample / HDR_RGB10_MAX; return _sample / HDR_RGB10_MAX;
#else #else
// No encoding. // No encoding.
return sample; return _sample;
#endif #endif
} }
/// Encodes an HDR color for storage into a target. /// 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. /// Decodes an HDR color from a target.
vec3 hdrDecode( vec3 sample ) vec3 hdrDecode( vec3 _sample )
{ {
#if defined( TORQUE_HDR_RGB16 ) #if defined( TORQUE_HDR_RGB16 )
return sample * HDR_RGB16_MAX; return _sample * HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 ) #elif defined( TORQUE_HDR_RGB10 )
return sample * HDR_RGB10_MAX; return _sample * HDR_RGB10_MAX;
#else #else
// No encoding. // No encoding.
return sample; return _sample;
#endif #endif
} }
/// Decodes an HDR color from a target. /// 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. /// Returns the luminance for an HDR pixel.
float hdrLuminance( vec3 sample ) float hdrLuminance( vec3 _sample )
{ {
// There are quite a few different ways to // There are quite a few different ways to
// calculate luminance from an rgb value. // calculate luminance from an rgb value.
@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample )
// //
// Max component luminance. // 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. // The perceptual relative luminance.
@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample )
// See http://en.wikipedia.org/wiki/Luminance_(relative) // See http://en.wikipedia.org/wiki/Luminance_(relative)
// //
const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 ); 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. // The average component luminance.
// //
//const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 ); //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; 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. /// 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 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. /// @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. /// @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_ #endif // _TORQUE_GLSL_

View file

@ -28,10 +28,10 @@ uniform float specularPower;
uniform vec4 ambient; uniform vec4 ambient;
uniform float accumTime; uniform float accumTime;
varying vec2 TEX0; in vec2 TEX0;
varying vec4 outLightVec; in vec4 outLightVec;
varying vec3 outPos; in vec3 outPos;
varying vec3 outEyePos; in vec3 outEyePos;
void main() void main()
{ {
@ -42,14 +42,14 @@ void main()
texOffset.x = TEX0.x + sinOffset1 + sinOffset2; texOffset.x = TEX0.x + sinOffset1 + sinOffset2;
texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05; 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 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0;
vec4 diffuse = texture2D(diffMap, texOffset); 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 eyeVec = normalize(outEyePos - outPos);
vec3 halfAng = normalize(eyeVec + outLightVec.xyz); vec3 halfAng = normalize(eyeVec + outLightVec.xyz);
float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w; float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w;
specular = pow(specular, specularPower); specular = pow(specular, specularPower);
gl_FragColor += specularColor * specular; OUT_FragColor0 += specularColor * specular;
} }

View file

@ -20,16 +20,33 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
varying vec4 wsEyeDir; #include "../../../gl/hlslCompat.glsl"
varying vec4 ssPos;
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 modelview;
uniform mat4 objTrans; uniform mat4 objTrans;
uniform mat4 worldViewOnly;
uniform vec3 eyePosWorld; uniform vec3 eyePosWorld;
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; OUT_hpos = tMul( modelview, IN_pos );
wsEyeDir = objTrans * gl_Vertex - vec4( eyePosWorld, 0.0 ); OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 );
ssPos = gl_Position; OUT_vsEyeDir = tMul( worldViewOnly, IN_pos );
OUT_ssPos = OUT_hpos;
correctSSP(gl_Position);
} }

View file

@ -20,14 +20,15 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D prepassBuffer; uniform sampler2D prepassBuffer;
uniform sampler1D depthViz; uniform sampler1D depthViz;
void main() void main()
{ {
float depth = prepassUncondition( prepassBuffer, uv0 ).w; float depth = prepassUncondition( prepassBuffer, uv0 ).w;
gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1 ); OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1.0 );
} }

View file

@ -20,15 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D lightInfoBuffer; uniform sampler2D lightInfoBuffer;
void main() void main()
{ {
vec3 lightcolor; vec3 lightcolor;
float nl_Att, specular; float nl_Att, specular;
lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular );
gl_FragColor = vec4( lightcolor, 1.0 ); OUT_FragColor0 = vec4( lightcolor, 1.0 );
} }

View file

@ -20,15 +20,16 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D lightInfoBuffer; uniform sampler2D lightInfoBuffer;
void main() void main()
{ {
vec3 lightcolor; vec3 lightcolor;
float nl_Att, specular; float nl_Att, specular;
lightinfoUncondition( texture2DLod( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular ); lightinfoUncondition( texture( lightInfoBuffer, uv0 ), lightcolor, nl_Att, specular );
gl_FragColor = vec4( specular, specular, specular, 1.0 ); OUT_FragColor0 = vec4( specular, specular, specular, 1.0 );
} }

View file

@ -20,14 +20,14 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
in vec2 uv0;
varying vec2 uv0; uniform sampler2D prepassBuffer;
uniform sampler2D prepassTex;
void main() void main()
{ {
vec3 normal = prepassUncondition( prepassTex, uv0 ).xyz; vec3 normal = prepassUncondition( prepassBuffer, uv0 ).xyz;
gl_FragColor = vec4( ( normal + 1.0 ) * 0.5, 1.0 ); OUT_FragColor0 = vec4( ( normal + 1.0 ) * 0.5, 1.0 );
} }

View file

@ -19,13 +19,14 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
varying vec2 uv0; in vec2 uv0;
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
uniform sampler1D depthViz; uniform sampler1D depthViz;
void main() void main()
{ {
float depth = clamp( texture2DLod( shadowMap, uv0, 0 ).r, 0.0, 1.0 ); float depth = saturate( texture( shadowMap, uv0 ).r );
gl_FragColor = vec4( texture1D( depthViz, depth ).rgb, 1.0 ); OUT_FragColor0 = vec4( texture( depthViz, depth ).rgb, 1 );
} }

View file

@ -24,7 +24,7 @@
vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams ) vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams )
{ {
vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0; vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0;
outPos.y = 1.0 - outPos.y;
outPos = ( outPos * rtParams.zw ) + rtParams.xy; outPos = ( outPos * rtParams.zw ) + rtParams.xy;
//outPos.y = 1.0 - outPos.y;
return outPos; return outPos;
} }

View file

@ -20,24 +20,32 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
#include "farFrustumQuad.glsl" #include "farFrustumQuad.glsl"
uniform vec4 renderTargetParams; in vec4 vPosition;
in vec3 vNormal;
varying vec4 hpos; in vec3 vTangent;
varying vec2 uv0; in vec2 vTexCoord0;
varying vec3 wsEyeRay;
uniform vec4 rtParams0;
out vec4 hpos;
out vec2 uv0;
out vec3 wsEyeRay;
out vec3 vsEyeRay;
void main() void main()
{ {
// Expand the SS coordinate (stored in uv0) hpos = vec4( vTexCoord0, 0, 1 );
hpos = vec4( gl_MultiTexCoord0.st * 2.0 - 1.0, 1.0, 1.0 );
gl_Position = hpos;
// Get a RT-corrected UV from the SS coord // 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 // Interpolators will generate eye rays the
wsEyeRay = gl_Vertex.xyz; // from far-frustum corners.
wsEyeRay = vTangent;
vsEyeRay = vNormal;
correctSSP(gl_Position);
} }

View file

@ -21,34 +21,26 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl" #include "../../../gl/hlslCompat.glsl"
#include "farFrustumQuad.glsl"
#include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h"
#include "shadergen:/autogenConditioners.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 #ifdef USE_COOKIE_TEX
// filtering for SM3.0 and above.
#define SOFTSHADOW_SM3
#include "softShadow.glsl"
#else
/// The texture for cookie rendering.
uniform samplerCube cookieMap ;
#endif #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 #ifdef SHADOW_CUBE
vec3 decodeShadowCoord( vec3 shadowCoord ) vec3 decodeShadowCoord( vec3 shadowCoord )
@ -56,39 +48,47 @@
return shadowCoord; 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 ) vec3 decodeShadowCoord( vec3 paraVec )
{ {
// Swizzle z and y // Flip y and z
paraVec = paraVec.xzy; paraVec = paraVec.xzy;
#ifdef SHADOW_DUALPARABOLOID_SINGLE_PASS #ifndef SHADOW_PARABOLOID
bool calcBack = (paraVec.z < 0.0); bool calcBack = (paraVec.z < 0.0);
if(calcBack) if ( calcBack )
{
paraVec.z = paraVec.z * -1.0; paraVec.z = paraVec.z * -1.0;
#ifdef SHADOW_DUALPARABOLOID
paraVec.x = -paraVec.x;
#endif
}
#endif #endif
vec3 shadowCoord; vec3 shadowCoord;
shadowCoord.x = (paraVec.x / (2.0*(1.0 + paraVec.z))) + 0.5; shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5;
shadowCoord.y = ((paraVec.y / (2.0*(1.0 + paraVec.z))) + 0.5); shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5);
shadowCoord.z = 0; shadowCoord.z = 0;
// adjust the co-ordinate slightly if it is near the extent of the paraboloid // adjust the co-ordinate slightly if it is near the extent of the paraboloid
// this value was found via experementation // 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 this is the back, offset in the atlas
if(calcBack) if ( calcBack )
shadowCoord.x += 1.0; shadowCoord.x += 1.0;
// Atlasing front and back maps, so scale // Atlasing front and back maps, so scale
@ -99,51 +99,35 @@
return shadowCoord; return shadowCoord;
} }
#else
#error Unknown shadow type!
#endif #endif
varying vec4 wsEyeDir;
varying vec4 ssPos;
uniform sampler2D prePassBuffer; uniform sampler2D prePassBuffer;
#ifdef SHADOW_CUBE #ifdef SHADOW_CUBE
uniform samplerCube shadowMap; uniform samplerCube shadowMap;
#else #else
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
#endif
#ifdef ACCUMULATE_LUV
uniform sampler2D scratchTarget;
#endif #endif
uniform vec4 renderTargetParams; uniform vec4 rtParams0;
uniform vec3 lightPosition; uniform vec3 lightPosition;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform float lightRange; uniform float lightRange;
uniform vec2 lightAttenuation; uniform vec2 lightAttenuation;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform vec3 eyePosWorld; uniform mat3 viewToLightProj;
uniform vec4 farPlane;
uniform float negFarPlaneDotEye;
uniform mat3x3 worldToLightProj;
uniform vec4 lightParams; uniform vec4 lightParams;
uniform float shadowSoftness; uniform float shadowSoftness;
uniform float constantSpecularPower;
void main() void main()
{ {
// Compute scene UV // Compute scene UV
vec3 ssPosP = ssPos.xyz / ssPos.w; vec3 ssPos = ssPos.xyz / ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
@ -151,21 +135,17 @@ void main()
float depth = prepassSample.a; float depth = prepassSample.a;
// Eye ray - Eye -> Pixel // Eye ray - Eye -> Pixel
vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane );
vec3 viewSpacePos = eyeRay * depth;
// Get world space pixel position
vec3 worldPos = eyePosWorld + eyeRay * depth;
// Build light vec, get length, clip pixel if needed // Build light vec, get length, clip pixel if needed
vec3 lightVec = lightPosition - worldPos; vec3 lightVec = lightPosition - viewSpacePos;
float lenLightV = length( lightVec ); float lenLightV = length( lightVec );
if ( lightRange - lenLightV < 0.0 ) clip( lightRange - lenLightV );
discard;
// Get the attenuated falloff. // Get the attenuated falloff.
float atten = attenuate( lightColor, lightAttenuation, lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV );
if ( atten - 1e-6 < 0.0 ) clip( atten - 1e-6 );
discard;
// Normalize lightVec // Normalize lightVec
lightVec /= lenLightV; lightVec /= lenLightV;
@ -181,61 +161,73 @@ void main()
#else #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. // 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, float shadowed = softShadow_filter( shadowMap,
gTapRotationTex, ssPos.xy,
ssPosP.xy, shadowCoord,
shadowCoord.xy,
shadowSoftness, shadowSoftness,
distToLight, distToLight,
nDotL, nDotL,
lightParams.y ); lightParams.y );
#else // !SOFTSHADOW_SM3
// TODO: Implement the SM2 lower quality
// shadow filtering method.
#endif #endif
#endif // !NO_SHADOW #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 // NOTE: Do not clip on fully shadowed pixels as it would
// cause the hardware occlusion query to disable the shadow. // cause the hardware occlusion query to disable the shadow.
// Specular term // Specular term
float specular = calcSpecular( lightVec, float specular = AL_CalcSpecular( lightVec,
normal, normal,
normalize( -eyeRay ), normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
constantSpecularPower,
shadowed * atten * lightBrightness );
// N.L * Attenuation float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = vec4(0.0);
// In LUV color mode we need to blend in the // TODO: This needs to be removed when lightmapping is disabled
// output from the previous target. // as its extra work per-pixel on dynamic lit scenes.
vec4 previousPix = vec4(0.0); //
#ifdef ACCUMULATE_LUV // Special lightmapping pass.
previousPix = texture2DLod( scratchTarget, uvScene, 0 ); if ( lightMapParams.a < 0.0 )
#endif {
// This disables shadows on the backsides of objects.
shadowed = nDotL < 0.0f ? 1.0f : shadowed;
// Output Sat_NL_Att = 1.0f;
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, shadowed = mix( 1.0f, shadowed, atten );
Sat_NL_Att, lightColorOut = vec3(shadowed);
specular, specular *= lightBrightness;
previousPix ) * lightMapParams; addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
} }

View file

@ -21,38 +21,55 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define NUM_TAPS 12 #if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
#define NUM_PRE_TAPS 4 #define NUM_PRE_TAPS 4
#define NUM_TAPS 12
/// The non-uniform poisson disk used in the /// The non-uniform poisson disk used in the
/// high quality shadow filtering. /// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS]; vec2 sNonUniformTaps[NUM_TAPS] = vec2[]
(
void initNonUniformTaps()
{
// These first 4 taps are located around the edges // These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed // of the disk and are used to predict fully shadowed
// or unshadowed areas. // or unshadowed areas.
sNonUniformTaps[0] = vec2( 0.992833, 0.979309 ); vec2( 0.992833, 0.979309 ),
sNonUniformTaps[1] = vec2( -0.998585, 0.985853 ); vec2( -0.998585, 0.985853 ),
sNonUniformTaps[2] = vec2( 0.949299, -0.882562 ); vec2( 0.949299, -0.882562 ),
sNonUniformTaps[3] = vec2( -0.941358, -0.893924 ); vec2( -0.941358, -0.893924 ),
// The rest of the samples. // The rest of the samples.
sNonUniformTaps[4] = vec2( 0.545055, -0.589072 ); vec2( 0.545055, -0.589072 ),
sNonUniformTaps[5] = vec2( 0.346526, 0.385821 ); vec2( 0.346526, 0.385821 ),
sNonUniformTaps[6] = vec2( -0.260183, 0.334412 ); vec2( -0.260183, 0.334412 ),
sNonUniformTaps[7] = vec2( 0.248676, -0.679605 ); vec2( 0.248676, -0.679605 ),
sNonUniformTaps[8] = vec2( -0.569502, -0.390637 ); vec2( -0.569502, -0.390637 ),
sNonUniformTaps[9] = vec2( -0.014096, 0.012577 ); vec2( -0.614096, 0.212577 ),
sNonUniformTaps[10] = vec2( -0.259178, 0.876272 ); vec2( -0.259178, 0.876272 ),
sNonUniformTaps[11] = vec2( 0.649526, 0.664333 ); 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 /// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps. /// rotations of the filter taps.
uniform sampler2D gTapRotationTex; uniform sampler2D gTapRotationTex ;
float softShadow_sampleTaps( sampler2D shadowMap, float softShadow_sampleTaps( sampler2D shadowMap,
@ -64,17 +81,16 @@ float softShadow_sampleTaps( sampler2D shadowMap,
int startTap, int startTap,
int endTap ) int endTap )
{ {
initNonUniformTaps(); float shadow = 0;
float shadow = 0.0;
vec2 tap = vec2(0.0); vec2 tap = vec2(0);
for ( int t = startTap; t < endTap; t++ ) for ( int t = startTap; t < endTap; t++ )
{ {
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; 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; tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r; float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r;
float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 ); float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
shadow += esm / float( endTap - startTap ); shadow += esm / float( endTap - startTap );
} }
@ -82,13 +98,7 @@ float softShadow_sampleTaps( sampler2D shadowMap,
} }
// 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, float softShadow_filter( sampler2D shadowMap,
sampler2D noiseTexture,
vec2 vpos, vec2 vpos,
vec2 shadowPos, vec2 shadowPos,
float filterRadius, float filterRadius,
@ -96,36 +106,54 @@ float softShadow_filter( sampler2D shadowMap,
float dotNL, float dotNL,
float esmFactor ) float esmFactor )
{ {
// Lookup the random rotation for this screen pixel. #ifndef SOFTSHADOW
vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0;
// Do the prediction taps first. // If softshadow is undefined then we skip any complex
float shadow = softShadow_sampleTaps( shadowMap, // filtering... just do a single sample ESM.
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// Only do the expensive filtering if we're really float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r;
// in a partially shadowed area. float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
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 #else
// of the prediction samples.
shadow *= 0.5; // 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; return shadow;
} }

View file

@ -25,58 +25,49 @@
#include "lightingUtils.glsl" #include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h" #include "../../shadowMap/shadowMapIO_GLSL.h"
#include "shadergen:/autogenConditioners.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 #ifdef USE_COOKIE_TEX
// filtering for SM3.0 and above.
#define SOFTSHADOW_SM3
#include "softShadow.glsl"
#else
/// The texture for cookie rendering.
uniform sampler2D cookieMap;
#endif #endif
varying vec4 ssPos;
varying vec4 wsEyeDir;
uniform sampler2D prePassBuffer; uniform sampler2D prePassBuffer;
uniform sampler2D shadowMap; uniform sampler2D shadowMap;
#ifdef ACCUMULATE_LUV
uniform sampler2D scratchTarget;
#endif
uniform vec4 renderTargetParams; uniform vec4 rtParams0;
uniform vec3 lightPosition; uniform vec3 lightPosition;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform float lightRange; uniform float lightRange;
uniform vec2 lightAttenuation; uniform vec2 lightAttenuation;
uniform vec3 lightDirection; uniform vec3 lightDirection;
uniform vec4 lightSpotParams; uniform vec4 lightSpotParams;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform vec3 eyePosWorld; uniform vec4 vsFarPlane;
uniform vec4 farPlane; uniform mat4 viewToLightProj;
uniform float negFarPlaneDotEye;
uniform mat4x4 worldToLightProj;
uniform vec4 lightParams; uniform vec4 lightParams;
uniform float shadowSoftness; uniform float shadowSoftness;
uniform float constantSpecularPower;
void main() void main()
{ {
// Compute scene UV // Compute scene UV
vec3 ssPosP = ssPos.xyz / ssPos.w; vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPosP, renderTargetParams ); vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene ); vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
@ -84,85 +75,92 @@ void main()
float depth = prepassSample.a; float depth = prepassSample.a;
// Eye ray - Eye -> Pixel // Eye ray - Eye -> Pixel
vec3 eyeRay = getDistanceVectorToPlane( negFarPlaneDotEye, wsEyeDir.xyz / wsEyeDir.w , farPlane ); vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane );
vec3 viewSpacePos = eyeRay * depth;
// Get world space pixel position
vec3 worldPos = eyePosWorld + eyeRay * depth;
// Build light vec, get length, clip pixel if needed // Build light vec, get length, clip pixel if needed
vec3 lightToPxlVec = worldPos - lightPosition; vec3 lightToPxlVec = viewSpacePos - lightPosition;
float lenLightV = length( lightToPxlVec ); float lenLightV = length( lightToPxlVec );
lightToPxlVec /= lenLightV; 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 ); float cosAlpha = dot( lightDirection, lightToPxlVec );
if ( cosAlpha - lightSpotParams.x < 0.0 ) discard; clip( cosAlpha - lightSpotParams.x );
if ( lightRange - lenLightV < 0.0 ) discard; clip( lightRange - lenLightV );
float atten = attenuate( lightColor, lightAttenuation, lenLightV ); float atten = attenuate( lightColor, lightAttenuation, lenLightV );
atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; 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 ); 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 #ifdef NO_SHADOW
float shadowed = 1.0; float shadowed = 1.0;
#else #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. // Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange; float distToLight = pxlPosLightProj.z / lightRange;
#ifdef SOFTSHADOW_SM3 float shadowed = softShadow_filter( shadowMap,
ssPos.xy,
float shadowed = softShadow_filter( shadowMap, shadowCoord,
gTapRotationTex, shadowSoftness,
ssPosP.xy, distToLight,
shadowCoord, nDotL,
shadowSoftness, lightParams.y );
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
#endif // !NO_SHADOW #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 // NOTE: Do not clip on fully shadowed pixels as it would
// cause the hardware occlusion query to disable the shadow. // cause the hardware occlusion query to disable the shadow.
// Specular term // Specular term
float specular = calcSpecular( -lightToPxlVec, float specular = AL_CalcSpecular( -lightToPxlVec,
normal, normal,
normalize( -eyeRay ), normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
constantSpecularPower,
shadowed * atten * lightBrightness );
// N.L * Attenuation float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float Sat_NL_Att = clamp( nDotL * atten * shadowed, 0.0, 1.0 ); vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = vec4(0.0);
// In LUV color mode we need to blend in the // TODO: This needs to be removed when lightmapping is disabled
// output from the previous target. // as its extra work per-pixel on dynamic lit scenes.
vec4 previousPix = vec4(0.0); //
#ifdef ACCUMULATE_LUV // Special lightmapping pass.
previousPix = texture2DLod( scratchTarget, uvScene, 0.0 ); if ( lightMapParams.a < 0.0 )
#endif {
// This disables shadows on the backsides of objects.
shadowed = nDotL < 0.0f ? 1.0f : shadowed;
// Output Sat_NL_Att = 1.0f;
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, shadowed = mix( 1.0f, shadowed, atten );
Sat_NL_Att, lightColorOut = vec3(shadowed);
specular, specular *= lightBrightness;
previousPix ) * lightMapParams; addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
} }

View file

@ -22,40 +22,32 @@
#include "../../../gl/hlslCompat.glsl" #include "../../../gl/hlslCompat.glsl"
#include "shadergen:/autogenConditioners.h" #include "shadergen:/autogenConditioners.h"
#include "farFrustumQuad.glsl"
#include "../../../gl/torque.glsl"
#include "../../../gl/lighting.glsl"
#include "lightingUtils.glsl" #include "lightingUtils.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h" #include "../../shadowMap/shadowMapIO_GLSL.h"
#include "softShadow.glsl"
varying vec2 uv0; in vec4 hpos;
varying vec3 wsEyeRay; in vec2 uv0;
in vec3 wsEyeRay;
uniform sampler2D prePassBuffer; in vec3 vsEyeRay;
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
uniform sampler2D ShadowMap ;
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask ;
uniform vec4 rtParams2;
#endif #endif
uniform sampler2D prePassBuffer;
uniform vec3 lightDirection; uniform vec3 lightDirection;
uniform vec4 lightColor; uniform vec4 lightColor;
uniform float lightBrightness; uniform float lightBrightness;
uniform vec4 lightAmbient; uniform vec4 lightAmbient;
uniform vec4 lightTrilight;
uniform vec3 eyePosWorld; uniform vec3 eyePosWorld;
uniform mat4x4 worldToLightProj;
uniform mat4 worldToLightProj;
uniform vec4 splitDistStart;
uniform vec4 splitDistEnd;
uniform vec4 scaleX; uniform vec4 scaleX;
uniform vec4 scaleY; uniform vec4 scaleY;
uniform vec4 offsetX; uniform vec4 offsetX;
@ -65,15 +57,11 @@ uniform vec4 atlasYOffset;
uniform vec2 atlasScale; uniform vec2 atlasScale;
uniform vec4 zNearFarInvNearFar; uniform vec4 zNearFarInvNearFar;
uniform vec4 lightMapParams; uniform vec4 lightMapParams;
uniform float constantSpecularPower;
uniform vec2 fadeStartLength; uniform vec2 fadeStartLength;
uniform vec4 farPlaneScalePSSM; uniform vec4 farPlaneScalePSSM;
uniform vec4 splitFade;
uniform vec4 overDarkPSSM; uniform vec4 overDarkPSSM;
uniform float shadowSoftness; uniform float shadowSoftness;
void main() void main()
{ {
// Sample/unpack the normal/z data // Sample/unpack the normal/z data
@ -87,144 +75,158 @@ void main()
// Get the light attenuation. // Get the light attenuation.
float dotNL = dot(-lightDirection, normal); float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
vec3 debugColor = vec3(0);
#endif
#ifdef NO_SHADOW #ifdef NO_SHADOW
// Fully unshadowed. // Fully unshadowed.
float shadowed = 1.0; float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = vec3(1.0);
#endif
#else #else
// Compute shadow map coordinate // Compute shadow map coordinate
vec4 pxlPosLightProj = worldToLightProj * worldPos; vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
float distOffset = 0.0; // Distance to light, in shadowmap space
float shadowed = 0.0; float distToLight = pxlPosLightProj.z / pxlPosLightProj.w;
float fadeAmt = 0.0;
vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
// Calculate things dependant on the shadowmap split // Figure out which split to sample from. Basically, we compute the shadowmap sample coord
for ( int i = 0; i < 2; i++ ) // for all of the splits and then check if its valid.
{ vec4 shadowCoordX = vec4( baseShadowCoord.x );
float zDistSplit = zDist.x + distOffset; vec4 shadowCoordY = vec4( baseShadowCoord.y );
vec4 mask0; vec4 farPlaneDists = vec4( distToLight );
mask0.x = float(zDistSplit >= splitDistStart.x); shadowCoordX *= scaleX;
mask0.y = float(zDistSplit >= splitDistStart.y); shadowCoordY *= scaleY;
mask0.z = float(zDistSplit >= splitDistStart.z); shadowCoordX += offsetX;
mask0.w = float(zDistSplit >= splitDistStart.w); shadowCoordY += offsetY;
farPlaneDists *= farPlaneScalePSSM;
vec4 mask1; // If the shadow sample is within -1..1 and the distance
mask1.x = float(zDistSplit < splitDistEnd.x); // to the light for this pixel is less than the far plane
mask1.y = float(zDistSplit < splitDistEnd.y); // of the split, use it.
mask1.z = float(zDistSplit < splitDistEnd.z); vec4 finalMask;
mask1.w = float(zDistSplit < splitDistEnd.w); 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);
vec4 finalMask = mask0 * mask1; 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);
float splitFadeDist = dot( finalMask, splitFade ); 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);
vec2 finalScale; else
finalScale.x = dot(finalMask, scaleX); finalMask = vec4(0, 0, 0, 1);
finalScale.y = dot(finalMask, scaleY);
vec2 finalOffset;
finalOffset.x = dot(finalMask, offsetX);
finalOffset.y = dot(finalMask, offsetY);
vec2 shadowCoord; #ifdef PSSM_DEBUG_RENDER
shadowCoord = baseShadowCoord * finalScale; if ( finalMask.x > 0 )
shadowCoord += finalOffset; 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
// Convert to texcoord space // Here we know what split we're sampling from, so recompute the texcoord location
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); // Yes, we could just use the result from above, but doing it this way actually saves
//shadowCoord.y = 1.0f - shadowCoord.y; // shader instructions.
vec2 finalScale;
finalScale.x = dot(finalMask, scaleX);
finalScale.y = dot(finalMask, scaleY);
// Move around inside of atlas vec2 finalOffset;
vec2 aOffset; finalOffset.x = dot(finalMask, offsetX);
aOffset.x = dot(finalMask, atlasXOffset); finalOffset.y = dot(finalMask, offsetY);
aOffset.y = dot(finalMask, atlasYOffset);
shadowCoord *= atlasScale; vec2 shadowCoord;
shadowCoord += aOffset; shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Distance to light, in shadowmap space // Convert to texcoord space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Each split has a different far plane, take this into account. // Move around inside of atlas
float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); vec2 aOffset;
distToLight *= farPlaneScale; aOffset.x = dot(finalMask, atlasXOffset);
aOffset.y = dot(finalMask, atlasYOffset);
#ifdef SOFTSHADOW_SM3 shadowCoord *= atlasScale;
shadowCoord += aOffset;
float esmShadow = softShadow_filter( ShadowMap, // Each split has a different far plane, take this into account.
gTapRotationTex, float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
uv0.xy, distToLight *= farPlaneScale;
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) );
#else // !SOFTSHADOW_SM3 float shadowed = softShadow_filter( ShadowMap,
uv0.xy,
float occluder = decodeShadowMap( texture2DLod( ShadowMap, shadowCoord, 0.0 ) ); shadowCoord,
float overDark = dot( finalMask, overDarkPSSM ); farPlaneScale * shadowSoftness,
float esmShadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); distToLight,
dotNL,
#endif dot( finalMask, overDarkPSSM ) );
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;
}
// Fade out the shadow at the end of the range. // 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; 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 #endif // !NO_SHADOW
// Calc lighting coefficents // Specular term
float specular = calcSpecular( -lightDirection, float specular = AL_CalcSpecular( -lightDirection,
normal, normal,
normalize(-wsEyeRay), normalize(-vsEyeRay) ) * lightBrightness * shadowed;
constantSpecularPower,
shadowed * lightBrightness );
float Sat_NL_Att = clamp(dotNL, 0.0, 1.0) * shadowed; float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness;
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec4 addToResult = lightAmbient;
// Trilight, described by Tom Forsyth // TODO: This needs to be removed when lightmapping is disabled
// http://home.comcast.net/~tom_forsyth/papers/trilight/trilight.html // as its extra work per-pixel on dynamic lit scenes.
#ifdef ACCUMULATE_LUV //
// Special lightmapping pass.
if ( lightMapParams.a < 0.0 )
{
// This disables shadows on the backsides of objects.
shadowed = dotNL < 0.0f ? 1.0f : shadowed;
// In LUV multiply in the brightness of the light color (normaly done in the attenuate function) Sat_NL_Att = 1.0f;
Sat_NL_Att *= lightColor.a; lightColorOut = vec3(shadowed);
specular *= lightBrightness;
addToResult = ( 1.0 - shadowed ) * abs(lightMapParams);
}
vec4 ambientBlend = lightAmbient; // Sample the AO texture.
ambientBlend.b *= clamp(-dotNL, 0.0, 1.0); #ifdef USE_SSAO_MASK
float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams2 ) ).r;
addToResult *= ao;
#endif
vec3 trilight = lightTrilight.rgb; #ifdef PSSM_DEBUG_RENDER
trilight.b *= clamp(1.0 - abs(dotNL), 0.0, 1.0); lightColorOut = debugColor;
#endif
ambientBlend.rg = mix(ambientBlend.rg, trilight.rg, clamp(0.5 * trilight.b / lightAmbient.b, 0.0, 1.0)); OUT_FragColor0 = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
ambientBlend.b += trilight.b;
#else
// 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);
#endif
// Output
gl_FragColor = lightinfoCondition( lightColor.rgb * lightBrightness, Sat_NL_Att, specular, ambientBlend) * lightMapParams;
} }

View file

@ -20,35 +20,27 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
uniform sampler2D diffuseMap; uniform sampler2D diffuseMap;
varying vec2 uv; in vec2 uv;
uniform vec2 oneOverTargetSize; 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() void main()
{ {
vec2 sNonUniformTaps[8]; vec4 OUT = texture( diffuseMap, uv ) * weight[0];
sNonUniformTaps[0] = vec2(0.992833, 0.979309); for ( int i=1; i < 3; i++ )
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);
gl_FragColor = vec4(0.0);
vec2 texScale = vec2(1.0);
for ( int i=0; i < 4; i++ )
{ {
vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i]; vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
gl_FragColor += texture2D( diffuseMap, uv + offset ); OUT += texture( diffuseMap, uv + _sample ) * weight[i];
OUT += texture( diffuseMap, uv - _sample ) * weight[i];
} }
gl_FragColor /= vec4(4.0); OUT_FragColor0 = OUT;
gl_FragColor.rgb = vec3(0.0);
} }

View file

@ -22,13 +22,16 @@
#include "../../../../../../shaders/common/gl/torque.glsl" #include "../../../../../../shaders/common/gl/torque.glsl"
uniform vec2 oneOverTargetSize; in vec4 vPosition;
in vec2 vTexCoord0;
uniform vec4 rtParams0; uniform vec4 rtParams0;
varying vec2 uv; out vec2 uv;
void main() void main()
{ {
gl_Position = gl_Vertex; gl_Position = vPosition;
uv = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 );
gl_Position.y *= -1; //correct ssp
} }

View file

@ -26,7 +26,7 @@ uniform sampler2D diffuseMap0;
uniform float texSize; uniform float texSize;
uniform vec2 blurDimension; uniform vec2 blurDimension;
varying vec2 tex0; in vec2 tex0;
void main() void main()
{ {
@ -40,8 +40,8 @@ void main()
vec4 accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
for(int i = 0; i < int(blurSamples); i++) for(int i = 0; i < int(blurSamples); i++)
{ {
accum += texture2D(diffuseMap0, BaseTexCoord + float(i) * SampleOffset); accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset);
} }
accum /= blurSamples; accum /= blurSamples;
gl_FragColor = accum; OUT_FragColor0 = accum;
} }

View file

@ -20,12 +20,15 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview; uniform mat4 modelview;
varying vec2 tex0; out vec2 tex0;
void main() void main()
{ {
gl_Position = modelview * gl_Vertex; gl_Position = modelview * vPosition;
tex0 = gl_MultiTexCoord0.st; tex0 = vTexCoord0.st;
} }

View file

@ -22,27 +22,30 @@
#include "./../gl/torque.glsl" #include "./../gl/torque.glsl"
in vec4 vPosition;
in vec2 vTexCoord0;
in vec3 vTexCoord1;
uniform vec4 rtParams0; uniform vec4 rtParams0;
uniform vec4 rtParams1; uniform vec4 rtParams1;
uniform vec4 rtParams2; uniform vec4 rtParams2;
uniform vec4 rtParams3; uniform vec4 rtParams3;
varying vec2 uv0; out vec2 uv0;
varying vec2 uv1; out vec2 uv1;
varying vec2 uv2; out vec2 uv2;
varying vec2 uv3; out vec2 uv3;
varying vec3 wsEyeRay; out vec3 wsEyeRay;
void main() void main()
{ {
gl_Position = gl_Vertex; gl_Position = vPosition;
uv0 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams0 ); uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 );
uv1 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams1 ); uv1 = viewportCoordToRenderTarget( vTexCoord0, rtParams1 );
uv2 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams2 ); uv2 = viewportCoordToRenderTarget( vTexCoord0, rtParams2 );
uv3 = viewportCoordToRenderTarget( gl_MultiTexCoord0.st, rtParams3 ); uv3 = viewportCoordToRenderTarget( vTexCoord0, rtParams3 );
wsEyeRay = gl_MultiTexCoord1.xyz; wsEyeRay = vTexCoord1;
} }

View file

@ -23,8 +23,10 @@
#include "../terrain.glsl" #include "../terrain.glsl"
#include "../../gl/hlslCompat.glsl" #include "../../gl/hlslCompat.glsl"
varying vec2 layerCoord; in vec2 layerCoord;
varying vec2 texCoord; #define IN_layerCoord layerCoord
in vec2 texCoord;
#define IN_texCoord texCoord
uniform sampler2D layerTex; uniform sampler2D layerTex;
uniform sampler2D textureMap; uniform sampler2D textureMap;
@ -33,12 +35,12 @@ uniform float layerSize;
void main() 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) if(blend - 0.0001 < 0.0)
discard; discard;
gl_FragColor = vec4( texture2D( textureMap, texCoord ).rgb, blend ); OUT_FragColor0 = vec4( texture( textureMap, IN_texCoord ).rgb, blend );
} }

View file

@ -23,14 +23,19 @@
/// The vertex shader used in the generation and caching of the /// The vertex shader used in the generation and caching of the
/// base terrain texture. /// base terrain texture.
varying vec2 layerCoord; in vec4 vPosition;
varying vec2 texCoord; in vec2 vTexCoord0;
out vec2 layerCoord;
out vec2 texCoord;
uniform vec2 texScale; uniform vec2 texScale;
void main() void main()
{ {
gl_Position = vec4(gl_Vertex.xyz, 1.0); gl_Position = vec4(vPosition.xyz, 1.0);
layerCoord = gl_MultiTexCoord0.st; layerCoord = vTexCoord0.st;
texCoord = gl_MultiTexCoord0.st * texScale; texCoord = vTexCoord0.st * texScale;
gl_Position.y *= -1;
} }

View file

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

View file

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

View file

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

View file

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