Merge pull request #1442 from Azaezel/shadow_caching

This all seems to work pretty well.
This commit is contained in:
Areloch 2015-11-12 12:49:58 -06:00
commit 92aa785bb2
61 changed files with 1490 additions and 466 deletions

View file

@ -62,9 +62,10 @@ new ShaderData( AL_VectorLightShader )
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$ShadowMap";
samplerNames[2] = "$ssaoMask";
samplerNames[3] = "$gTapRotationTex";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$ssaoMask";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -75,7 +76,8 @@ new CustomMaterial( AL_VectorLightMaterial )
stateBlock = AL_VectorLightState;
sampler["prePassBuffer"] = "#prepass";
sampler["ShadowMap"] = "$dynamiclight";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["ssaoMask"] = "#ssaoMask";
target = "lightinfo";
@ -128,8 +130,9 @@ new ShaderData( AL_PointLightShader )
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$cookieMap";
samplerNames[3] = "$gTapRotationTex";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$cookieMap";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -141,6 +144,7 @@ new CustomMaterial( AL_PointLightMaterial )
sampler["prePassBuffer"] = "#prepass";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["cookieMap"] = "$dynamiclightmask";
target = "lightinfo";
@ -159,8 +163,9 @@ new ShaderData( AL_SpotLightShader )
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$cookieMap";
samplerNames[3] = "$gTapRotationTex";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$cookieMap";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -172,6 +177,7 @@ new CustomMaterial( AL_SpotLightMaterial )
sampler["prePassBuffer"] = "#prepass";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["cookieMap"] = "$dynamiclightmask";
target = "lightinfo";

View file

@ -28,6 +28,7 @@
#include "../../../gl/lighting.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h"
#include "softShadow.glsl"
#include "../../../gl/torque.glsl"
in vec4 wsEyeDir;
in vec4 ssPos;
@ -107,6 +108,7 @@ uniform sampler2D prePassBuffer;
uniform samplerCube shadowMap;
#else
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
#endif
uniform vec4 rtParams0;
@ -119,9 +121,10 @@ uniform vec2 lightAttenuation;
uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform mat3 viewToLightProj;
uniform mat3 dynamicViewToLightProj;
uniform vec4 lightParams;
uniform float shadowSoftness;
out vec4 OUT_col;
void main()
@ -175,7 +178,7 @@ void main()
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -183,17 +186,28 @@ void main()
nDotL,
lightParams.y );
vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy;
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynamicShadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif
#endif // !NO_SHADOW
vec3 lightcol = lightColor.rgb;
#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;
lightcol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
@ -211,7 +225,7 @@ void main()
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec3 lightColorOut = lightMapParams.rgb * lightcol;
vec4 addToResult = vec4(0.0);
// TODO: This needs to be removed when lightmapping is disabled

View file

@ -27,6 +27,7 @@
#include "shadergen:/autogenConditioners.h"
#include "softShadow.glsl"
#include "../../../gl/lighting.glsl"
#include "../../../gl/torque.glsl"
in vec4 wsEyeDir;
in vec4 ssPos;
@ -45,6 +46,7 @@ uniform sampler2D cookieMap;
uniform sampler2D prePassBuffer;
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
uniform vec4 rtParams0;
@ -59,6 +61,7 @@ uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform mat4 viewToLightProj;
uniform mat4 dynamicViewToLightProj;
uniform vec4 lightParams;
uniform float shadowSoftness;
@ -70,7 +73,7 @@ void main()
// Compute scene UV
vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
vec3 normal = prepassSample.rgb;
@ -102,6 +105,10 @@ void main()
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
shadowCoord.y = 1.0f - shadowCoord.y;
// Get the dynamic shadow texture coordinate
vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) );
vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
#ifdef NO_SHADOW
float shadowed = 1.0;
@ -111,7 +118,7 @@ void main()
// Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -119,15 +126,24 @@ void main()
nDotL,
lightParams.y );
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynshadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif // !NO_SHADOW
vec3 lightcol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
vec4 cookie = texture( cookieMap, shadowCoord );
// Multiply the light with the cookie tex.
lightColor.rgb *= cookie.rgb;
lightcol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
@ -145,7 +161,7 @@ void main()
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
vec3 lightColorOut = lightMapParams.rgb * lightcol;
vec4 addToResult = vec4(0.0);
// TODO: This needs to be removed when lightmapping is disabled

View file

@ -34,38 +34,162 @@ in vec2 uv0;
in vec3 wsEyeRay;
in vec3 vsEyeRay;
uniform sampler2D ShadowMap ;
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask ;
uniform vec4 rtParams2;
#endif
uniform sampler2D prePassBuffer;
uniform sampler2D prePassBuffer;
uniform vec3 lightDirection;
uniform vec4 lightColor;
uniform float lightBrightness;
uniform vec4 lightAmbient;
uniform vec3 eyePosWorld;
uniform mat4x4 worldToLightProj;
uniform vec4 scaleX;
uniform vec4 scaleY;
uniform vec4 offsetX;
uniform vec4 offsetY;
uniform mat4x4 eyeMat;
uniform vec4 atlasXOffset;
uniform vec4 atlasYOffset;
uniform vec2 atlasScale;
uniform vec4 zNearFarInvNearFar;
uniform vec4 lightMapParams;
uniform vec2 fadeStartLength;
uniform vec4 farPlaneScalePSSM;
uniform vec4 overDarkPSSM;
uniform float shadowSoftness;
//static shadowMap
uniform mat4x4 worldToLightProj;
uniform vec4 scaleX;
uniform vec4 scaleY;
uniform vec4 offsetX;
uniform vec4 offsetY;
uniform vec4 farPlaneScalePSSM;
//dynamic shadowMap
uniform mat4x4 dynamicWorldToLightProj;
uniform vec4 dynamicScaleX;
uniform vec4 dynamicScaleY;
uniform vec4 dynamicOffsetX;
uniform vec4 dynamicOffsetY;
uniform vec4 dynamicFarPlaneScalePSSM;
vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap,
vec2 _texCoord,
mat4 _worldToLightProj,
vec4 _worldPos,
vec4 _scaleX, vec4 _scaleY,
vec4 _offsetX, vec4 _offsetY,
vec4 _farPlaneScalePSSM,
vec4 _atlasXOffset, vec4 _atlasYOffset,
vec2 _atlasScale,
float _shadowSoftness,
float _dotNL ,
vec4 _overDarkPSSM
)
{
// Compute shadow map coordinate
vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
// Distance to light, in shadowMap space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.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);
else
finalMask = vec4(0, 0, 0, 1);
vec3 debugColor = vec3(0);
#ifdef NO_SHADOW
debugColor = vec3(1.0);
#endif
#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
// 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);
vec2 finalOffset;
finalOffset.x = dot(finalMask, _offsetX);
finalOffset.y = dot(finalMask, _offsetY);
vec2 shadowCoord;
shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Convert to _texCoord space
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Move around inside of atlas
vec2 aOffset;
aOffset.x = dot(finalMask, _atlasXOffset);
aOffset.y = dot(finalMask, _atlasYOffset);
shadowCoord *= _atlasScale;
shadowCoord += aOffset;
// Each split has a different far plane, take this into account.
float farPlaneScale = dot( _farPlaneScalePSSM, finalMask );
distToLight *= farPlaneScale;
return vec4(debugColor,
softShadow_filter( _sourceshadowMap,
_texCoord,
shadowCoord,
farPlaneScale * _shadowSoftness,
distToLight,
_dotNL,
dot( finalMask, _overDarkPSSM ) ) );
}
out vec4 OUT_col;
void main()
{
{
// Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 );
vec3 normal = prepassSample.rgb;
@ -92,102 +216,52 @@ void main()
#else
// Compute shadow map coordinate
vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
uv0.xy,
worldToLightProj,
worldPos,
scaleX, scaleY,
offsetX, offsetY,
farPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
// Distance to light, in shadowmap space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.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;
vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
uv0.xy,
dynamicWorldToLightProj,
worldPos,
dynamicScaleX, dynamicScaleY,
dynamicOffsetX, dynamicOffsetY,
dynamicFarPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
// 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);
else
finalMask = vec4(0, 0, 0, 1);
float static_shadowed = static_shadowed_colors.a;
float dynamic_shadowed = dynamic_shadowed_colors.a;
#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 );
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
#endif
// 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);
vec2 finalOffset;
finalOffset.x = dot(finalMask, offsetX);
finalOffset.y = dot(finalMask, offsetY);
vec2 shadowCoord;
shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Convert to texcoord space
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Move around inside of atlas
vec2 aOffset;
aOffset.x = dot(finalMask, atlasXOffset);
aOffset.y = dot(finalMask, atlasYOffset);
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, saturate( fadeOutAmt ) );
static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) );
dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
// temp for debugging. uncomment one or the other.
//float shadowed = static_shadowed;
//float shadowed = dynamic_shadowed;
float shadowed = min(static_shadowed, dynamic_shadowed);
#ifdef PSSM_DEBUG_RENDER
if ( fadeOutAmt > 1.0 )
debugColor = vec3(1.0);
@ -228,7 +302,7 @@ void main()
#ifdef PSSM_DEBUG_RENDER
lightColorOut = debugColor;
#endif
OUT_col = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
}

View file

@ -27,7 +27,7 @@
#include "../../lighting.hlsl"
#include "../shadowMap/shadowMapIO_HLSL.h"
#include "softShadow.hlsl"
#include "../../torque.hlsl"
struct ConvexConnectP
{
@ -40,7 +40,7 @@ struct ConvexConnectP
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
uniform samplerCUBE cookieMap : register(S2);
uniform samplerCUBE cookieMap : register(S3);
#endif
@ -114,6 +114,7 @@ float4 main( ConvexConnectP IN,
uniform samplerCUBE shadowMap : register(S1),
#else
uniform sampler2D shadowMap : register(S1),
uniform sampler2D dynamicShadowMap : register(S2),
#endif
uniform float4 rtParams0,
@ -127,6 +128,7 @@ float4 main( ConvexConnectP IN,
uniform float4 vsFarPlane,
uniform float3x3 viewToLightProj,
uniform float3x3 dynamicViewToLightProj,
uniform float4 lightParams,
uniform float shadowSoftness ) : COLOR0
@ -134,7 +136,7 @@ float4 main( ConvexConnectP IN,
// Compute scene UV
float3 ssPos = IN.ssPos.xyz / IN.ssPos.w;
float2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
float3 normal = prepassSample.rgb;
@ -178,9 +180,9 @@ float4 main( ConvexConnectP IN,
#else
// Static
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -188,17 +190,30 @@ float4 main( ConvexConnectP IN,
nDotL,
lightParams.y );
// Dynamic
float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy;
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynamicShadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif
#endif // !NO_SHADOW
float3 lightcol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
float4 cookie = texCUBE( cookieMap, mul( viewToLightProj, -lightVec ) );
// Multiply the light with the cookie tex.
lightColor.rgb *= cookie.rgb;
lightcol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
@ -216,7 +231,7 @@ float4 main( ConvexConnectP IN,
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
float3 lightColorOut = lightMapParams.rgb * lightcol;
float4 addToResult = 0.0;
// TODO: This needs to be removed when lightmapping is disabled

View file

@ -69,7 +69,7 @@ static float2 sNonUniformTaps[NUM_PRE_TAPS] =
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex : register(S3);
uniform sampler2D gTapRotationTex : register(S4);
float softShadow_sampleTaps( sampler2D shadowMap,

View file

@ -27,7 +27,7 @@
#include "../../lighting.hlsl"
#include "../shadowMap/shadowMapIO_HLSL.h"
#include "softShadow.hlsl"
#include "../../torque.hlsl"
struct ConvexConnectP
{
@ -39,7 +39,7 @@ struct ConvexConnectP
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
uniform sampler2D cookieMap : register(S2);
uniform sampler2D cookieMap : register(S3);
#endif
@ -48,6 +48,7 @@ float4 main( ConvexConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform sampler2D shadowMap : register(S1),
uniform sampler2D dynamicShadowMap : register(S2),
uniform float4 rtParams0,
@ -62,6 +63,7 @@ float4 main( ConvexConnectP IN,
uniform float4 vsFarPlane,
uniform float4x4 viewToLightProj,
uniform float4x4 dynamicViewToLightProj,
uniform float4 lightParams,
uniform float shadowSoftness ) : COLOR0
@ -101,6 +103,11 @@ float4 main( ConvexConnectP IN,
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
shadowCoord.y = 1.0f - shadowCoord.y;
// Get the dynamic shadow texture coordinate
float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) );
float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
#ifdef NO_SHADOW
float shadowed = 1.0;
@ -110,23 +117,32 @@ float4 main( ConvexConnectP IN,
// Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynshadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif // !NO_SHADOW
float3 lightcol = lightColor.rgb;
#ifdef USE_COOKIE_TEX
// Lookup the cookie sample.
float4 cookie = tex2D( cookieMap, shadowCoord );
// Multiply the light with the cookie tex.
lightColor.rgb *= cookie.rgb;
lightcol *= cookie.rgb;
// Use a maximum channel luminance to attenuate
// the lighting else we get specular in the dark
@ -144,7 +160,7 @@ float4 main( ConvexConnectP IN,
normalize( -eyeRay ) ) * lightBrightness * atten * shadowed;
float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness;
float3 lightColorOut = lightMapParams.rgb * lightColor.rgb;
float3 lightColorOut = lightMapParams.rgb * lightcol;
float4 addToResult = 0.0;
// TODO: This needs to be removed when lightmapping is disabled

View file

@ -30,68 +30,31 @@
#include "softShadow.hlsl"
uniform sampler2D ShadowMap : register(S1);
uniform sampler2D shadowMap : register(S1);
uniform sampler2D dynamicShadowMap : register(S2);
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask : register(S2);
uniform sampler2D ssaoMask : register(S3);
uniform float4 rtParams2;
#endif
float4 main( FarFrustumQuadConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform float3 lightDirection,
uniform float4 lightColor,
uniform float lightBrightness,
uniform float4 lightAmbient,
uniform float3 eyePosWorld,
uniform float4x4 worldToLightProj,
uniform float4 scaleX,
uniform float4 scaleY,
uniform float4 offsetX,
uniform float4 offsetY,
uniform float4 atlasXOffset,
uniform float4 atlasYOffset,
uniform float2 atlasScale,
uniform float4 zNearFarInvNearFar,
uniform float4 lightMapParams,
uniform float2 fadeStartLength,
uniform float4 farPlaneScalePSSM,
uniform float4 overDarkPSSM,
uniform float shadowSoftness ) : COLOR0
float4 AL_VectorLightShadowCast( sampler2D sourceShadowMap,
float2 texCoord,
float4x4 worldToLightProj,
float4 worldPos,
float4 scaleX,
float4 scaleY,
float4 offsetX,
float4 offsetY,
float4 farPlaneScalePSSM,
float4 atlasXOffset,
float4 atlasYOffset,
float2 atlasScale,
float shadowSoftness,
float dotNL ,
float4 overDarkPSSM
)
{
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
float3 normal = prepassSample.rgb;
float depth = prepassSample.a;
// Use eye ray to get ws pos
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
// Get the light attenuation.
float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
float3 debugColor = 0;
#endif
#ifdef NO_SHADOW
// Fully unshadowed.
float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = 1.0;
#endif
#else
// Compute shadow map coordinate
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
@ -132,6 +95,11 @@ float4 main( FarFrustumQuadConnectP IN,
else
finalMask = float4(0, 0, 0, 1);
float3 debugColor = float3(0,0,0);
#ifdef NO_SHADOW
debugColor = float3(1.0,1.0,1.0);
#endif
#ifdef PSSM_DEBUG_RENDER
if ( finalMask.x > 0 )
@ -174,19 +142,125 @@ float4 main( FarFrustumQuadConnectP IN,
// Each split has a different far plane, take this into account.
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
distToLight *= farPlaneScale;
return float4(debugColor,
softShadow_filter( sourceShadowMap,
texCoord,
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) ) );
};
float4 main( FarFrustumQuadConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform float3 lightDirection,
uniform float4 lightColor,
uniform float lightBrightness,
uniform float4 lightAmbient,
uniform float4x4 eyeMat,
uniform float3 eyePosWorld,
uniform float4 atlasXOffset,
uniform float4 atlasYOffset,
uniform float2 atlasScale,
uniform float4 zNearFarInvNearFar,
uniform float4 lightMapParams,
uniform float2 fadeStartLength,
uniform float4 overDarkPSSM,
uniform float shadowSoftness,
// Static Shadows
uniform float4x4 worldToLightProj,
uniform float4 scaleX,
uniform float4 scaleY,
uniform float4 offsetX,
uniform float4 offsetY,
uniform float4 farPlaneScalePSSM,
// Dynamic Shadows
uniform float4x4 dynamicWorldToLightProj,
uniform float4 dynamicScaleX,
uniform float4 dynamicScaleY,
uniform float4 dynamicOffsetX,
uniform float4 dynamicOffsetY,
uniform float4 dynamicFarPlaneScalePSSM
) : COLOR0
{
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
float3 normal = prepassSample.rgb;
float depth = prepassSample.a;
// Use eye ray to get ws pos
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
// Get the light attenuation.
float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
float3 debugColor = float3(0,0,0);
#endif
#ifdef NO_SHADOW
// Fully unshadowed.
float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = float3(1.0,1.0,1.0);
#endif
#else
float shadowed = softShadow_filter( ShadowMap,
IN.uv0.xy,
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) );
float4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
IN.uv0.xy,
worldToLightProj,
worldPos,
scaleX, scaleY,
offsetX, offsetY,
farPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
IN.uv0.xy,
dynamicWorldToLightProj,
worldPos,
dynamicScaleX, dynamicScaleY,
dynamicOffsetX, dynamicOffsetY,
dynamicFarPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
float static_shadowed = static_shadowed_colors.a;
float dynamic_shadowed = dynamic_shadowed_colors.a;
#ifdef PSSM_DEBUG_RENDER
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
#endif
// Fade out the shadow at the end of the range.
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
shadowed = lerp( shadowed, 1.0, saturate( fadeOutAmt ) );
static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) );
dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
// temp for debugging. uncomment one or the other.
//float shadowed = static_shadowed;
//float shadowed = dynamic_shadowed;
float shadowed = min(static_shadowed, dynamic_shadowed);
#ifdef PSSM_DEBUG_RENDER
if ( fadeOutAmt > 1.0 )

View file

@ -3309,7 +3309,7 @@
HorizSizing = "width";
VertSizing = "bottom";
Position = "0 0";
Extent = "210 71";
Extent = "210 89";
new GuiPopUpMenuCtrl() {
internalName = "blendingTypePopUp";
@ -3480,7 +3480,7 @@
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
tooltipprofile = "ToolsGuiDefaultProfile";
ToolTip = "Alows object to cast shadows.";
ToolTip = "Object casts shadows.";
hovertime = "1000";
text = "Cast Shadows";
groupNum = "-1";
@ -3488,6 +3488,29 @@
useMouseEvents = "0";
useInactiveState = "0";
};
new GuiCheckBoxCtrl() {
canSaveDynamicFields = "0";
internalName = "castDynamicShadows";
Enabled = "1";
isContainer = "0";
Profile = "ToolsGuiCheckBoxProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "3 70";
Extent = "112 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"castDynamicShadows\", $ThisControl.getValue());";
tooltipprofile = "ToolsGuiDefaultProfile";
ToolTip = "Object casts dynamic shadows.";
hovertime = "1000";
text = "Dynamic Shadows";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
useInactiveState = "0";
};
new GuiCheckBoxCtrl() {
canSaveDynamicFields = "0";
internalName = "doubleSidedCheckBox";

View file

@ -754,6 +754,7 @@ function MaterialEditorGui::guiSync( %this, %material )
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
MaterialEditorPropertiesWindow-->castDynamicShadows.setValue((%material).castDynamicShadows);
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
switch$((%material).translucentBlendOp)

View file

@ -29,6 +29,7 @@ singleton Material(Cheetah_Main)
translucentBlendOp = "None";
normalMap[0] = "art/shapes/Cheetah/Cheetah_N";
specularMap[0] = "art/shapes/Cheetah/Cheetah_S";
castDynamicShadows = true;
};
singleton Material(Cheetah_TailLights)

View file

@ -35,6 +35,7 @@ singleton Material(Mat_Soldier_Main)
doubleSided = false;
translucent = false;
showFootprints = "0";
castDynamicShadows = true;
materialTag0 = "Player";
};
@ -55,6 +56,7 @@ singleton Material(Mat_Soldier_Dazzle)
emissive[0] = "1";
castShadows = "0";
showFootprints = "0";
castDynamicShadows = true;
materialTag0 = "Player";
};

View file

@ -38,6 +38,7 @@ singleton Material(grenade_grenade)
doubleSided = false;
translucent = false;
translucentBlendOp = "None";
castDynamicShadows = true;
materialTag0 = "Weapon";
};

View file

@ -41,6 +41,7 @@ singleton Material(Lurker_Base)
specularPower[0] = "10";
translucentBlendOp = "None";
useAnisotropic[0] = "1";
castDynamicShadows = true;
};
singleton Material(Lurker_MuzzleFlash_Base)

View file

@ -31,6 +31,7 @@ singleton Material(ProxMine_Base)
pixelSpecular[0] = "1";
specularMap[0] = "ProxMine_S.dds";
useAnisotropic[0] = "1";
castDynamicShadows = true;
};
singleton Material(ProxMine_Glow_Base)

View file

@ -31,6 +31,7 @@ singleton Material(FP_Ryder_Base)
translucentBlendOp = "None";
pixelSpecular[0] = "1";
useAnisotropic[0] = "1";
castDynamicShadows = true;
};
singleton Material(TP_Ryder_Base)
@ -43,6 +44,7 @@ singleton Material(TP_Ryder_Base)
specularPower[0] = "10";
translucentBlendOp = "None";
pixelSpecular[0] = "1";
castDynamicShadows = true;
};
singleton Material(Ryder_MuzzleFlash_Base)

View file

@ -31,6 +31,7 @@ singleton Material(Turret_Base)
pixelSpecular[0] = "1";
specularMap[0] = "art/shapes/weapons/Turret/Turret_D.dds";
useAnisotropic[0] = "1";
castDynamicShadows = true;
materialTag0 = "Weapon";
};
@ -53,6 +54,7 @@ singleton Material(Turret_Lazer_Base)
waveFreq[0] = "0";
waveAmp[0] = "0";
castShadows = "1";
castDynamicShadows = true;
translucentZWrite = "0";
materialTag0 = "Weapon";
materialTag1 = "FX";
@ -68,6 +70,7 @@ singleton Material(Turret_Lazer_Base)
glow[0] = "1";
emissive[0] = "1";
translucentBlendOp = "Add";
castDynamicShadows = true;
};
singleton Material(CollisionMat)

View file

@ -62,9 +62,10 @@ new ShaderData( AL_VectorLightShader )
OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/vectorLightP.glsl";
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$ShadowMap";
samplerNames[2] = "$ssaoMask";
samplerNames[3] = "$gTapRotationTex";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$ssaoMask";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -75,7 +76,8 @@ new CustomMaterial( AL_VectorLightMaterial )
stateBlock = AL_VectorLightState;
sampler["prePassBuffer"] = "#prepass";
sampler["ShadowMap"] = "$dynamiclight";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["ssaoMask"] = "#ssaoMask";
target = "lightinfo";
@ -128,8 +130,9 @@ new ShaderData( AL_PointLightShader )
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$cookieMap";
samplerNames[3] = "$gTapRotationTex";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$cookieMap";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -141,6 +144,7 @@ new CustomMaterial( AL_PointLightMaterial )
sampler["prePassBuffer"] = "#prepass";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["cookieMap"] = "$dynamiclightmask";
target = "lightinfo";
@ -159,8 +163,9 @@ new ShaderData( AL_SpotLightShader )
samplerNames[0] = "$prePassBuffer";
samplerNames[1] = "$shadowMap";
samplerNames[2] = "$cookieMap";
samplerNames[3] = "$gTapRotationTex";
samplerNames[2] = "$dynamicShadowMap";
samplerNames[3] = "$cookieMap";
samplerNames[4] = "$gTapRotationTex";
pixVersion = 3.0;
};
@ -172,6 +177,7 @@ new CustomMaterial( AL_SpotLightMaterial )
sampler["prePassBuffer"] = "#prepass";
sampler["shadowMap"] = "$dynamiclight";
sampler["dynamicShadowMap"] = "$dynamicShadowMap";
sampler["cookieMap"] = "$dynamiclightmask";
target = "lightinfo";

View file

@ -28,6 +28,7 @@
#include "../../../gl/lighting.glsl"
#include "../../shadowMap/shadowMapIO_GLSL.h"
#include "softShadow.glsl"
#include "../../../gl/torque.glsl"
in vec4 wsEyeDir;
in vec4 ssPos;
@ -107,6 +108,7 @@ uniform sampler2D prePassBuffer;
uniform samplerCube shadowMap;
#else
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
#endif
uniform vec4 rtParams0;
@ -119,6 +121,7 @@ uniform vec2 lightAttenuation;
uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform mat3 viewToLightProj;
uniform mat3 dynamicViewToLightProj;
uniform vec4 lightParams;
uniform float shadowSoftness;
@ -175,7 +178,7 @@ void main()
vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -183,6 +186,16 @@ void main()
nDotL,
lightParams.y );
vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy;
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynamicShadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif
#endif // !NO_SHADOW

View file

@ -27,6 +27,7 @@
#include "shadergen:/autogenConditioners.h"
#include "softShadow.glsl"
#include "../../../gl/lighting.glsl"
#include "../../../gl/torque.glsl"
in vec4 wsEyeDir;
in vec4 ssPos;
@ -45,6 +46,7 @@ uniform sampler2D cookieMap;
uniform sampler2D prePassBuffer;
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
uniform vec4 rtParams0;
@ -59,6 +61,7 @@ uniform vec4 lightMapParams;
uniform vec4 vsFarPlane;
uniform mat4 viewToLightProj;
uniform mat4 dynamicViewToLightProj;
uniform vec4 lightParams;
uniform float shadowSoftness;
@ -70,7 +73,7 @@ void main()
// Compute scene UV
vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w;
vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
vec3 normal = prepassSample.rgb;
@ -102,6 +105,10 @@ void main()
vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
shadowCoord.y = 1.0f - shadowCoord.y;
// Get the dynamic shadow texture coordinate
vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) );
vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 );
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
#ifdef NO_SHADOW
float shadowed = 1.0;
@ -111,7 +118,7 @@ void main()
// Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -119,6 +126,14 @@ void main()
nDotL,
lightParams.y );
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynshadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif // !NO_SHADOW
vec3 lightcol = lightColor.rgb;

View file

@ -34,38 +34,162 @@ in vec2 uv0;
in vec3 wsEyeRay;
in vec3 vsEyeRay;
uniform sampler2D ShadowMap ;
uniform sampler2D shadowMap;
uniform sampler2D dynamicShadowMap;
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask ;
uniform vec4 rtParams2;
#endif
uniform sampler2D prePassBuffer;
uniform sampler2D prePassBuffer;
uniform vec3 lightDirection;
uniform vec4 lightColor;
uniform float lightBrightness;
uniform vec4 lightAmbient;
uniform vec3 eyePosWorld;
uniform mat4x4 worldToLightProj;
uniform vec4 scaleX;
uniform vec4 scaleY;
uniform vec4 offsetX;
uniform vec4 offsetY;
uniform mat4x4 eyeMat;
uniform vec4 atlasXOffset;
uniform vec4 atlasYOffset;
uniform vec2 atlasScale;
uniform vec4 zNearFarInvNearFar;
uniform vec4 lightMapParams;
uniform vec2 fadeStartLength;
uniform vec4 farPlaneScalePSSM;
uniform vec4 overDarkPSSM;
uniform float shadowSoftness;
//static shadowMap
uniform mat4x4 worldToLightProj;
uniform vec4 scaleX;
uniform vec4 scaleY;
uniform vec4 offsetX;
uniform vec4 offsetY;
uniform vec4 farPlaneScalePSSM;
//dynamic shadowMap
uniform mat4x4 dynamicWorldToLightProj;
uniform vec4 dynamicScaleX;
uniform vec4 dynamicScaleY;
uniform vec4 dynamicOffsetX;
uniform vec4 dynamicOffsetY;
uniform vec4 dynamicFarPlaneScalePSSM;
vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap,
vec2 _texCoord,
mat4 _worldToLightProj,
vec4 _worldPos,
vec4 _scaleX, vec4 _scaleY,
vec4 _offsetX, vec4 _offsetY,
vec4 _farPlaneScalePSSM,
vec4 _atlasXOffset, vec4 _atlasYOffset,
vec2 _atlasScale,
float _shadowSoftness,
float _dotNL ,
vec4 _overDarkPSSM
)
{
// Compute shadow map coordinate
vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
// Distance to light, in shadowMap space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.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);
else
finalMask = vec4(0, 0, 0, 1);
vec3 debugColor = vec3(0);
#ifdef NO_SHADOW
debugColor = vec3(1.0);
#endif
#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
// 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);
vec2 finalOffset;
finalOffset.x = dot(finalMask, _offsetX);
finalOffset.y = dot(finalMask, _offsetY);
vec2 shadowCoord;
shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Convert to _texCoord space
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Move around inside of atlas
vec2 aOffset;
aOffset.x = dot(finalMask, _atlasXOffset);
aOffset.y = dot(finalMask, _atlasYOffset);
shadowCoord *= _atlasScale;
shadowCoord += aOffset;
// Each split has a different far plane, take this into account.
float farPlaneScale = dot( _farPlaneScalePSSM, finalMask );
distToLight *= farPlaneScale;
return vec4(debugColor,
softShadow_filter( _sourceshadowMap,
_texCoord,
shadowCoord,
farPlaneScale * _shadowSoftness,
distToLight,
_dotNL,
dot( finalMask, _overDarkPSSM ) ) );
}
out vec4 OUT_col;
void main()
{
{
// Sample/unpack the normal/z data
vec4 prepassSample = prepassUncondition( prePassBuffer, uv0 );
vec3 normal = prepassSample.rgb;
@ -92,102 +216,52 @@ void main()
#else
// Compute shadow map coordinate
vec4 pxlPosLightProj = tMul(worldToLightProj, worldPos);
vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
uv0.xy,
worldToLightProj,
worldPos,
scaleX, scaleY,
offsetX, offsetY,
farPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
// Distance to light, in shadowmap space
float distToLight = pxlPosLightProj.z / pxlPosLightProj.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;
vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
uv0.xy,
dynamicWorldToLightProj,
worldPos,
dynamicScaleX, dynamicScaleY,
dynamicOffsetX, dynamicOffsetY,
dynamicFarPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
// 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);
else
finalMask = vec4(0, 0, 0, 1);
float static_shadowed = static_shadowed_colors.a;
float dynamic_shadowed = dynamic_shadowed_colors.a;
#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 );
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
#endif
// 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);
vec2 finalOffset;
finalOffset.x = dot(finalMask, offsetX);
finalOffset.y = dot(finalMask, offsetY);
vec2 shadowCoord;
shadowCoord = baseShadowCoord * finalScale;
shadowCoord += finalOffset;
// Convert to texcoord space
shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5);
shadowCoord.y = 1.0f - shadowCoord.y;
// Move around inside of atlas
vec2 aOffset;
aOffset.x = dot(finalMask, atlasXOffset);
aOffset.y = dot(finalMask, atlasYOffset);
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, saturate( fadeOutAmt ) );
static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) );
dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
// temp for debugging. uncomment one or the other.
//float shadowed = static_shadowed;
//float shadowed = dynamic_shadowed;
float shadowed = min(static_shadowed, dynamic_shadowed);
#ifdef PSSM_DEBUG_RENDER
if ( fadeOutAmt > 1.0 )
debugColor = vec3(1.0);
@ -228,7 +302,7 @@ void main()
#ifdef PSSM_DEBUG_RENDER
lightColorOut = debugColor;
#endif
OUT_col = lightinfoCondition( lightColorOut, Sat_NL_Att, specular, addToResult );
}

View file

@ -27,7 +27,7 @@
#include "../../lighting.hlsl"
#include "../shadowMap/shadowMapIO_HLSL.h"
#include "softShadow.hlsl"
#include "../../torque.hlsl"
struct ConvexConnectP
{
@ -40,7 +40,7 @@ struct ConvexConnectP
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
uniform samplerCUBE cookieMap : register(S2);
uniform samplerCUBE cookieMap : register(S3);
#endif
@ -114,6 +114,7 @@ float4 main( ConvexConnectP IN,
uniform samplerCUBE shadowMap : register(S1),
#else
uniform sampler2D shadowMap : register(S1),
uniform sampler2D dynamicShadowMap : register(S2),
#endif
uniform float4 rtParams0,
@ -127,6 +128,7 @@ float4 main( ConvexConnectP IN,
uniform float4 vsFarPlane,
uniform float3x3 viewToLightProj,
uniform float3x3 dynamicViewToLightProj,
uniform float4 lightParams,
uniform float shadowSoftness ) : COLOR0
@ -134,7 +136,7 @@ float4 main( ConvexConnectP IN,
// Compute scene UV
float3 ssPos = IN.ssPos.xyz / IN.ssPos.w;
float2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, uvScene );
float3 normal = prepassSample.rgb;
@ -178,9 +180,9 @@ float4 main( ConvexConnectP IN,
#else
// Static
float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
@ -188,6 +190,18 @@ float4 main( ConvexConnectP IN,
nDotL,
lightParams.y );
// Dynamic
float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy;
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynamicShadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif
#endif // !NO_SHADOW

View file

@ -69,7 +69,7 @@ static float2 sNonUniformTaps[NUM_PRE_TAPS] =
/// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps.
uniform sampler2D gTapRotationTex : register(S3);
uniform sampler2D gTapRotationTex : register(S4);
float softShadow_sampleTaps( sampler2D shadowMap,

View file

@ -27,7 +27,7 @@
#include "../../lighting.hlsl"
#include "../shadowMap/shadowMapIO_HLSL.h"
#include "softShadow.hlsl"
#include "../../torque.hlsl"
struct ConvexConnectP
{
@ -39,7 +39,7 @@ struct ConvexConnectP
#ifdef USE_COOKIE_TEX
/// The texture for cookie rendering.
uniform sampler2D cookieMap : register(S2);
uniform sampler2D cookieMap : register(S3);
#endif
@ -48,6 +48,7 @@ float4 main( ConvexConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform sampler2D shadowMap : register(S1),
uniform sampler2D dynamicShadowMap : register(S2),
uniform float4 rtParams0,
@ -62,6 +63,7 @@ float4 main( ConvexConnectP IN,
uniform float4 vsFarPlane,
uniform float4x4 viewToLightProj,
uniform float4x4 dynamicViewToLightProj,
uniform float4 lightParams,
uniform float shadowSoftness ) : COLOR0
@ -101,6 +103,11 @@ float4 main( ConvexConnectP IN,
float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
shadowCoord.y = 1.0f - shadowCoord.y;
// Get the dynamic shadow texture coordinate
float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) );
float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
dynshadowCoord.y = 1.0f - dynshadowCoord.y;
#ifdef NO_SHADOW
float shadowed = 1.0;
@ -110,14 +117,22 @@ float4 main( ConvexConnectP IN,
// Get a linear depth from the light source.
float distToLight = pxlPosLightProj.z / lightRange;
float shadowed = softShadow_filter( shadowMap,
float static_shadowed = softShadow_filter( shadowMap,
ssPos.xy,
shadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float dynamic_shadowed = softShadow_filter( dynamicShadowMap,
ssPos.xy,
dynshadowCoord,
shadowSoftness,
distToLight,
nDotL,
lightParams.y );
float shadowed = min(static_shadowed, dynamic_shadowed);
#endif // !NO_SHADOW
float3 lightcol = lightColor.rgb;

View file

@ -30,68 +30,31 @@
#include "softShadow.hlsl"
uniform sampler2D ShadowMap : register(S1);
uniform sampler2D shadowMap : register(S1);
uniform sampler2D dynamicShadowMap : register(S2);
#ifdef USE_SSAO_MASK
uniform sampler2D ssaoMask : register(S2);
uniform float4 rtParams2;
uniform sampler2D ssaoMask : register(S3);
uniform float4 rtParams3;
#endif
float4 main( FarFrustumQuadConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform float3 lightDirection,
uniform float4 lightColor,
uniform float lightBrightness,
uniform float4 lightAmbient,
uniform float3 eyePosWorld,
uniform float4x4 worldToLightProj,
uniform float4 scaleX,
uniform float4 scaleY,
uniform float4 offsetX,
uniform float4 offsetY,
uniform float4 atlasXOffset,
uniform float4 atlasYOffset,
uniform float2 atlasScale,
uniform float4 zNearFarInvNearFar,
uniform float4 lightMapParams,
uniform float2 fadeStartLength,
uniform float4 farPlaneScalePSSM,
uniform float4 overDarkPSSM,
uniform float shadowSoftness ) : COLOR0
float4 AL_VectorLightShadowCast( sampler2D sourceShadowMap,
float2 texCoord,
float4x4 worldToLightProj,
float4 worldPos,
float4 scaleX,
float4 scaleY,
float4 offsetX,
float4 offsetY,
float4 farPlaneScalePSSM,
float4 atlasXOffset,
float4 atlasYOffset,
float2 atlasScale,
float shadowSoftness,
float dotNL ,
float4 overDarkPSSM
)
{
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
float3 normal = prepassSample.rgb;
float depth = prepassSample.a;
// Use eye ray to get ws pos
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
// Get the light attenuation.
float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
float3 debugColor = 0;
#endif
#ifdef NO_SHADOW
// Fully unshadowed.
float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = 1.0;
#endif
#else
// Compute shadow map coordinate
float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
@ -132,6 +95,11 @@ float4 main( FarFrustumQuadConnectP IN,
else
finalMask = float4(0, 0, 0, 1);
float3 debugColor = float3(0,0,0);
#ifdef NO_SHADOW
debugColor = float3(1.0,1.0,1.0);
#endif
#ifdef PSSM_DEBUG_RENDER
if ( finalMask.x > 0 )
@ -174,19 +142,125 @@ float4 main( FarFrustumQuadConnectP IN,
// Each split has a different far plane, take this into account.
float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
distToLight *= farPlaneScale;
return float4(debugColor,
softShadow_filter( sourceShadowMap,
texCoord,
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) ) );
};
float4 main( FarFrustumQuadConnectP IN,
uniform sampler2D prePassBuffer : register(S0),
uniform float3 lightDirection,
uniform float4 lightColor,
uniform float lightBrightness,
uniform float4 lightAmbient,
uniform float4x4 eyeMat,
uniform float3 eyePosWorld,
uniform float4 atlasXOffset,
uniform float4 atlasYOffset,
uniform float2 atlasScale,
uniform float4 zNearFarInvNearFar,
uniform float4 lightMapParams,
uniform float2 fadeStartLength,
uniform float4 overDarkPSSM,
uniform float shadowSoftness,
// Static Shadows
uniform float4x4 worldToLightProj,
uniform float4 scaleX,
uniform float4 scaleY,
uniform float4 offsetX,
uniform float4 offsetY,
uniform float4 farPlaneScalePSSM,
// Dynamic Shadows
uniform float4x4 dynamicWorldToLightProj,
uniform float4 dynamicScaleX,
uniform float4 dynamicScaleY,
uniform float4 dynamicOffsetX,
uniform float4 dynamicOffsetY,
uniform float4 dynamicFarPlaneScalePSSM
) : COLOR0
{
// Sample/unpack the normal/z data
float4 prepassSample = prepassUncondition( prePassBuffer, IN.uv0 );
float3 normal = prepassSample.rgb;
float depth = prepassSample.a;
// Use eye ray to get ws pos
float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
// Get the light attenuation.
float dotNL = dot(-lightDirection, normal);
#ifdef PSSM_DEBUG_RENDER
float3 debugColor = float3(0,0,0);
#endif
#ifdef NO_SHADOW
// Fully unshadowed.
float shadowed = 1.0;
#ifdef PSSM_DEBUG_RENDER
debugColor = float3(1.0,1.0,1.0);
#endif
#else
float shadowed = softShadow_filter( ShadowMap,
IN.uv0.xy,
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) );
float4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap,
IN.uv0.xy,
worldToLightProj,
worldPos,
scaleX, scaleY,
offsetX, offsetY,
farPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap,
IN.uv0.xy,
dynamicWorldToLightProj,
worldPos,
dynamicScaleX, dynamicScaleY,
dynamicOffsetX, dynamicOffsetY,
dynamicFarPlaneScalePSSM,
atlasXOffset, atlasYOffset,
atlasScale,
shadowSoftness,
dotNL,
overDarkPSSM);
float static_shadowed = static_shadowed_colors.a;
float dynamic_shadowed = dynamic_shadowed_colors.a;
#ifdef PSSM_DEBUG_RENDER
debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
#endif
// Fade out the shadow at the end of the range.
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
shadowed = lerp( shadowed, 1.0, saturate( fadeOutAmt ) );
static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) );
dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
// temp for debugging. uncomment one or the other.
//float shadowed = static_shadowed;
//float shadowed = dynamic_shadowed;
float shadowed = min(static_shadowed, dynamic_shadowed);
#ifdef PSSM_DEBUG_RENDER
if ( fadeOutAmt > 1.0 )
@ -221,7 +295,7 @@ float4 main( FarFrustumQuadConnectP IN,
// Sample the AO texture.
#ifdef USE_SSAO_MASK
float ao = 1.0 - tex2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams2 ) ).r;
float ao = 1.0 - tex2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r;
addToResult *= ao;
#endif

View file

@ -3309,7 +3309,7 @@
HorizSizing = "width";
VertSizing = "bottom";
Position = "0 0";
Extent = "210 71";
Extent = "210 89";
new GuiPopUpMenuCtrl() {
internalName = "blendingTypePopUp";
@ -3480,7 +3480,7 @@
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"castShadows\", $ThisControl.getValue());";
tooltipprofile = "ToolsGuiDefaultProfile";
ToolTip = "Alows object to cast shadows.";
ToolTip = "Object casts shadows.";
hovertime = "1000";
text = "Cast Shadows";
groupNum = "-1";
@ -3488,6 +3488,29 @@
useMouseEvents = "0";
useInactiveState = "0";
};
new GuiCheckBoxCtrl() {
canSaveDynamicFields = "0";
internalName = "castDynamicShadows";
Enabled = "1";
isContainer = "0";
Profile = "ToolsGuiCheckBoxProfile";
HorizSizing = "right";
VertSizing = "bottom";
position = "3 70";
Extent = "112 16";
MinExtent = "8 2";
canSave = "1";
Visible = "1";
Command = "MaterialEditorGui.updateActiveMaterial(\"castDynamicShadows\", $ThisControl.getValue());";
tooltipprofile = "ToolsGuiDefaultProfile";
ToolTip = "Object casts dynamic shadows.";
hovertime = "1000";
text = "Dynamic Shadows";
groupNum = "-1";
buttonType = "ToggleButton";
useMouseEvents = "0";
useInactiveState = "0";
};
new GuiCheckBoxCtrl() {
canSaveDynamicFields = "0";
internalName = "doubleSidedCheckBox";

View file

@ -754,6 +754,7 @@ function MaterialEditorGui::guiSync( %this, %material )
MaterialEditorPropertiesWindow-->transZWriteCheckBox.setValue((%material).translucentZWrite);
MaterialEditorPropertiesWindow-->alphaTestCheckBox.setValue((%material).alphaTest);
MaterialEditorPropertiesWindow-->castShadows.setValue((%material).castShadows);
MaterialEditorPropertiesWindow-->castDynamicShadows.setValue((%material).castDynamicShadows);
MaterialEditorPropertiesWindow-->translucentCheckbox.setValue((%material).translucent);
switch$((%material).translucentBlendOp)