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 sampler2D diffuseMap;
varying vec2 texc0, texc1, texc2, texc3;
in vec2 texc0, texc1, texc2, texc3;
void main()
{
gl_FragColor = texture2D(diffuseMap, texc0) * kernel.x;
gl_FragColor += texture2D(diffuseMap, texc1) * kernel.y;
gl_FragColor += texture2D(diffuseMap, texc2) * kernel.z;
gl_FragColor += texture2D(diffuseMap, texc3) * kernel.w;
OUT_FragColor0 = texture(diffuseMap, texc0) * kernel.x;
OUT_FragColor0 += texture(diffuseMap, texc1) * kernel.y;
OUT_FragColor0 += texture(diffuseMap, texc2) * kernel.z;
OUT_FragColor0 += texture(diffuseMap, texc3) * kernel.w;
}

View file

@ -24,20 +24,25 @@
// Glow shader
//*****************************************************************************
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
uniform mat4 modelview;
uniform vec2 offset0, offset1, offset2, offset3;
varying vec2 texc0, texc1, texc2, texc3;
out vec2 texc0, texc1, texc2, texc3;
void main()
{
gl_Position = modelview * gl_Vertex;
gl_Position = modelview * vPosition;
vec2 tc = gl_MultiTexCoord0.st;
vec2 tc = vTexCoord0.st;
tc.y = 1.0 - tc.y;
texc0 = tc + offset0;
texc1 = tc + offset1;
texc2 = tc + offset2;
texc3 = tc + offset3;
gl_Position.y *= -1;
}

View file

@ -22,12 +22,20 @@
#include "hlslCompat.glsl"
varying vec4 texCoord12;
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized
varying vec3 vViewTS; // view vector in tangent space, denormalized
varying vec3 vNormalWS; // Normal vector in world space
varying float worldDist;
//-----------------------------------------------------------------------------
// Structures
//-----------------------------------------------------------------------------
//ConnectData
in vec4 texCoord12;
#define IN_texCoord12 texCoord12
in vec4 texCoord34;
#define IN_texCoord34 texCoord34
in vec3 vLightTS; // light vector in tangent space, denormalized
#define IN_vLightTS vLightTS
in vec3 vViewTS; // view vector in tangent space, denormalized
#define IN_vViewTS vViewTS
in float worldDist;
#define IN_worldDist worldDist
//-----------------------------------------------------------------------------
// Uniforms
@ -37,6 +45,7 @@ uniform vec3 ambientColor;
uniform vec3 sunColor;
uniform float cloudCoverage;
uniform vec3 cloudBaseColor;
uniform float cloudExposure;
//-----------------------------------------------------------------------------
// Globals
@ -97,26 +106,25 @@ void main()
// Normalize the interpolated vectors:
vec3 vViewTS = normalize( vViewTS );
vec3 vLightTS = normalize( vLightTS );
vec3 vNormalWS = normalize( vNormalWS );
vec4 cResultColor = float4( 0, 0, 0, 1 );
vec4 cResultColor = vec4( 0, 0, 0, 1 );
vec2 texSample = texCoord12.xy;
vec2 texSample = IN_texCoord12.xy;
vec4 noise1 = texture2D( normalHeightMap, texCoord12.zw );
vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw );
noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
//return noise1;
vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy );
vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy );
noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
//return noise2;
vec3 noiseNormal = normalize( noise1 + noise2 ).xyz;
//return float4( noiseNormal, 1.0 );
//return vec4( noiseNormal, 1.0 );
float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 );
vec3 vNormalTS = normalize( texture2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 );
vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 );
vNormalTS += noiseNormal;
vNormalTS = normalize( vNormalTS );
@ -124,16 +132,14 @@ void main()
cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
float coverage = ( cloudCoverage - 0.5 ) * 2.0;
cResultColor.a = texture2D( normalHeightMap, texSample ).a + coverage + noiseHeight;
cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight;
if ( cloudCoverage > -1.0 )
cResultColor.a /= 1.0 + coverage;
cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) );
cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 );
cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(worldDist,2.0) );
cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) );
// If using HDR rendering, make sure to tonemap the resuld color prior to outputting it.
// But since this example isn't doing that, we just output the computed result color here:
gl_FragColor = cResultColor;
OUT_FragColor0 = cResultColor;
}

View file

@ -20,12 +20,24 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec4 texCoord12;
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized
varying vec3 vViewTS; // view vector in tangent space, denormalized
varying vec3 vNormalWS; // Normal vector in world space
varying float worldDist;
#include "hlslCompat.glsl"
in vec4 vPosition;
in vec3 vNormal;
in vec3 vBinormal;
in vec3 vTangent;
in vec2 vTexCoord0;
out vec4 texCoord12;
#define OUT_texCoord12 texCoord12
out vec4 texCoord34;
#define OUT_texCoord34 texCoord34
out vec3 vLightTS; // light vector in tangent space, denormalized
#define OUT_vLightTS vLightTS
out vec3 vViewTS; // view vector in tangent space, denormalized
#define OUT_vViewTS vViewTS
out float worldDist;
#define OUT_worldDist worldDist
//-----------------------------------------------------------------------------
// Uniforms
@ -43,37 +55,37 @@ uniform vec3 texScale;
//-----------------------------------------------------------------------------
void main()
{
vec4 pos = gl_Vertex;
vec3 normal = gl_Normal;
vec3 binormal = gl_MultiTexCoord0.xyz;
vec3 tangent = gl_MultiTexCoord1.xyz;
vec2 uv0 = gl_MultiTexCoord2.st;
vec4 IN_pos = vPosition;
vec3 IN_normal = vNormal;
vec3 IN_binormal = vBinormal;
vec3 IN_tangent = vTangent;
vec2 IN_uv0 = vTexCoord0.st;
gl_Position = modelview * pos;
gl_Position = modelview * IN_pos;
// Offset the uv so we don't have a seam directly over our head.
vec2 uv = uv0 + vec2( 0.5, 0.5 );
vec2 uv = IN_uv0 + vec2( 0.5, 0.5 );
texCoord12.xy = uv * texScale.x;
texCoord12.xy += texOffset0;
OUT_texCoord12.xy = uv * texScale.x;
OUT_texCoord12.xy += texOffset0;
texCoord12.zw = uv * texScale.y;
texCoord12.zw += texOffset1;
OUT_texCoord12.zw = uv * texScale.y;
OUT_texCoord12.zw += texOffset1;
texCoord34.xy = uv * texScale.z;
texCoord34.xy += texOffset2;
OUT_texCoord34.xy = uv * texScale.z;
OUT_texCoord34.xy += texOffset2;
texCoord34.z = pos.z;
texCoord34.w = 0.0;
OUT_texCoord34.z = IN_pos.z;
OUT_texCoord34.w = 0.0;
// Transform the normal, tangent and binormal vectors from object space to
// homogeneous projection space:
vNormalWS = -normal;
vec3 vTangentWS = -tangent;
vec3 vBinormalWS = -binormal;
vec3 vNormalWS = -IN_normal;
vec3 vTangentWS = -IN_tangent;
vec3 vBinormalWS = -IN_binormal;
// Compute position in world space:
vec4 vPositionWS = pos + vec4( eyePosWorld, 1 ); //mul( pos, objTrans );
vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans );
// Compute and output the world view vector (unnormalized):
vec3 vViewWS = eyePosWorld - vPositionWS.xyz;
@ -81,12 +93,14 @@ void main()
// Compute denormalized light vector in world space:
vec3 vLightWS = -sunVec;
// Normalize the light and view vectors and transform it to the tangent space:
// Normalize the light and view vectors and transform it to the IN_tangent space:
mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS );
// Propagate the view and the light vectors (in tangent space):
vLightTS = mWorldToTangent * vLightWS;
vViewTS = vViewWS * mWorldToTangent;
worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 );
OUT_vLightTS = vLightWS * mWorldToTangent;
OUT_vViewTS = mWorldToTangent * vViewWS;
OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 );
correctSSP(gl_Position);
}

View file

@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo;
uniform vec2 gc_turbInfo;
//static float sMovableCorner[4] = { 0.0, 0.0, 1.0, 1.0 };
const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 );
const float sCornerUp[4] = float[]( 0, 0, 1, 1 );
const float sMovableCorner[4] = float[]( 0, 0, 1, 1 );
const vec2 sUVCornerExtent[4] = vec2[]
(
vec2( 0, 1 ),
vec2( 1, 1 ),
vec2( 1, 0 ),
vec2( 0, 0 )
);
///////////////////////////////////////////////////////////////////////////////
@ -106,34 +118,13 @@ vec2 windEffect( float bbPhase,
void foliageProcessVert( inout vec3 position,
inout vec4 diffuse,
in vec4 texCoord,
out vec2 outTexCoord,
inout vec4 texCoord,
inout vec3 normal,
inout vec3 T,
in vec3 eyePos )
{
float sCornerRight[4];
sCornerRight[0] = -0.5;
sCornerRight[1] = 0.5;
sCornerRight[2] = 0.5;
sCornerRight[3] = -0.5;
float sCornerUp[4];
sCornerUp[0] = 0.0;
sCornerUp[1] = 0.0;
sCornerUp[2] = 1.0;
sCornerUp[3] = 1.0;
vec2 sUVCornerExtent[4];
sUVCornerExtent[0] = vec2( 0.0, 1.0 );
sUVCornerExtent[1] = vec2( 1.0, 1.0 );
sUVCornerExtent[2] = vec2( 1.0, 0.0 );
sUVCornerExtent[3] = vec2( 0.0, 0.0 );
// Assign the normal and tagent values.
//normal = cross( gc_camUp, gc_camRight );
//normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight );
T = gc_camRight;
// Pull out local vars we need for work.
@ -172,8 +163,8 @@ void foliageProcessVert( inout vec3 position,
// Grab the uv set and setup the texture coord.
vec4 uvSet = gc_typeRects[type];
outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
// Animate the normal to get lighting changes
// across the the wind swept foliage.
@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position,
normal.xy += wind.xy * ( 10.0 * texCoord.w );
normal = normalize( normal );
// Get the alpha fade value.
float fadeStart = gc_fadeParams.x;

View file

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

View file

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

View file

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

View file

@ -27,17 +27,79 @@
#define float3 vec3
#define float2 vec2
#define texCUBE textureCube
#define tex2D texture2D
#define half float
#define half2 vec2
#define half3 vec3
#define half4 vec4
#define float4x4 mat4
#define float3x3 mat3
#define float2x2 mat2
#define texCUBE texture
#define tex2D texture
#define tex1D texture
#define tex2Dproj textureProj
#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w)
#define samplerCUBE samplerCube
#define frac fract
#define lerp mix
float saturate( float val ) { return clamp( val, 0.0, 1.0 ); }
vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); }
vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); }
vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); }
void tSetMatrixRow(out float3x3 m, int row, float3 value)
{
m[0][row] = value.x;
m[1][row] = value.y;
m[2][row] = value.z;
}
float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
void tSetMatrixRow(out float4x4 m, int row, float4 value)
{
m[0][row] = value.x;
m[1][row] = value.y;
m[2][row] = value.z;
m[3][row] = value.w;
}
#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row])
#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row])
float3x3 float4x4to3x3(float4x4 m)
{
return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz);
}
float3x3 float4x4to3x3_(float4x4 m)
{
return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz);
}
mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3,
float r1c0, float r1c1, float r1c2, float r1c3,
float r2c0, float r2c1, float r2c2, float r2c3,
float r3c0, float r3c1, float r3c2, float r3c3 )
{
return mat4( r0c0, r1c0, r2c0, r3c0,
r0c1, r1c1, r2c1, r3c1,
r0c2, r1c2, r2c2, r3c2,
r0c3, r1c3, r2c3, r3c3 );
}
#define saturate( val ) clamp( val, 0.0, 1.0 )
#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 ))
#define tMul(a, b) (a*b)
#define inversesqrt( n ) inversesqrt( n )
#define correctSSP(vec) vec.y *= -1
#ifdef TORQUE_PIXEL_SHADER
void clip(float a) { if(a < 0) discard;}
out vec4 OUT_FragColor0;
#endif

View file

@ -20,73 +20,181 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef TORQUE_SHADERGEN
// These are the uniforms used by most lighting shaders.
uniform vec3 inLightPos[4];
uniform vec4 inLightPos[3];
uniform vec4 inLightInvRadiusSq;
uniform vec4 inLightColor[4];
#ifndef TORQUE_BL_NOSPOTLIGHT
uniform vec4 inLightSpotDir[3];
uniform vec4 inLightSpotAngle;
uniform vec4 inLightSpotFalloff;
#endif
uniform vec4 ambient;
uniform float specularPower;
uniform vec4 specularColor;
// This is used to limit the maximum processed
// lights in the compute4Lights down for really
// low end GPUs.
//
// NOTE: If you want to support 10.5.x, this needs to be changed to 2.
#define C4L_MAX_LIGHTS 4
#endif // !TORQUE_SHADERGEN
void compute4Lights( vec3 wsView,
vec3 wsPosition,
vec3 wsNormal,
vec3 wsNormal,
vec4 shadowMask,
#ifdef TORQUE_SHADERGEN
vec4 inLightPos[3],
vec4 inLightInvRadiusSq,
vec4 inLightColor[4],
vec4 inLightSpotDir[3],
vec4 inLightSpotAngle,
vec4 inLightSpotFalloff,
float specularPower,
vec4 specularColor,
#endif // TORQUE_SHADERGEN
out vec4 outDiffuse,
out vec4 outSpecular )
{
#ifdef PHONG_SPECULAR
// (R.V)^c
float reflected = reflect( wsView, wsNormal );
#endif
vec4 nDotL = vec4( 0.0 );
vec4 rDotL = vec4( 0.0 );
vec4 sqDists = vec4( 0.0 );
// NOTE: The light positions and spotlight directions
// are stored in SoA order, so inLightPos[0] is the
// x coord for all 4 lights... inLightPos[1] is y... etc.
//
// This is the key to fully utilizing the vector units and
// saving a huge amount of instructions.
//
// For example this change saved more than 10 instructions
// over a simple for loop for each light.
int i;
for ( i = 0; i < C4L_MAX_LIGHTS; ++i )
{
vec3 lightVector = inLightPos[i] - wsPosition;
vec3 lightDirection = normalize( lightVector );
vec4 lightVectors[3];
for ( i = 0; i < 3; i++ )
lightVectors[i] = wsPosition[i] - inLightPos[i];
nDotL[i] = max( dot( lightDirection, wsNormal ), 0.0 );
vec4 squareDists = vec4(0);
for ( i = 0; i < 3; i++ )
squareDists += lightVectors[i] * lightVectors[i];
#ifdef PHONG_SPECULAR
rDotL[i] = saturate( dot( lightDirection, reflected ) );
#else
// (N.H)^c [Blinn-Phong, TGEA style, default]
rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) );
#endif
// Accumulate the dot product between the light
// vector and the normal.
//
// The normal is negated because it faces away from
// the surface and the light faces towards the
// surface... this keeps us from needing to flip
// the light vector direction which complicates
// the spot light calculations.
//
// We normalize the result a little later.
//
vec4 nDotL = vec4(0);
for ( i = 0; i < 3; i++ )
nDotL += lightVectors[i] * -wsNormal[i];
sqDists[i] = dot( lightVector, lightVector );
}
vec4 rDotL = vec4(0);
#ifndef TORQUE_BL_NOSPECULAR
// Attenuation
vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq );
// We're using the Phong specular reflection model
// here where traditionally Torque has used Blinn-Phong
// which has proven to be more accurate to real materials.
//
// We do so because its cheaper as do not need to
// calculate the half angle for all 4 lights.
//
// Advanced Lighting still uses Blinn-Phong, but the
// specular reconstruction it does looks fairly similar
// to this.
//
vec3 R = reflect( wsView, -wsNormal );
for ( i = 0; i < 3; i++ )
rDotL += lightVectors[i] * R[i];
#endif
// Normalize the dots.
//
// Notice we're using the half type here to get a
// much faster sqrt via the rsq_pp instruction at
// the loss of some precision.
//
// Unless we have some extremely large point lights
// i don't believe the precision loss will matter.
//
half4 correction = half4(inversesqrt( squareDists ));
nDotL = saturate( nDotL * correction );
rDotL = clamp( rDotL * correction, 0.00001, 1.0 );
// First calculate a simple point light linear
// attenuation factor.
//
// If this is a directional light the inverse
// radius should be greater than the distance
// causing the attenuation to have no affect.
//
vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) );
#ifndef TORQUE_BL_NOSPOTLIGHT
// The spotlight attenuation factor. This is really
// fast for what it does... 6 instructions for 4 spots.
vec4 spotAtten = vec4(0);
for ( i = 0; i < 3; i++ )
spotAtten += lightVectors[i] * inLightSpotDir[i];
vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle;
atten *= saturate( cosAngle * inLightSpotFalloff );
#endif
// Finally apply the shadow masking on the attenuation.
atten *= shadowMask;
// Get the final light intensity.
vec4 intensity = nDotL * atten;
// Combine the light colors for output.
vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) );
outDiffuse = vec4( 0.0 );
for ( i = 0; i < C4L_MAX_LIGHTS; ++i )
outDiffuse += vec4( diffuse[i] ) * inLightColor[i];
outDiffuse = vec4(0);
for ( i = 0; i < 4; i++ )
outDiffuse += intensity[i] * inLightColor[i];
// Output the specular power.
rDotL = max( rDotL, vec4( 0.00001 ) );
outSpecular = pow( rDotL, vec4( specularPower ) );
vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten;
// Apply the per-light specular attenuation.
vec4 specular = vec4(0,0,0,1);
for ( i = 0; i < 4; i++ )
specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 );
// Add the final specular intensity values together
// using a single dot product operation then get the
// final specular lighting color.
outSpecular = specularColor * specular;
}
/// The standard specular calculation.
// This value is used in AL as a constant power to raise specular values
// to, before storing them into the light info buffer. The per-material
// specular value is then computer by using the integer identity of
// exponentiation:
//
// (a^m)^n = a^(m*n)
//
// or
//
// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular)
//
#define AL_ConstantSpecularPower 12.0f
/// The specular calculation used in Advanced Lighting.
///
/// @param toLight Normalized vector representing direction from the pixel
/// being lit, to the light source, in world space.
@ -96,11 +204,7 @@ void compute4Lights( vec3 wsView,
/// @param toEye The normalized vector representing direction from the pixel
/// being lit to the camera.
///
/// @param specPwr The specular exponent.
///
/// @param specScale A scalar on the specular output used in RGB accumulation.
///
float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye )
{
#ifdef PHONG_SPECULAR
// (R.V)^c
@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
#endif
// Return the specular factor.
return pow( max( specVal, 0.00001f ), specPwr );
return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
}

View file

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

View file

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

View file

@ -20,63 +20,92 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "hlslCompat.glsl"
#include "torque.glsl"
#include "hlslCompat.glsl"
// With advanced lighting we get soft particles.
#ifdef TORQUE_LINEAR_DEPTH
#define SOFTPARTICLES
#endif
#define CLIP_Z // TODO: Make this a proper macro
uniform sampler2D diffuseMap;
#ifdef SOFTPARTICLES
#include "shadergen:/autogenConditioners.h"
uniform float oneOverSoftness;
uniform float oneOverFar;
uniform sampler2D prepassTex;
uniform sampler2D prepassTex;
//uniform vec3 vEye;
uniform vec4 prePassTargetParams;
#endif
#define CLIP_Z // TODO: Make this a proper macro
in vec4 color;
in vec2 uv0;
in vec4 pos;
#define IN_color color
#define IN_uv0 uv0
#define IN_pos pos
uniform sampler2D diffuseMap;
uniform sampler2D paraboloidLightMap;
vec4 lmSample( vec3 nrm )
{
bool calcBack = (nrm.z < 0.0);
if ( calcBack )
nrm.z = nrm.z * -1.0;
vec2 lmCoord;
lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5;
lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5);
// If this is the back, offset in the atlas
if ( calcBack )
lmCoord.x += 1.0;
// Atlasing front and back maps, so scale
lmCoord.x *= 0.5;
return texture(paraboloidLightMap, lmCoord);
}
uniform float alphaFactor;
uniform float alphaScale;
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
void main()
{
float softBlend = 1.0;
float softBlend = 1;
#ifdef SOFTPARTICLES
float2 tc = pos.xy * vec2(1.0, -1.0 ) / pos.w;
vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w;
tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams);
float sceneDepth = prepassUncondition( prepassTex, tc ).w;
float depth = pos.w * oneOverFar;
float diff = sceneDepth - depth;
float depth = IN_pos.w * oneOverFar;
float diff = sceneDepth - depth;
#ifdef CLIP_Z
// If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer
// When drawing high-res, though, we want to be able to take advantage of hi-z
// so this is #ifdef'd out
if (diff < 0.0)
discard;
//clip(diff);
#endif
softBlend = saturate( diff * oneOverSoftness );
#endif
vec4 diffuse = texture2D( diffuseMap, uv0 );
vec4 diffuse = texture( diffuseMap, IN_uv0 );
//OUT_FragColor0 = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale);
// Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha)
vec3 colorScale = ( alphaFactor < 0.0 ? color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? vec3(color.a * alphaFactor * diffuse.a * softBlend) : vec3(softBlend) ) );
vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) );
gl_FragColor = hdrEncode( vec4(color.rgb * diffuse.rgb * colorScale, softBlend * color.a * diffuse.a * alphaScale) );
OUT_FragColor0 = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale,
IN_color.a * diffuse.a * softBlend * alphaScale ) );
}

View file

@ -20,18 +20,35 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
#include "hlslCompat.glsl"
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
#define In_pos vPosition
#define In_color vColor
#define In_uv0 vTexCoord0
out vec4 color;
out vec2 uv0;
out vec4 pos;
#define OUT_hpos gl_Position
#define OUT_color color
#define OUT_uv0 uv0
#define OUT_pos pos
uniform mat4 modelViewProj;
uniform mat4 fsModelViewProj;
void main()
{
gl_Position = modelViewProj * gl_Vertex;
pos = fsModelViewProj * gl_Vertex;
color = gl_Color;
uv0 = gl_MultiTexCoord0.st;
OUT_hpos = tMul( modelViewProj, In_pos );
OUT_pos = tMul( fsModelViewProj, In_pos );
OUT_color = In_color;
OUT_uv0 = In_uv0;
correctSSP(gl_Position);
}

View file

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

View file

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

View file

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

View file

@ -23,10 +23,13 @@
//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview;
varying vec2 TEX0;
varying vec4 TEX1;
out vec2 TEX0;
out vec4 TEX1;
//-----------------------------------------------------------------------------
// Main
@ -38,9 +41,9 @@ void main()
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
gl_Position = modelview * gl_Vertex;
gl_Position = modelview * vPosition;
TEX0 = gl_MultiTexCoord0.st;
TEX0 = vTexCoord0;
TEX1 = texGenTest * gl_Position;
TEX1.y = -TEX1.y;

View file

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

View file

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

View file

@ -20,9 +20,11 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec2 texCoord;
varying vec4 color;
varying float fade;
in vec2 texCoord;
in vec4 color;
in float fade;
out vec4 OUT_FragColor0;
uniform sampler2D inputTex;
uniform vec4 ambient;
@ -30,17 +32,6 @@ uniform vec4 ambient;
void main()
{
vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f);
float esmFactor = 200.0;
float lum = dot( ambient.rgb, LUMINANCE_VECTOR );
gl_FragColor.rgb = ambient.rgb * lum;
gl_FragColor.a = 0.0;
float depth = texture2D(inputTex, texCoord).a;
depth = depth * exp(depth - 10.0);
depth = exp(esmFactor * depth) - 1.0;
gl_FragColor.a = clamp(depth * 300.0, 0.0, 1.0) * (1.0 - lum) * fade * color.a;
float shadow = texture( inputTex, texCoord ).a * color.a;
OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow );
}

View file

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

View file

@ -21,36 +21,32 @@
//-----------------------------------------------------------------------------
#include "torque.glsl"
#include "hlslCompat.glsl"
// Calculates the Mie phase function
float getMiePhase(float fCos, float fCos2, float g, float g2)
{
return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
}
// Calculates the Rayleigh phase function
float getRayleighPhase(float fCos2)
{
//return 1.0;
return 0.75 + 0.75*fCos2;
}
// Conn
in vec4 rayleighColor;
#define IN_rayleighColor rayleighColor
in vec4 mieColor;
#define IN_mieColor mieColor
in vec3 v3Direction;
#define IN_v3Direction v3Direction
in float zPosition;
#define IN_zPosition zPosition
in vec3 pos;
#define IN_pos pos
varying vec4 rayleighColor;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
uniform samplerCube nightSky;
uniform samplerCube nightSky ;
uniform vec4 nightColor;
uniform vec2 nightInterpAndExposure;
uniform float useCubemap;
uniform vec3 lightDir;
uniform vec3 sunDir;
void main()
void main()
{
float fCos = dot( lightDir, v3Direction ) / length(v3Direction);
float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction);
float fCos2 = fCos*fCos;
float g = -0.991;
@ -58,15 +54,15 @@ void main()
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
vec4 color = rayleighColor + fMiePhase * mieColor;
vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor;
color.a = color.b;
vec4 nightSkyColor = textureCube(nightSky, -v3Direction);
vec4 nightSkyColor = texture(nightSky, -v3Direction);
nightSkyColor = mix(nightColor, nightSkyColor, useCubemap);
float fac = dot( normalize( pos ), sunDir );
fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) );
gl_FragColor = mix( color, nightSkyColor, nightInterpAndExposure.y );
OUT_FragColor0 = mix( color, nightSkyColor, nightInterpAndExposure.y );
// Clip based on the camera-relative
// z position of the vertex, passed through
@ -74,6 +70,6 @@ void main()
if(zPosition < 0.0)
discard;
gl_FragColor.a = 1;
gl_FragColor = hdrEncode( gl_FragColor );
OUT_FragColor0.a = 1;
OUT_FragColor0 = hdrEncode( OUT_FragColor0 );
}

View file

@ -20,12 +20,7 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
const int nSamples = 4;
const float fSamples = 4.0;
// The scale depth (the altitude at which the average atmospheric density is found)
const float fScaleDepth = 0.25;
const float fInvScaleDepth = 1.0 / 0.25;
#include "hlslCompat.glsl"
// The scale equation calculated by Vernier's Graphical Analysis
float vernierScale(float fCos)
@ -40,12 +35,27 @@ float vernierScale(float fCos)
return 0.25 * outx;
}
in vec4 vPosition;
in vec3 vNormal;
in vec4 vColor;
in vec2 vTexCoord0;
// This is the shader input vertex structure.
#define IN_position vPosition
#define IN_normal vNormal
#define IN_color vColor
// This is the shader output data.
varying vec4 rayleighColor;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
out vec4 rayleighColor;
#define OUT_rayleighColor rayleighColor
out vec4 mieColor;
#define OUT_mieColor mieColor
out vec3 v3Direction;
#define OUT_v3Direction v3Direction
out float zPosition;
#define OUT_zPosition zPosition
out vec3 pos;
#define OUT_pos pos
uniform mat4 modelView;
uniform vec4 misc;
@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs;
uniform vec3 camPos;
uniform vec3 lightDir;
uniform vec4 invWaveLength;
void main()
{
vec4 position = gl_Vertex.xyzw;
vec3 normal = gl_Normal.xyz;
vec4 color = gl_MultiTexCoord0.xyzw;
uniform vec4 colorize;
vec3 desaturate(const vec3 color, const float desaturation)
{
const vec3 gray_conv = vec3 (0.30, 0.59, 0.11);
return mix(color, vec3(dot(gray_conv , color)), desaturation);
}
void main()
{
// Pull some variables out:
float camHeight = misc.x;
float camHeightSqr = misc.y;
@ -83,7 +96,7 @@ void main()
// Get the ray from the camera to the vertex,
// and its length (which is the far point of the ray
// passing through the atmosphere).
vec3 v3Pos = position.xyz / 6378000.0;// / outerRadius;
vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius;
vec3 newCamPos = vec3( 0, 0, camHeight );
v3Pos.z += innerRadius;
vec3 v3Ray = v3Pos.xyz - newCamPos;
@ -97,16 +110,7 @@ void main()
float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
float x = 1.0 - fStartAngle;
float x5 = x * 5.25;
float x5p6 = (-6.80 + x5);
float xnew = (3.83 + x * x5p6);
float xfinal = (0.459 + x * xnew);
float xfinal2 = -0.00287 + x * xfinal;
float othx = exp( xfinal2 );
float vscale1 = 0.25 * othx;
float fStartOffset = fDepth * vscale1;//vernierScale(fStartAngle);
float fStartOffset = fDepth * vernierScale( fStartAngle );
// Initialize the scattering loop variables.
float fSampleLength = fFar / 2.0;
@ -123,24 +127,8 @@ void main()
float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
x = 1.0 - fCameraAngle;
x5 = x * 5.25;
x5p6 = (-6.80 + x5);
xnew = (3.83 + x * x5p6);
xfinal = (0.459 + x * xnew);
xfinal2 = -0.00287 + x * xfinal;
othx = exp( xfinal2 );
float vscale3 = 0.25 * othx;
x = 1.0 - fLightAngle;
x5 = x * 5.25;
x5p6 = (-6.80 + x5);
xnew = (3.83 + x * x5p6);
xfinal = (0.459 + x * xnew);
xfinal2 = -0.00287 + x * xfinal;
othx = exp( xfinal2 );
float vscale2 = 0.25 * othx;
float vscale3 = vernierScale( fCameraAngle );
float vscale2 = vernierScale( fLightAngle );
float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
@ -150,16 +138,24 @@ void main()
// Finally, scale the Mie and Rayleigh colors
// and set up the varying variables for the pixel shader.
gl_Position = modelView * position;
mieColor.rgb = v3FrontColor * mieBrightness;
mieColor.a = 1.0;
rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
rayleighColor.a = 1.0;
v3Direction = newCamPos - v3Pos.xyz;
gl_Position = modelView * IN_position;
OUT_mieColor.rgb = v3FrontColor * mieBrightness;
OUT_mieColor.a = 1.0;
OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
OUT_rayleighColor.a = 1.0;
OUT_v3Direction = newCamPos - v3Pos.xyz;
OUT_pos = IN_position.xyz;
// This offset is to get rid of the black line between the atmosky and the waterPlane
// along the horizon.
zPosition = position.z + 4000.0;
pos = position.xyz;
#ifdef USE_COLORIZE
OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a;
OUT_rayleighColor.r *= colorize.r;
OUT_rayleighColor.g *= colorize.g;
OUT_rayleighColor.b *= colorize.b;
#endif
correctSSP(gl_Position);
}

View file

@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat )
return mat;
}
/// The number of additional substeps we take when refining
/// the results of the offset parallax mapping function below.
///
@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat )
/// Performs fast parallax offset mapping using
/// multiple refinement steps.
////// @param texMap The texture map whos alpha channel we sample the parallax depth.
///
/// @param texMap The texture map whos alpha channel we sample the parallax depth.
/// @param texCoord The incoming texture coordinate for sampling the parallax depth.
/// @param negViewTS The negative view vector in tangent space.
/// @param depthScale The parallax factor used to scale the depth result.
///
vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale )
{
float depth = texture2D( texMap, texCoord ).a;
float depth = texture( texMap, texCoord ).a;
vec2 offset = negViewTS.xy * ( depth * depthScale );
for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ )
{
depth = ( depth + texture2D( texMap, texCoord + offset ).a ) * 0.5;
depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5;
offset = negViewTS.xy * ( depth * depthScale );
}
@ -151,59 +153,61 @@ vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float dept
/// The maximum value for 16bit per component integer HDR encoding.
const float HDR_RGB16_MAX = 100.0;
/// The maximum value for 10bit per component integer HDR encoding.const float HDR_RGB10_MAX = 4.0;
/// The maximum value for 10bit per component integer HDR encoding.
const float HDR_RGB10_MAX = 4.0;
/// Encodes an HDR color for storage into a target.
vec3 hdrEncode( vec3 sample ){
vec3 hdrEncode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 )
return sample / HDR_RGB16_MAX;
return _sample / HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 )
return sample / HDR_RGB10_MAX;
return _sample / HDR_RGB10_MAX;
#else
// No encoding.
return sample;
return _sample;
#endif
}
/// Encodes an HDR color for storage into a target.
vec4 hdrEncode( vec4 sample )
vec4 hdrEncode( vec4 _sample )
{
return vec4( hdrEncode( sample.rgb ), sample.a );
return vec4( hdrEncode( _sample.rgb ), _sample.a );
}
/// Decodes an HDR color from a target.
vec3 hdrDecode( vec3 sample )
vec3 hdrDecode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 )
return sample * HDR_RGB16_MAX;
return _sample * HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 )
return sample * HDR_RGB10_MAX;
return _sample * HDR_RGB10_MAX;
#else
// No encoding.
return sample;
return _sample;
#endif
}
/// Decodes an HDR color from a target.
vec4 hdrDecode( vec4 sample )
vec4 hdrDecode( vec4 _sample )
{
return vec4( hdrDecode( sample.rgb ), sample.a );
return vec4( hdrDecode( _sample.rgb ), _sample.a );
}
/// Returns the luminance for an HDR pixel.
float hdrLuminance( vec3 sample )
float hdrLuminance( vec3 _sample )
{
// There are quite a few different ways to
// calculate luminance from an rgb value.
@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample )
//
// Max component luminance.
//
//float lum = max( sample.r, max( sample.g, sample.b ) );
//float lum = max( _sample.r, max( _sample.g, _sample.b ) );
////////////////////////////////////////////////////////////////////////////
// The perceptual relative luminance.
@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample )
// See http://en.wikipedia.org/wiki/Luminance_(relative)
//
const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 );
float lum = dot( sample, RELATIVE_LUMINANCE );
float lum = dot( _sample, RELATIVE_LUMINANCE );
////////////////////////////////////////////////////////////////////////////
//
// The average component luminance.
//
//const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 );
//float lum = dot( sample, AVERAGE_LUMINANCE );
//float lum = dot( _sample, AVERAGE_LUMINANCE );
return lum;
}
#ifdef TORQUE_PIXEL_SHADER
/// Called from the visibility feature to do screen
/// door transparency for fading of objects.
void fizzle(vec2 vpos, float visibility)
{
// NOTE: The magic values below are what give us
// the nice even pattern during the fizzle.
//
// These values can be changed to get different
// patterns... some better than others.
//
// Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 }
// Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 }
//
// I'm sure there are many more patterns here to
// discover for different effects.
mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 );
if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard;
discard;
}
#endif //TORQUE_PIXEL_SHADER
/// Basic assert macro. If the condition fails, then the shader will output color.
/// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail.
/// @param color The color that should be outputted if the condition fails.
/// @note This macro will only work in the void main() method of a pixel shader.
#define assert(condition, color) { if(!any(condition)) { gl_FragColor = color; return; } }
#define assert(condition, color) { if(!any(condition)) { OUT_FragColor0 = color; return; } }
#endif // _TORQUE_GLSL_

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,113 +19,141 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#define NUM_TAPS 12
#define NUM_PRE_TAPS 4
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS];
void initNonUniformTaps()
#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
#define NUM_PRE_TAPS 4
#define NUM_TAPS 12
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS] = vec2[]
(
// These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed
// or unshadowed areas.
vec2( 0.992833, 0.979309 ),
vec2( -0.998585, 0.985853 ),
vec2( 0.949299, -0.882562 ),
vec2( -0.941358, -0.893924 ),
// The rest of the samples.
vec2( 0.545055, -0.589072 ),
vec2( 0.346526, 0.385821 ),
vec2( -0.260183, 0.334412 ),
vec2( 0.248676, -0.679605 ),
vec2( -0.569502, -0.390637 ),
vec2( -0.614096, 0.212577 ),
vec2( -0.259178, 0.876272 ),
vec2( 0.649526, 0.864333 )
);
#else
#define NUM_PRE_TAPS 5
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[]
(
vec2( 0.892833, 0.959309 ),
vec2( -0.941358, -0.873924 ),
vec2( -0.260183, 0.334412 ),
vec2( 0.348676, -0.679605 ),
vec2( -0.569502, -0.390637 )
);
#endif
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex ;
float softShadow_sampleTaps( sampler2D shadowMap,
vec2 sinCos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float esmFactor,
int startTap,
int endTap )
{
// These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed
// or unshadowed areas.
sNonUniformTaps[0] = vec2( 0.992833, 0.979309 );
sNonUniformTaps[1] = vec2( -0.998585, 0.985853 );
sNonUniformTaps[2] = vec2( 0.949299, -0.882562 );
sNonUniformTaps[3] = vec2( -0.941358, -0.893924 );
// The rest of the samples.
sNonUniformTaps[4] = vec2( 0.545055, -0.589072 );
sNonUniformTaps[5] = vec2( 0.346526, 0.385821 );
sNonUniformTaps[6] = vec2( -0.260183, 0.334412 );
sNonUniformTaps[7] = vec2( 0.248676, -0.679605 );
sNonUniformTaps[8] = vec2( -0.569502, -0.390637 );
sNonUniformTaps[9] = vec2( -0.014096, 0.012577 );
sNonUniformTaps[10] = vec2( -0.259178, 0.876272 );
sNonUniformTaps[11] = vec2( 0.649526, 0.664333 );
float shadow = 0;
vec2 tap = vec2(0);
for ( int t = startTap; t < endTap; t++ )
{
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r;
float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
shadow += esm / float( endTap - startTap );
}
return shadow;
}
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex;
float softShadow_sampleTaps( sampler2D shadowMap,
vec2 sinCos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float esmFactor,
int startTap,
int endTap )
{
initNonUniformTaps();
float shadow = 0.0;
vec2 tap = vec2(0.0);
for ( int t = startTap; t < endTap; t++ )
{
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r;
float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 );
shadow += esm / float( endTap - startTap );
}
return shadow;
}
// HACK! HACK! HACK!
// We take the noise texture directly as the second parameter to ensure that it
// is the "last used" sampler, and thus doesn't collide with the prepass buffer
// or shadow map. If we use gTapRotationTex directly here, then it is the first
// used sampler and will collide with the prepass buffer.
float softShadow_filter( sampler2D shadowMap,
sampler2D noiseTexture,
vec2 vpos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float dotNL,
float esmFactor )
{
// Lookup the random rotation for this screen pixel.
vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0;
// Do the prediction taps first.
float shadow = softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// Only do the expensive filtering if we're really
// in a partially shadowed area.
if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0.0 ) > 0.06 )
{
shadow += softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
NUM_PRE_TAPS,
NUM_TAPS );
// This averages the taps above with the results
// of the prediction samples.
shadow *= 0.5;
}
return shadow;
}
float softShadow_filter( sampler2D shadowMap,
vec2 vpos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float dotNL,
float esmFactor )
{
#ifndef SOFTSHADOW
// If softshadow is undefined then we skip any complex
// filtering... just do a single sample ESM.
float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r;
float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
#else
// Lookup the random rotation for this screen pixel.
vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2;
// Do the prediction taps first.
float shadow = softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// We live with only the pretap results if we don't
// have high quality shadow filtering enabled.
#ifdef SOFTSHADOW_HIGH_QUALITY
// Only do the expensive filtering if we're really
// in a partially shadowed area.
if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 )
{
shadow += softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
NUM_PRE_TAPS,
NUM_TAPS );
// This averages the taps above with the results
// of the prediction samples.
shadow *= 0.5;
}
#endif // SOFTSHADOW_HIGH_QUALITY
#endif // SOFTSHADOW
return shadow;
}

View file

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

View file

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

View file

@ -20,35 +20,27 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
uniform sampler2D diffuseMap;
varying vec2 uv;
in vec2 uv;
uniform vec2 oneOverTargetSize;
const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );
const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );
void main()
{
vec2 sNonUniformTaps[8];
sNonUniformTaps[0] = vec2(0.992833, 0.979309);
sNonUniformTaps[1] = vec2(-0.998585, 0.985853);
sNonUniformTaps[2] = vec2(0.949299, -0.882562);
sNonUniformTaps[3] = vec2(-0.941358, -0.893924);
sNonUniformTaps[4] = vec2(0.545055, -0.589072);
sNonUniformTaps[5] = vec2(0.346526, 0.385821);
sNonUniformTaps[6] = vec2(-0.260183, 0.334412);
sNonUniformTaps[7] = vec2(0.248676, -0.679605);
vec4 OUT = texture( diffuseMap, uv ) * weight[0];
gl_FragColor = vec4(0.0);
vec2 texScale = vec2(1.0);
for ( int i=0; i < 4; i++ )
for ( int i=1; i < 3; i++ )
{
vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i];
gl_FragColor += texture2D( diffuseMap, uv + offset );
vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
OUT += texture( diffuseMap, uv + _sample ) * weight[i];
OUT += texture( diffuseMap, uv - _sample ) * weight[i];
}
gl_FragColor /= vec4(4.0);
gl_FragColor.rgb = vec3(0.0);
OUT_FragColor0 = OUT;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,20 +24,25 @@
// Glow shader
//*****************************************************************************
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
uniform mat4 modelview;
uniform vec2 offset0, offset1, offset2, offset3;
varying vec2 texc0, texc1, texc2, texc3;
out vec2 texc0, texc1, texc2, texc3;
void main()
{
gl_Position = modelview * gl_Vertex;
gl_Position = modelview * vPosition;
vec2 tc = gl_MultiTexCoord0.st;
vec2 tc = vTexCoord0.st;
tc.y = 1.0 - tc.y;
texc0 = tc + offset0;
texc1 = tc + offset1;
texc2 = tc + offset2;
texc3 = tc + offset3;
gl_Position.y *= -1;
}

View file

@ -22,12 +22,20 @@
#include "hlslCompat.glsl"
varying vec4 texCoord12;
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized
varying vec3 vViewTS; // view vector in tangent space, denormalized
varying vec3 vNormalWS; // Normal vector in world space
varying float worldDist;
//-----------------------------------------------------------------------------
// Structures
//-----------------------------------------------------------------------------
//ConnectData
in vec4 texCoord12;
#define IN_texCoord12 texCoord12
in vec4 texCoord34;
#define IN_texCoord34 texCoord34
in vec3 vLightTS; // light vector in tangent space, denormalized
#define IN_vLightTS vLightTS
in vec3 vViewTS; // view vector in tangent space, denormalized
#define IN_vViewTS vViewTS
in float worldDist;
#define IN_worldDist worldDist
//-----------------------------------------------------------------------------
// Uniforms
@ -37,6 +45,7 @@ uniform vec3 ambientColor;
uniform vec3 sunColor;
uniform float cloudCoverage;
uniform vec3 cloudBaseColor;
uniform float cloudExposure;
//-----------------------------------------------------------------------------
// Globals
@ -97,26 +106,25 @@ void main()
// Normalize the interpolated vectors:
vec3 vViewTS = normalize( vViewTS );
vec3 vLightTS = normalize( vLightTS );
vec3 vNormalWS = normalize( vNormalWS );
vec4 cResultColor = float4( 0, 0, 0, 1 );
vec4 cResultColor = vec4( 0, 0, 0, 1 );
vec2 texSample = texCoord12.xy;
vec2 texSample = IN_texCoord12.xy;
vec4 noise1 = texture2D( normalHeightMap, texCoord12.zw );
vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw );
noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
//return noise1;
vec4 noise2 = texture2D( normalHeightMap, texCoord34.xy );
vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy );
noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
//return noise2;
vec3 noiseNormal = normalize( noise1 + noise2 ).xyz;
//return float4( noiseNormal, 1.0 );
//return vec4( noiseNormal, 1.0 );
float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 );
vec3 vNormalTS = normalize( texture2D( normalHeightMap, texSample ).xyz * 2.0 - 1.0 );
vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 );
vNormalTS += noiseNormal;
vNormalTS = normalize( vNormalTS );
@ -124,16 +132,14 @@ void main()
cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
float coverage = ( cloudCoverage - 0.5 ) * 2.0;
cResultColor.a = texture2D( normalHeightMap, texSample ).a + coverage + noiseHeight;
cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight;
if ( cloudCoverage > -1.0 )
cResultColor.a /= 1.0 + coverage;
cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) );
cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 );
cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(worldDist,2.0) );
cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) );
// If using HDR rendering, make sure to tonemap the resuld color prior to outputting it.
// But since this example isn't doing that, we just output the computed result color here:
gl_FragColor = cResultColor;
OUT_FragColor0 = cResultColor;
}

View file

@ -20,12 +20,24 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec4 texCoord12;
varying vec4 texCoord34;
varying vec3 vLightTS; // light vector in tangent space, denormalized
varying vec3 vViewTS; // view vector in tangent space, denormalized
varying vec3 vNormalWS; // Normal vector in world space
varying float worldDist;
#include "hlslCompat.glsl"
in vec4 vPosition;
in vec3 vNormal;
in vec3 vBinormal;
in vec3 vTangent;
in vec2 vTexCoord0;
out vec4 texCoord12;
#define OUT_texCoord12 texCoord12
out vec4 texCoord34;
#define OUT_texCoord34 texCoord34
out vec3 vLightTS; // light vector in tangent space, denormalized
#define OUT_vLightTS vLightTS
out vec3 vViewTS; // view vector in tangent space, denormalized
#define OUT_vViewTS vViewTS
out float worldDist;
#define OUT_worldDist worldDist
//-----------------------------------------------------------------------------
// Uniforms
@ -43,37 +55,37 @@ uniform vec3 texScale;
//-----------------------------------------------------------------------------
void main()
{
vec4 pos = gl_Vertex;
vec3 normal = gl_Normal;
vec3 binormal = gl_MultiTexCoord0.xyz;
vec3 tangent = gl_MultiTexCoord1.xyz;
vec2 uv0 = gl_MultiTexCoord2.st;
vec4 IN_pos = vPosition;
vec3 IN_normal = vNormal;
vec3 IN_binormal = vBinormal;
vec3 IN_tangent = vTangent;
vec2 IN_uv0 = vTexCoord0.st;
gl_Position = modelview * pos;
gl_Position = modelview * IN_pos;
// Offset the uv so we don't have a seam directly over our head.
vec2 uv = uv0 + vec2( 0.5, 0.5 );
vec2 uv = IN_uv0 + vec2( 0.5, 0.5 );
texCoord12.xy = uv * texScale.x;
texCoord12.xy += texOffset0;
OUT_texCoord12.xy = uv * texScale.x;
OUT_texCoord12.xy += texOffset0;
texCoord12.zw = uv * texScale.y;
texCoord12.zw += texOffset1;
OUT_texCoord12.zw = uv * texScale.y;
OUT_texCoord12.zw += texOffset1;
texCoord34.xy = uv * texScale.z;
texCoord34.xy += texOffset2;
OUT_texCoord34.xy = uv * texScale.z;
OUT_texCoord34.xy += texOffset2;
texCoord34.z = pos.z;
texCoord34.w = 0.0;
OUT_texCoord34.z = IN_pos.z;
OUT_texCoord34.w = 0.0;
// Transform the normal, tangent and binormal vectors from object space to
// homogeneous projection space:
vNormalWS = -normal;
vec3 vTangentWS = -tangent;
vec3 vBinormalWS = -binormal;
vec3 vNormalWS = -IN_normal;
vec3 vTangentWS = -IN_tangent;
vec3 vBinormalWS = -IN_binormal;
// Compute position in world space:
vec4 vPositionWS = pos + vec4( eyePosWorld, 1 ); //mul( pos, objTrans );
vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans );
// Compute and output the world view vector (unnormalized):
vec3 vViewWS = eyePosWorld - vPositionWS.xyz;
@ -81,12 +93,14 @@ void main()
// Compute denormalized light vector in world space:
vec3 vLightWS = -sunVec;
// Normalize the light and view vectors and transform it to the tangent space:
// Normalize the light and view vectors and transform it to the IN_tangent space:
mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS );
// Propagate the view and the light vectors (in tangent space):
vLightTS = mWorldToTangent * vLightWS;
vViewTS = vViewWS * mWorldToTangent;
worldDist = clamp( pow( pos.z, 2.0 ), 0.0, 1.0 );
OUT_vLightTS = vLightWS * mWorldToTangent;
OUT_vViewTS = mWorldToTangent * vViewWS;
OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 );
correctSSP(gl_Position);
}

View file

@ -46,7 +46,19 @@ uniform vec3 gc_gustInfo;
uniform vec2 gc_turbInfo;
//static float sMovableCorner[4] = { 0.0, 0.0, 1.0, 1.0 };
const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 );
const float sCornerUp[4] = float[]( 0, 0, 1, 1 );
const float sMovableCorner[4] = float[]( 0, 0, 1, 1 );
const vec2 sUVCornerExtent[4] = vec2[]
(
vec2( 0, 1 ),
vec2( 1, 1 ),
vec2( 1, 0 ),
vec2( 0, 0 )
);
///////////////////////////////////////////////////////////////////////////////
@ -106,34 +118,13 @@ vec2 windEffect( float bbPhase,
void foliageProcessVert( inout vec3 position,
inout vec4 diffuse,
in vec4 texCoord,
out vec2 outTexCoord,
inout vec4 texCoord,
inout vec3 normal,
inout vec3 T,
in vec3 eyePos )
{
float sCornerRight[4];
sCornerRight[0] = -0.5;
sCornerRight[1] = 0.5;
sCornerRight[2] = 0.5;
sCornerRight[3] = -0.5;
float sCornerUp[4];
sCornerUp[0] = 0.0;
sCornerUp[1] = 0.0;
sCornerUp[2] = 1.0;
sCornerUp[3] = 1.0;
vec2 sUVCornerExtent[4];
sUVCornerExtent[0] = vec2( 0.0, 1.0 );
sUVCornerExtent[1] = vec2( 1.0, 1.0 );
sUVCornerExtent[2] = vec2( 1.0, 0.0 );
sUVCornerExtent[3] = vec2( 0.0, 0.0 );
// Assign the normal and tagent values.
//normal = cross( gc_camUp, gc_camRight );
//normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight );
T = gc_camRight;
// Pull out local vars we need for work.
@ -172,8 +163,8 @@ void foliageProcessVert( inout vec3 position,
// Grab the uv set and setup the texture coord.
vec4 uvSet = gc_typeRects[type];
outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
// Animate the normal to get lighting changes
// across the the wind swept foliage.
@ -184,7 +175,6 @@ void foliageProcessVert( inout vec3 position,
normal.xy += wind.xy * ( 10.0 * texCoord.w );
normal = normalize( normal );
// Get the alpha fade value.
float fadeStart = gc_fadeParams.x;

View file

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

View file

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

View file

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

View file

@ -27,17 +27,79 @@
#define float3 vec3
#define float2 vec2
#define texCUBE textureCube
#define tex2D texture2D
#define half float
#define half2 vec2
#define half3 vec3
#define half4 vec4
#define float4x4 mat4
#define float3x3 mat3
#define float2x2 mat2
#define texCUBE texture
#define tex2D texture
#define tex1D texture
#define tex2Dproj textureProj
#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w)
#define samplerCUBE samplerCube
#define frac fract
#define lerp mix
float saturate( float val ) { return clamp( val, 0.0, 1.0 ); }
vec2 saturate( vec2 val ) { return clamp( val, 0.0, 1.0 ); }
vec3 saturate( vec3 val ) { return clamp( val, 0.0, 1.0 ); }
vec4 saturate( vec4 val ) { return clamp( val, 0.0, 1.0 ); }
void tSetMatrixRow(out float3x3 m, int row, float3 value)
{
m[0][row] = value.x;
m[1][row] = value.y;
m[2][row] = value.z;
}
float round( float n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec2 round( vec2 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec3 round( vec3 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
vec4 round( vec4 n ) { return sign( n ) * floor( abs( n ) + 0.5 ); }
void tSetMatrixRow(out float4x4 m, int row, float4 value)
{
m[0][row] = value.x;
m[1][row] = value.y;
m[2][row] = value.z;
m[3][row] = value.w;
}
#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row])
#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row])
float3x3 float4x4to3x3(float4x4 m)
{
return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz);
}
float3x3 float4x4to3x3_(float4x4 m)
{
return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz);
}
mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3,
float r1c0, float r1c1, float r1c2, float r1c3,
float r2c0, float r2c1, float r2c2, float r2c3,
float r3c0, float r3c1, float r3c2, float r3c3 )
{
return mat4( r0c0, r1c0, r2c0, r3c0,
r0c1, r1c1, r2c1, r3c1,
r0c2, r1c2, r2c2, r3c2,
r0c3, r1c3, r2c3, r3c3 );
}
#define saturate( val ) clamp( val, 0.0, 1.0 )
#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 ))
#define tMul(a, b) (a*b)
#define inversesqrt( n ) inversesqrt( n )
#define correctSSP(vec) vec.y *= -1
#ifdef TORQUE_PIXEL_SHADER
void clip(float a) { if(a < 0) discard;}
out vec4 OUT_FragColor0;
#endif

View file

@ -20,73 +20,181 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef TORQUE_SHADERGEN
// These are the uniforms used by most lighting shaders.
uniform vec3 inLightPos[4];
uniform vec4 inLightPos[3];
uniform vec4 inLightInvRadiusSq;
uniform vec4 inLightColor[4];
#ifndef TORQUE_BL_NOSPOTLIGHT
uniform vec4 inLightSpotDir[3];
uniform vec4 inLightSpotAngle;
uniform vec4 inLightSpotFalloff;
#endif
uniform vec4 ambient;
uniform float specularPower;
uniform vec4 specularColor;
// This is used to limit the maximum processed
// lights in the compute4Lights down for really
// low end GPUs.
//
// NOTE: If you want to support 10.5.x, this needs to be changed to 2.
#define C4L_MAX_LIGHTS 4
#endif // !TORQUE_SHADERGEN
void compute4Lights( vec3 wsView,
vec3 wsPosition,
vec3 wsNormal,
vec3 wsNormal,
vec4 shadowMask,
#ifdef TORQUE_SHADERGEN
vec4 inLightPos[3],
vec4 inLightInvRadiusSq,
vec4 inLightColor[4],
vec4 inLightSpotDir[3],
vec4 inLightSpotAngle,
vec4 inLightSpotFalloff,
float specularPower,
vec4 specularColor,
#endif // TORQUE_SHADERGEN
out vec4 outDiffuse,
out vec4 outSpecular )
{
#ifdef PHONG_SPECULAR
// (R.V)^c
float reflected = reflect( wsView, wsNormal );
#endif
vec4 nDotL = vec4( 0.0 );
vec4 rDotL = vec4( 0.0 );
vec4 sqDists = vec4( 0.0 );
// NOTE: The light positions and spotlight directions
// are stored in SoA order, so inLightPos[0] is the
// x coord for all 4 lights... inLightPos[1] is y... etc.
//
// This is the key to fully utilizing the vector units and
// saving a huge amount of instructions.
//
// For example this change saved more than 10 instructions
// over a simple for loop for each light.
int i;
for ( i = 0; i < C4L_MAX_LIGHTS; ++i )
{
vec3 lightVector = inLightPos[i] - wsPosition;
vec3 lightDirection = normalize( lightVector );
vec4 lightVectors[3];
for ( i = 0; i < 3; i++ )
lightVectors[i] = wsPosition[i] - inLightPos[i];
nDotL[i] = max( dot( lightDirection, wsNormal ), 0.0 );
vec4 squareDists = vec4(0);
for ( i = 0; i < 3; i++ )
squareDists += lightVectors[i] * lightVectors[i];
#ifdef PHONG_SPECULAR
rDotL[i] = saturate( dot( lightDirection, reflected ) );
#else
// (N.H)^c [Blinn-Phong, TGEA style, default]
rDotL[i] = dot( wsNormal, normalize( lightDirection + wsView ) );
#endif
// Accumulate the dot product between the light
// vector and the normal.
//
// The normal is negated because it faces away from
// the surface and the light faces towards the
// surface... this keeps us from needing to flip
// the light vector direction which complicates
// the spot light calculations.
//
// We normalize the result a little later.
//
vec4 nDotL = vec4(0);
for ( i = 0; i < 3; i++ )
nDotL += lightVectors[i] * -wsNormal[i];
sqDists[i] = dot( lightVector, lightVector );
}
vec4 rDotL = vec4(0);
#ifndef TORQUE_BL_NOSPECULAR
// Attenuation
vec4 atten = vec4( 1.0 ) - ( sqDists * inLightInvRadiusSq );
// We're using the Phong specular reflection model
// here where traditionally Torque has used Blinn-Phong
// which has proven to be more accurate to real materials.
//
// We do so because its cheaper as do not need to
// calculate the half angle for all 4 lights.
//
// Advanced Lighting still uses Blinn-Phong, but the
// specular reconstruction it does looks fairly similar
// to this.
//
vec3 R = reflect( wsView, -wsNormal );
for ( i = 0; i < 3; i++ )
rDotL += lightVectors[i] * R[i];
#endif
// Normalize the dots.
//
// Notice we're using the half type here to get a
// much faster sqrt via the rsq_pp instruction at
// the loss of some precision.
//
// Unless we have some extremely large point lights
// i don't believe the precision loss will matter.
//
half4 correction = half4(inversesqrt( squareDists ));
nDotL = saturate( nDotL * correction );
rDotL = clamp( rDotL * correction, 0.00001, 1.0 );
// First calculate a simple point light linear
// attenuation factor.
//
// If this is a directional light the inverse
// radius should be greater than the distance
// causing the attenuation to have no affect.
//
vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) );
#ifndef TORQUE_BL_NOSPOTLIGHT
// The spotlight attenuation factor. This is really
// fast for what it does... 6 instructions for 4 spots.
vec4 spotAtten = vec4(0);
for ( i = 0; i < 3; i++ )
spotAtten += lightVectors[i] * inLightSpotDir[i];
vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle;
atten *= saturate( cosAngle * inLightSpotFalloff );
#endif
// Finally apply the shadow masking on the attenuation.
atten *= shadowMask;
// Get the final light intensity.
vec4 intensity = nDotL * atten;
// Combine the light colors for output.
vec4 diffuse = clamp( nDotL * atten, vec4( 0.0 ), vec4( 1.0 ) );
outDiffuse = vec4( 0.0 );
for ( i = 0; i < C4L_MAX_LIGHTS; ++i )
outDiffuse += vec4( diffuse[i] ) * inLightColor[i];
outDiffuse = vec4(0);
for ( i = 0; i < 4; i++ )
outDiffuse += intensity[i] * inLightColor[i];
// Output the specular power.
rDotL = max( rDotL, vec4( 0.00001 ) );
outSpecular = pow( rDotL, vec4( specularPower ) );
vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten;
// Apply the per-light specular attenuation.
vec4 specular = vec4(0,0,0,1);
for ( i = 0; i < 4; i++ )
specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 );
// Add the final specular intensity values together
// using a single dot product operation then get the
// final specular lighting color.
outSpecular = specularColor * specular;
}
/// The standard specular calculation.
// This value is used in AL as a constant power to raise specular values
// to, before storing them into the light info buffer. The per-material
// specular value is then computer by using the integer identity of
// exponentiation:
//
// (a^m)^n = a^(m*n)
//
// or
//
// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular)
//
#define AL_ConstantSpecularPower 12.0f
/// The specular calculation used in Advanced Lighting.
///
/// @param toLight Normalized vector representing direction from the pixel
/// being lit, to the light source, in world space.
@ -96,11 +204,7 @@ void compute4Lights( vec3 wsView,
/// @param toEye The normalized vector representing direction from the pixel
/// being lit to the camera.
///
/// @param specPwr The specular exponent.
///
/// @param specScale A scalar on the specular output used in RGB accumulation.
///
float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye )
{
#ifdef PHONG_SPECULAR
// (R.V)^c
@ -111,5 +215,5 @@ float calcSpecular( vec3 toLight, vec3 normal, vec3 toEye, float specPwr )
#endif
// Return the specular factor.
return pow( max( specVal, 0.00001f ), specPwr );
return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
}

View file

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

View file

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

View file

@ -20,63 +20,92 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "hlslCompat.glsl"
#include "torque.glsl"
#include "hlslCompat.glsl"
// With advanced lighting we get soft particles.
#ifdef TORQUE_LINEAR_DEPTH
#define SOFTPARTICLES
#endif
#define CLIP_Z // TODO: Make this a proper macro
uniform sampler2D diffuseMap;
#ifdef SOFTPARTICLES
#include "shadergen:/autogenConditioners.h"
uniform float oneOverSoftness;
uniform float oneOverFar;
uniform sampler2D prepassTex;
uniform sampler2D prepassTex;
//uniform vec3 vEye;
uniform vec4 prePassTargetParams;
#endif
#define CLIP_Z // TODO: Make this a proper macro
in vec4 color;
in vec2 uv0;
in vec4 pos;
#define IN_color color
#define IN_uv0 uv0
#define IN_pos pos
uniform sampler2D diffuseMap;
uniform sampler2D paraboloidLightMap;
vec4 lmSample( vec3 nrm )
{
bool calcBack = (nrm.z < 0.0);
if ( calcBack )
nrm.z = nrm.z * -1.0;
vec2 lmCoord;
lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5;
lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5);
// If this is the back, offset in the atlas
if ( calcBack )
lmCoord.x += 1.0;
// Atlasing front and back maps, so scale
lmCoord.x *= 0.5;
return texture(paraboloidLightMap, lmCoord);
}
uniform float alphaFactor;
uniform float alphaScale;
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
void main()
{
float softBlend = 1.0;
float softBlend = 1;
#ifdef SOFTPARTICLES
float2 tc = pos.xy * vec2(1.0, -1.0 ) / pos.w;
vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w;
tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), prePassTargetParams);
float sceneDepth = prepassUncondition( prepassTex, tc ).w;
float depth = pos.w * oneOverFar;
float diff = sceneDepth - depth;
float depth = IN_pos.w * oneOverFar;
float diff = sceneDepth - depth;
#ifdef CLIP_Z
// If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer
// When drawing high-res, though, we want to be able to take advantage of hi-z
// so this is #ifdef'd out
if (diff < 0.0)
discard;
//clip(diff);
#endif
softBlend = saturate( diff * oneOverSoftness );
#endif
vec4 diffuse = texture2D( diffuseMap, uv0 );
vec4 diffuse = texture( diffuseMap, IN_uv0 );
//OUT_FragColor0 = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale);
// Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha)
vec3 colorScale = ( alphaFactor < 0.0 ? color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? vec3(color.a * alphaFactor * diffuse.a * softBlend) : vec3(softBlend) ) );
vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) );
gl_FragColor = hdrEncode( vec4(color.rgb * diffuse.rgb * colorScale, softBlend * color.a * diffuse.a * alphaScale) );
OUT_FragColor0 = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale,
IN_color.a * diffuse.a * softBlend * alphaScale ) );
}

View file

@ -20,18 +20,35 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec4 color;
varying vec2 uv0;
varying vec4 pos;
#include "hlslCompat.glsl"
in vec4 vPosition;
in vec4 vColor;
in vec2 vTexCoord0;
#define In_pos vPosition
#define In_color vColor
#define In_uv0 vTexCoord0
out vec4 color;
out vec2 uv0;
out vec4 pos;
#define OUT_hpos gl_Position
#define OUT_color color
#define OUT_uv0 uv0
#define OUT_pos pos
uniform mat4 modelViewProj;
uniform mat4 fsModelViewProj;
void main()
{
gl_Position = modelViewProj * gl_Vertex;
pos = fsModelViewProj * gl_Vertex;
color = gl_Color;
uv0 = gl_MultiTexCoord0.st;
OUT_hpos = tMul( modelViewProj, In_pos );
OUT_pos = tMul( fsModelViewProj, In_pos );
OUT_color = In_color;
OUT_uv0 = In_uv0;
correctSSP(gl_Position);
}

View file

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

View file

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

View file

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

View file

@ -23,10 +23,13 @@
//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------
in vec4 vPosition;
in vec2 vTexCoord0;
uniform mat4 modelview;
varying vec2 TEX0;
varying vec4 TEX1;
out vec2 TEX0;
out vec4 TEX1;
//-----------------------------------------------------------------------------
// Main
@ -38,9 +41,9 @@ void main()
0.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 1.0);
gl_Position = modelview * gl_Vertex;
gl_Position = modelview * vPosition;
TEX0 = gl_MultiTexCoord0.st;
TEX0 = vTexCoord0;
TEX1 = texGenTest * gl_Position;
TEX1.y = -TEX1.y;

View file

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

View file

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

View file

@ -20,9 +20,11 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
varying vec2 texCoord;
varying vec4 color;
varying float fade;
in vec2 texCoord;
in vec4 color;
in float fade;
out vec4 OUT_FragColor0;
uniform sampler2D inputTex;
uniform vec4 ambient;
@ -30,17 +32,6 @@ uniform vec4 ambient;
void main()
{
vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.4154f, 0.1721f);
float esmFactor = 200.0;
float lum = dot( ambient.rgb, LUMINANCE_VECTOR );
gl_FragColor.rgb = ambient.rgb * lum;
gl_FragColor.a = 0.0;
float depth = texture2D(inputTex, texCoord).a;
depth = depth * exp(depth - 10.0);
depth = exp(esmFactor * depth) - 1.0;
gl_FragColor.a = clamp(depth * 300.0, 0.0, 1.0) * (1.0 - lum) * fade * color.a;
float shadow = texture( inputTex, texCoord ).a * color.a;
OUT_FragColor0 = ( ambient * shadow ) + ( 1 - shadow );
}

View file

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

View file

@ -21,36 +21,32 @@
//-----------------------------------------------------------------------------
#include "torque.glsl"
#include "hlslCompat.glsl"
// Calculates the Mie phase function
float getMiePhase(float fCos, float fCos2, float g, float g2)
{
return 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
}
// Calculates the Rayleigh phase function
float getRayleighPhase(float fCos2)
{
//return 1.0;
return 0.75 + 0.75*fCos2;
}
// Conn
in vec4 rayleighColor;
#define IN_rayleighColor rayleighColor
in vec4 mieColor;
#define IN_mieColor mieColor
in vec3 v3Direction;
#define IN_v3Direction v3Direction
in float zPosition;
#define IN_zPosition zPosition
in vec3 pos;
#define IN_pos pos
varying vec4 rayleighColor;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
uniform samplerCube nightSky;
uniform samplerCube nightSky ;
uniform vec4 nightColor;
uniform vec2 nightInterpAndExposure;
uniform float useCubemap;
uniform vec3 lightDir;
uniform vec3 sunDir;
void main()
void main()
{
float fCos = dot( lightDir, v3Direction ) / length(v3Direction);
float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction);
float fCos2 = fCos*fCos;
float g = -0.991;
@ -58,15 +54,15 @@ void main()
float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
vec4 color = rayleighColor + fMiePhase * mieColor;
vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor;
color.a = color.b;
vec4 nightSkyColor = textureCube(nightSky, -v3Direction);
vec4 nightSkyColor = texture(nightSky, -v3Direction);
nightSkyColor = mix(nightColor, nightSkyColor, useCubemap);
float fac = dot( normalize( pos ), sunDir );
fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) );
gl_FragColor = mix( color, nightSkyColor, nightInterpAndExposure.y );
OUT_FragColor0 = mix( color, nightSkyColor, nightInterpAndExposure.y );
// Clip based on the camera-relative
// z position of the vertex, passed through
@ -74,6 +70,6 @@ void main()
if(zPosition < 0.0)
discard;
gl_FragColor.a = 1;
gl_FragColor = hdrEncode( gl_FragColor );
OUT_FragColor0.a = 1;
OUT_FragColor0 = hdrEncode( OUT_FragColor0 );
}

View file

@ -20,12 +20,7 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
const int nSamples = 4;
const float fSamples = 4.0;
// The scale depth (the altitude at which the average atmospheric density is found)
const float fScaleDepth = 0.25;
const float fInvScaleDepth = 1.0 / 0.25;
#include "hlslCompat.glsl"
// The scale equation calculated by Vernier's Graphical Analysis
float vernierScale(float fCos)
@ -40,12 +35,27 @@ float vernierScale(float fCos)
return 0.25 * outx;
}
in vec4 vPosition;
in vec3 vNormal;
in vec4 vColor;
in vec2 vTexCoord0;
// This is the shader input vertex structure.
#define IN_position vPosition
#define IN_normal vNormal
#define IN_color vColor
// This is the shader output data.
varying vec4 rayleighColor;
varying vec4 mieColor;
varying vec3 v3Direction;
varying float zPosition;
varying vec3 pos;
out vec4 rayleighColor;
#define OUT_rayleighColor rayleighColor
out vec4 mieColor;
#define OUT_mieColor mieColor
out vec3 v3Direction;
#define OUT_v3Direction v3Direction
out float zPosition;
#define OUT_zPosition zPosition
out vec3 pos;
#define OUT_pos pos
uniform mat4 modelView;
uniform vec4 misc;
@ -54,13 +64,16 @@ uniform vec4 scatteringCoeffs;
uniform vec3 camPos;
uniform vec3 lightDir;
uniform vec4 invWaveLength;
void main()
{
vec4 position = gl_Vertex.xyzw;
vec3 normal = gl_Normal.xyz;
vec4 color = gl_MultiTexCoord0.xyzw;
uniform vec4 colorize;
vec3 desaturate(const vec3 color, const float desaturation)
{
const vec3 gray_conv = vec3 (0.30, 0.59, 0.11);
return mix(color, vec3(dot(gray_conv , color)), desaturation);
}
void main()
{
// Pull some variables out:
float camHeight = misc.x;
float camHeightSqr = misc.y;
@ -83,7 +96,7 @@ void main()
// Get the ray from the camera to the vertex,
// and its length (which is the far point of the ray
// passing through the atmosphere).
vec3 v3Pos = position.xyz / 6378000.0;// / outerRadius;
vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius;
vec3 newCamPos = vec3( 0, 0, camHeight );
v3Pos.z += innerRadius;
vec3 v3Ray = v3Pos.xyz - newCamPos;
@ -97,16 +110,7 @@ void main()
float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
float fStartAngle = dot(v3Ray, v3Start) / fHeight;
float x = 1.0 - fStartAngle;
float x5 = x * 5.25;
float x5p6 = (-6.80 + x5);
float xnew = (3.83 + x * x5p6);
float xfinal = (0.459 + x * xnew);
float xfinal2 = -0.00287 + x * xfinal;
float othx = exp( xfinal2 );
float vscale1 = 0.25 * othx;
float fStartOffset = fDepth * vscale1;//vernierScale(fStartAngle);
float fStartOffset = fDepth * vernierScale( fStartAngle );
// Initialize the scattering loop variables.
float fSampleLength = fFar / 2.0;
@ -123,24 +127,8 @@ void main()
float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
x = 1.0 - fCameraAngle;
x5 = x * 5.25;
x5p6 = (-6.80 + x5);
xnew = (3.83 + x * x5p6);
xfinal = (0.459 + x * xnew);
xfinal2 = -0.00287 + x * xfinal;
othx = exp( xfinal2 );
float vscale3 = 0.25 * othx;
x = 1.0 - fLightAngle;
x5 = x * 5.25;
x5p6 = (-6.80 + x5);
xnew = (3.83 + x * x5p6);
xfinal = (0.459 + x * xnew);
xfinal2 = -0.00287 + x * xfinal;
othx = exp( xfinal2 );
float vscale2 = 0.25 * othx;
float vscale3 = vernierScale( fCameraAngle );
float vscale2 = vernierScale( fLightAngle );
float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
@ -150,16 +138,24 @@ void main()
// Finally, scale the Mie and Rayleigh colors
// and set up the varying variables for the pixel shader.
gl_Position = modelView * position;
mieColor.rgb = v3FrontColor * mieBrightness;
mieColor.a = 1.0;
rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
rayleighColor.a = 1.0;
v3Direction = newCamPos - v3Pos.xyz;
gl_Position = modelView * IN_position;
OUT_mieColor.rgb = v3FrontColor * mieBrightness;
OUT_mieColor.a = 1.0;
OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
OUT_rayleighColor.a = 1.0;
OUT_v3Direction = newCamPos - v3Pos.xyz;
OUT_pos = IN_position.xyz;
// This offset is to get rid of the black line between the atmosky and the waterPlane
// along the horizon.
zPosition = position.z + 4000.0;
pos = position.xyz;
#ifdef USE_COLORIZE
OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a;
OUT_rayleighColor.r *= colorize.r;
OUT_rayleighColor.g *= colorize.g;
OUT_rayleighColor.b *= colorize.b;
#endif
correctSSP(gl_Position);
}

View file

@ -117,6 +117,7 @@ mat3x3 quatToMat( vec4 quat )
return mat;
}
/// The number of additional substeps we take when refining
/// the results of the offset parallax mapping function below.
///
@ -129,19 +130,20 @@ mat3x3 quatToMat( vec4 quat )
/// Performs fast parallax offset mapping using
/// multiple refinement steps.
////// @param texMap The texture map whos alpha channel we sample the parallax depth.
///
/// @param texMap The texture map whos alpha channel we sample the parallax depth.
/// @param texCoord The incoming texture coordinate for sampling the parallax depth.
/// @param negViewTS The negative view vector in tangent space.
/// @param depthScale The parallax factor used to scale the depth result.
///
vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale )
{
float depth = texture2D( texMap, texCoord ).a;
float depth = texture( texMap, texCoord ).a;
vec2 offset = negViewTS.xy * ( depth * depthScale );
for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ )
{
depth = ( depth + texture2D( texMap, texCoord + offset ).a ) * 0.5;
depth = ( depth + texture( texMap, texCoord + offset ).a ) * 0.5;
offset = negViewTS.xy * ( depth * depthScale );
}
@ -151,59 +153,61 @@ vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float dept
/// The maximum value for 16bit per component integer HDR encoding.
const float HDR_RGB16_MAX = 100.0;
/// The maximum value for 10bit per component integer HDR encoding.const float HDR_RGB10_MAX = 4.0;
/// The maximum value for 10bit per component integer HDR encoding.
const float HDR_RGB10_MAX = 4.0;
/// Encodes an HDR color for storage into a target.
vec3 hdrEncode( vec3 sample ){
vec3 hdrEncode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 )
return sample / HDR_RGB16_MAX;
return _sample / HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 )
return sample / HDR_RGB10_MAX;
return _sample / HDR_RGB10_MAX;
#else
// No encoding.
return sample;
return _sample;
#endif
}
/// Encodes an HDR color for storage into a target.
vec4 hdrEncode( vec4 sample )
vec4 hdrEncode( vec4 _sample )
{
return vec4( hdrEncode( sample.rgb ), sample.a );
return vec4( hdrEncode( _sample.rgb ), _sample.a );
}
/// Decodes an HDR color from a target.
vec3 hdrDecode( vec3 sample )
vec3 hdrDecode( vec3 _sample )
{
#if defined( TORQUE_HDR_RGB16 )
return sample * HDR_RGB16_MAX;
return _sample * HDR_RGB16_MAX;
#elif defined( TORQUE_HDR_RGB10 )
return sample * HDR_RGB10_MAX;
return _sample * HDR_RGB10_MAX;
#else
// No encoding.
return sample;
return _sample;
#endif
}
/// Decodes an HDR color from a target.
vec4 hdrDecode( vec4 sample )
vec4 hdrDecode( vec4 _sample )
{
return vec4( hdrDecode( sample.rgb ), sample.a );
return vec4( hdrDecode( _sample.rgb ), _sample.a );
}
/// Returns the luminance for an HDR pixel.
float hdrLuminance( vec3 sample )
float hdrLuminance( vec3 _sample )
{
// There are quite a few different ways to
// calculate luminance from an rgb value.
@ -216,7 +220,7 @@ float hdrLuminance( vec3 sample )
//
// Max component luminance.
//
//float lum = max( sample.r, max( sample.g, sample.b ) );
//float lum = max( _sample.r, max( _sample.g, _sample.b ) );
////////////////////////////////////////////////////////////////////////////
// The perceptual relative luminance.
@ -224,23 +228,45 @@ float hdrLuminance( vec3 sample )
// See http://en.wikipedia.org/wiki/Luminance_(relative)
//
const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 );
float lum = dot( sample, RELATIVE_LUMINANCE );
float lum = dot( _sample, RELATIVE_LUMINANCE );
////////////////////////////////////////////////////////////////////////////
//
// The average component luminance.
//
//const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 );
//float lum = dot( sample, AVERAGE_LUMINANCE );
//float lum = dot( _sample, AVERAGE_LUMINANCE );
return lum;
}
#ifdef TORQUE_PIXEL_SHADER
/// Called from the visibility feature to do screen
/// door transparency for fading of objects.
void fizzle(vec2 vpos, float visibility)
{
// NOTE: The magic values below are what give us
// the nice even pattern during the fizzle.
//
// These values can be changed to get different
// patterns... some better than others.
//
// Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 }
// Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 }
//
// I'm sure there are many more patterns here to
// discover for different effects.
mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 );
if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard;
discard;
}
#endif //TORQUE_PIXEL_SHADER
/// Basic assert macro. If the condition fails, then the shader will output color.
/// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail.
/// @param color The color that should be outputted if the condition fails.
/// @note This macro will only work in the void main() method of a pixel shader.
#define assert(condition, color) { if(!any(condition)) { gl_FragColor = color; return; } }
#define assert(condition, color) { if(!any(condition)) { OUT_FragColor0 = color; return; } }
#endif // _TORQUE_GLSL_

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,113 +19,141 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#define NUM_TAPS 12
#define NUM_PRE_TAPS 4
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS];
void initNonUniformTaps()
#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
#define NUM_PRE_TAPS 4
#define NUM_TAPS 12
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_TAPS] = vec2[]
(
// These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed
// or unshadowed areas.
vec2( 0.992833, 0.979309 ),
vec2( -0.998585, 0.985853 ),
vec2( 0.949299, -0.882562 ),
vec2( -0.941358, -0.893924 ),
// The rest of the samples.
vec2( 0.545055, -0.589072 ),
vec2( 0.346526, 0.385821 ),
vec2( -0.260183, 0.334412 ),
vec2( 0.248676, -0.679605 ),
vec2( -0.569502, -0.390637 ),
vec2( -0.614096, 0.212577 ),
vec2( -0.259178, 0.876272 ),
vec2( 0.649526, 0.864333 )
);
#else
#define NUM_PRE_TAPS 5
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[]
(
vec2( 0.892833, 0.959309 ),
vec2( -0.941358, -0.873924 ),
vec2( -0.260183, 0.334412 ),
vec2( 0.348676, -0.679605 ),
vec2( -0.569502, -0.390637 )
);
#endif
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex ;
float softShadow_sampleTaps( sampler2D shadowMap,
vec2 sinCos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float esmFactor,
int startTap,
int endTap )
{
// These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed
// or unshadowed areas.
sNonUniformTaps[0] = vec2( 0.992833, 0.979309 );
sNonUniformTaps[1] = vec2( -0.998585, 0.985853 );
sNonUniformTaps[2] = vec2( 0.949299, -0.882562 );
sNonUniformTaps[3] = vec2( -0.941358, -0.893924 );
// The rest of the samples.
sNonUniformTaps[4] = vec2( 0.545055, -0.589072 );
sNonUniformTaps[5] = vec2( 0.346526, 0.385821 );
sNonUniformTaps[6] = vec2( -0.260183, 0.334412 );
sNonUniformTaps[7] = vec2( 0.248676, -0.679605 );
sNonUniformTaps[8] = vec2( -0.569502, -0.390637 );
sNonUniformTaps[9] = vec2( -0.014096, 0.012577 );
sNonUniformTaps[10] = vec2( -0.259178, 0.876272 );
sNonUniformTaps[11] = vec2( 0.649526, 0.664333 );
float shadow = 0;
vec2 tap = vec2(0);
for ( int t = startTap; t < endTap; t++ )
{
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r;
float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
shadow += esm / float( endTap - startTap );
}
return shadow;
}
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex;
float softShadow_sampleTaps( sampler2D shadowMap,
vec2 sinCos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float esmFactor,
int startTap,
int endTap )
{
initNonUniformTaps();
float shadow = 0.0;
vec2 tap = vec2(0.0);
for ( int t = startTap; t < endTap; t++ )
{
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
float occluder = texture2DLod( shadowMap, shadowPos + tap, 0.0 ).r;
float esm = clamp( exp( esmFactor * ( occluder - distToLight ) ), 0.0, 1.0 );
shadow += esm / float( endTap - startTap );
}
return shadow;
}
// HACK! HACK! HACK!
// We take the noise texture directly as the second parameter to ensure that it
// is the "last used" sampler, and thus doesn't collide with the prepass buffer
// or shadow map. If we use gTapRotationTex directly here, then it is the first
// used sampler and will collide with the prepass buffer.
float softShadow_filter( sampler2D shadowMap,
sampler2D noiseTexture,
vec2 vpos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float dotNL,
float esmFactor )
{
// Lookup the random rotation for this screen pixel.
vec2 sinCos = ( texture2DLod( noiseTexture, vpos * 16.0, 0.0 ).rg - 0.5 ) * 2.0;
// Do the prediction taps first.
float shadow = softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// Only do the expensive filtering if we're really
// in a partially shadowed area.
if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0.0 ) > 0.06 )
{
shadow += softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
NUM_PRE_TAPS,
NUM_TAPS );
// This averages the taps above with the results
// of the prediction samples.
shadow *= 0.5;
}
return shadow;
}
float softShadow_filter( sampler2D shadowMap,
vec2 vpos,
vec2 shadowPos,
float filterRadius,
float distToLight,
float dotNL,
float esmFactor )
{
#ifndef SOFTSHADOW
// If softshadow is undefined then we skip any complex
// filtering... just do a single sample ESM.
float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r;
float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
#else
// Lookup the random rotation for this screen pixel.
vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2;
// Do the prediction taps first.
float shadow = softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
0,
NUM_PRE_TAPS );
// We live with only the pretap results if we don't
// have high quality shadow filtering enabled.
#ifdef SOFTSHADOW_HIGH_QUALITY
// Only do the expensive filtering if we're really
// in a partially shadowed area.
if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 )
{
shadow += softShadow_sampleTaps( shadowMap,
sinCos,
shadowPos,
filterRadius,
distToLight,
esmFactor,
NUM_PRE_TAPS,
NUM_TAPS );
// This averages the taps above with the results
// of the prediction samples.
shadow *= 0.5;
}
#endif // SOFTSHADOW_HIGH_QUALITY
#endif // SOFTSHADOW
return shadow;
}

View file

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

View file

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

View file

@ -20,35 +20,27 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "../../../gl/hlslCompat.glsl"
uniform sampler2D diffuseMap;
varying vec2 uv;
in vec2 uv;
uniform vec2 oneOverTargetSize;
const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );
const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );
void main()
{
vec2 sNonUniformTaps[8];
sNonUniformTaps[0] = vec2(0.992833, 0.979309);
sNonUniformTaps[1] = vec2(-0.998585, 0.985853);
sNonUniformTaps[2] = vec2(0.949299, -0.882562);
sNonUniformTaps[3] = vec2(-0.941358, -0.893924);
sNonUniformTaps[4] = vec2(0.545055, -0.589072);
sNonUniformTaps[5] = vec2(0.346526, 0.385821);
sNonUniformTaps[6] = vec2(-0.260183, 0.334412);
sNonUniformTaps[7] = vec2(0.248676, -0.679605);
vec4 OUT = texture( diffuseMap, uv ) * weight[0];
gl_FragColor = vec4(0.0);
vec2 texScale = vec2(1.0);
for ( int i=0; i < 4; i++ )
for ( int i=1; i < 3; i++ )
{
vec2 offset = (oneOverTargetSize * texScale) * sNonUniformTaps[i];
gl_FragColor += texture2D( diffuseMap, uv + offset );
vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
OUT += texture( diffuseMap, uv + _sample ) * weight[i];
OUT += texture( diffuseMap, uv - _sample ) * weight[i];
}
gl_FragColor /= vec4(4.0);
gl_FragColor.rgb = vec3(0.0);
OUT_FragColor0 = OUT;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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