Shadow tests

only works on vectorLight (eg sun and scatter sky) for now
This commit is contained in:
marauder2k7 2022-12-13 21:48:39 +00:00
parent abbfb634f3
commit 239c7e58d2
9 changed files with 182 additions and 121 deletions

View file

@ -807,7 +807,9 @@ void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const Light
const F32 innerCone = getMin(lightInfo->getInnerConeAngle(), outerCone); const F32 innerCone = getMin(lightInfo->getInnerConeAngle(), outerCone);
const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f)); const F32 outerCos = mCos(mDegToRad(outerCone / 2.0f));
const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f)); const F32 innerCos = mCos(mDegToRad(innerCone / 2.0f));
Point2F spotParams(outerCos,innerCos - outerCos); const F32 lightAngleScale = 1.0f / getMax(0.001f, (innerCos - outerCos));
const F32 lightAngleOffset = -outerCos * lightAngleScale;
Point2F spotParams(lightAngleScale, lightAngleOffset);
matParams->setSafe( lightSpotParams, spotParams ); matParams->setSafe( lightSpotParams, spotParams );
matParams->setSafe( lightDirection, lightInfo->getDirection()); matParams->setSafe( lightDirection, lightInfo->getDirection());

View file

@ -265,8 +265,16 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
{ {
S32 reg = lsc->mShadowMapSC->getSamplerRegister(); S32 reg = lsc->mShadowMapSC->getSamplerRegister();
if ( reg != -1 ) if (reg != -1)
GFX->setTexture( reg, mShadowMapTex); {
GFX->setTexture(reg, mShadowMapTex);
}
reg = lsc->mShadowMapCMPSC->getSamplerRegister();
if (reg != -1)
{
GFX->setTexture(reg, mShadowMapTex);
}
return true; return true;
} else if ( currTexFlag == Material::DynamicLightMask ) } else if ( currTexFlag == Material::DynamicLightMask )
@ -427,7 +435,8 @@ LightingShaderConstants::LightingShaderConstants()
mVectorLightDirectionSC(NULL), mVectorLightDirectionSC(NULL),
mVectorLightColorSC(NULL), mVectorLightColorSC(NULL),
mVectorLightBrightnessSC(NULL), mVectorLightBrightnessSC(NULL),
mShadowMapSC(NULL), mShadowMapSC(NULL),
mShadowMapCMPSC(NULL),
mShadowMapSizeSC(NULL), mShadowMapSizeSC(NULL),
mCookieMapSC(NULL), mCookieMapSC(NULL),
mRandomDirsConst(NULL), mRandomDirsConst(NULL),
@ -487,6 +496,7 @@ void LightingShaderConstants::init(GFXShader* shader)
mVectorLightBrightnessSC = shader->getShaderConstHandle(ShaderGenVars::vectorLightBrightness); mVectorLightBrightnessSC = shader->getShaderConstHandle(ShaderGenVars::vectorLightBrightness);
mShadowMapSC = shader->getShaderConstHandle("$shadowMap"); mShadowMapSC = shader->getShaderConstHandle("$shadowMap");
mShadowMapCMPSC = shader->getShaderConstHandle("$shadowMapCMP");
mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize"); mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
mCookieMapSC = shader->getShaderConstHandle("$cookieMap"); mCookieMapSC = shader->getShaderConstHandle("$cookieMap");

View file

@ -96,6 +96,7 @@ struct LightingShaderConstants
GFXShaderConstHandle* mVectorLightBrightnessSC; GFXShaderConstHandle* mVectorLightBrightnessSC;
GFXShaderConstHandle* mShadowMapSC; GFXShaderConstHandle* mShadowMapSC;
GFXShaderConstHandle* mShadowMapCMPSC;
GFXShaderConstHandle* mShadowMapSizeSC; GFXShaderConstHandle* mShadowMapSizeSC;
GFXShaderConstHandle* mCookieMapSC; GFXShaderConstHandle* mCookieMapSC;

View file

@ -20,6 +20,14 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
singleton GFXSamplerStateData(ShadowSampler)
{
addressModeU = GFXAddressMirror;
addressModeV = GFXAddressMirror;
magFilter = GFXTextureFilterLinear;
minFilter = GFXTextureFilterLinear;
samplerFunc = GFXCmpGreater;
};
// Vector Light State // Vector Light State
singleton GFXStateBlockData( AL_VectorLightState ) singleton GFXStateBlockData( AL_VectorLightState )
@ -44,9 +52,10 @@ singleton GFXStateBlockData( AL_VectorLightState )
samplersDefined = true; samplersDefined = true;
samplerStates[0] = SamplerClampPoint; // G-buffer samplerStates[0] = SamplerClampPoint; // G-buffer
samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.) samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.)
samplerStates[3] = SamplerWrapPoint; // gTapRotationTex Random Direction Map samplerStates[2] = SamplerWrapPoint; // gTapRotationTex Random Direction Map
samplerStates[4] = SamplerClampPoint; // colorBuffer samplerStates[3] = SamplerClampPoint; // colorBuffer
samplerStates[5] = SamplerClampPoint; // matInfoBuffer samplerStates[4] = SamplerClampPoint; // matInfoBuffer
samplerStates[5] = ShadowSampler; // Shadow Map (Do not change this to linear, as all cards can not filter equally.)
cullDefined = true; cullDefined = true;
cullMode = GFXCullNone; cullMode = GFXCullNone;
@ -69,7 +78,8 @@ singleton shaderData( AL_VectorLightShader )
samplerNames[1] = "$shadowMap"; samplerNames[1] = "$shadowMap";
samplerNames[2] = "$gTapRotationTex"; samplerNames[2] = "$gTapRotationTex";
samplerNames[3] = "$colorBuffer"; samplerNames[3] = "$colorBuffer";
samplerNames[4] = "$matInfoBuffer"; samplerNames[4] = "$matInfoBuffer";
samplerNames[5] = "$shadowMapCMP";
pixVersion = 3.0; pixVersion = 3.0;
}; };
@ -83,6 +93,7 @@ singleton CustomMaterial( AL_VectorLightMaterial )
sampler["shadowMap"] = "$dynamiclight"; sampler["shadowMap"] = "$dynamiclight";
sampler["colorBuffer"] = "#color"; sampler["colorBuffer"] = "#color";
sampler["matInfoBuffer"] = "#matinfo"; sampler["matInfoBuffer"] = "#matinfo";
sampler["shadowMapCMP"] = "$dynamiclight";
target = "AL_FormatToken"; target = "AL_FormatToken";

View file

@ -204,23 +204,21 @@ float smoothDistanceAtt ( float squaredDistance , float invSqrAttRadius )
{ {
float factor = squaredDistance * invSqrAttRadius ; float factor = squaredDistance * invSqrAttRadius ;
float smoothFactor = saturate (1.0f - factor * factor ); float smoothFactor = saturate (1.0f - factor * factor );
return sqr(smoothFactor); return smoothFactor * smoothFactor;
} }
float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius ) float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius )
{ {
float sqrDist = dot ( unormalizedLightVector , unormalizedLightVector ); float sqrDist = dot( unormalizedLightVector, unormalizedLightVector );
float attenuation = 1.0 / (max ( sqrDist , 0.01*0.01) ); float attenuation = 1.0 / sqrDist * smoothDistanceAtt ( sqrDist , invSqrAttRadius );
attenuation *= smoothDistanceAtt ( sqrDist , invSqrAttRadius );
return attenuation; return attenuation;
} }
float getSpotAngleAtt( float3 normalizedLightVector , float3 lightDir , float2 lightSpotParams ) float getSpotAngleAtt( float3 normalizedLightVector , float3 lightDir , float2 lightSpotParams, float exponent )
{ {
float cd = dot ( lightDir , normalizedLightVector ); float attenuation = clamp(dot(lightDir, normalizedLightVector) * lightSpotParams.x + lightSpotParams.y, 0.0, 1.0);
float attenuation = saturate ( ( cd - lightSpotParams.x ) / lightSpotParams.y );
// smooth the transition // smooth the transition
return sqr(attenuation); return attenuation * attenuation;
} }
float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight) float3 evaluateStandardBRDF(Surface surface, SurfaceToLight surfaceToLight)
@ -250,8 +248,11 @@ float3 getDirectionalLight(Surface surface, SurfaceToLight surfaceToLight, float
float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow) float3 getPunctualLight(Surface surface, SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow)
{ {
float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); float attenuation = 1;
float3 factor = lightColor * max(surfaceToLight.NdotL* shadow * lightIntensity * attenuation, 0.0f) ; attenuation *= getDistanceAtt(surfaceToLight.Lu, radius);
float3 lCol = lightColor.rgb *(lightIntensity / (4.0 * 3.14159265359));
float3 radince = lCol * attenuation;
float3 factor = saturate(surfaceToLight.NdotL) * shadow * radince;
return evaluateStandardBRDF(surface,surfaceToLight) * factor; return evaluateStandardBRDF(surface,surfaceToLight) * factor;
} }
@ -310,7 +311,7 @@ float4 compute4Lights( Surface surface,
//get Punctual light contribution //get Punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation //get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, inLightSpotDir[i].xyz, lightSpotParams[i].xy ); lighting *= getSpotAngleAtt(-surfaceToLight.L, inLightSpotDir[i].xyz, lightSpotParams[i].xy, lightRange );
} }
} }
finalLighting += lighting; finalLighting += lighting;

View file

@ -101,7 +101,7 @@ TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
#ifdef SHADOW_CUBE #ifdef SHADOW_CUBE
TORQUE_UNIFORM_SAMPLERCUBE(shadowMap, 1); TORQUE_UNIFORM_SAMPLERCUBE(shadowMap, 1);
#else #else
TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); TORQUE_UNIFORM_SAMPLER2DCMP(shadowMap, 1);
#endif #endif
//contains gTapRotationTex sampler //contains gTapRotationTex sampler
#include "softShadow.hlsl" #include "softShadow.hlsl"
@ -174,7 +174,8 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
#else #else
float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy; float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
float shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); float4 shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), IN.pos.xy, ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
float shadowed = shadowed_colors.a;
#endif #endif
#endif // !NO_SHADOW #endif // !NO_SHADOW

View file

@ -22,83 +22,104 @@
#include "../../shaderModel.hlsl" #include "../../shaderModel.hlsl"
#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY ) #define NUM_TAPS 16
#define NUM_PRE_TAPS 4
#define NUM_TAPS 12
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
static float2 sNonUniformTaps[NUM_TAPS] =
{
// These first 4 taps are located around the edges
// of the disk and are used to predict fully shadowed
// or unshadowed areas.
{ 0.992833, 0.979309 },
{ -0.998585, 0.985853 },
{ 0.949299, -0.882562 },
{ -0.941358, -0.893924 },
// The rest of the samples.
{ 0.545055, -0.589072 },
{ 0.346526, 0.385821 },
{ -0.260183, 0.334412 },
{ 0.248676, -0.679605 },
{ -0.569502, -0.390637 },
{ -0.614096, 0.212577 },
{ -0.259178, 0.876272 },
{ 0.649526, 0.864333 },
};
#else
#define NUM_PRE_TAPS 5
/// The non-uniform poisson disk used in the
/// high quality shadow filtering.
static float2 sNonUniformTaps[NUM_PRE_TAPS] =
{
{ 0.892833, 0.959309 },
{ -0.941358, -0.873924 },
{ -0.260183, 0.334412 },
{ 0.348676, -0.679605 },
{ -0.569502, -0.390637 },
};
#endif
/// The texture used to do per-pixel pseudorandom /// The texture used to do per-pixel pseudorandom
/// rotations of the filter taps. /// rotations of the filter taps.
TORQUE_UNIFORM_SAMPLER2D(gTapRotationTex, 2); TORQUE_UNIFORM_SAMPLER2D(gTapRotationTex, 2);
float softShadow_sampleTaps( TORQUE_SAMPLER2D(shadowMap1), float2 VogelDisk(int sampleIndex, int sampleCount, float gradient)
float2 sinCos, {
float gA = 2.4f;
float r = sqrt(sampleIndex + 0.5f) / sqrt(sampleCount);
float theta = sampleIndex * gA + gradient;
float sine, cosine;
sincos(theta, sine, cosine);
return float2(r * cosine, r * sine);
}
float GradientNoise(float2 screenPos)
{
float3 mag = float3(0.06711056f, 0.00583715f, 52.9829189f);
return frac(mag.z * frac(dot(screenPos, mag.xy)));
}
float AvgOccluderDepthPenumbra(float zShadow, float avgDepth)
{
float penumbra = (zShadow - avgDepth) / avgDepth;
penumbra *= penumbra;
return saturate(80.0f * penumbra);
}
float AvgOccluderDepthPenumbra(float lightSize, float zShadow, float avgDepth)
{
float penumbra = lightSize * (zShadow - avgDepth) / avgDepth;
return penumbra;
}
float Penumbra(TORQUE_SAMPLER2D(shadowMap2), float gradient, float2 shadowUV, float zShadow, float filterRadius, float esmFactor, int sampleCount)
{
float avgOccluderDepth = 0.0f;
float occluderCount = 0.0f;
float penumbraFilterMaxSize = 8.0 / 1024.0;
for(int i = 0; i < sampleCount; i++)
{
float2 sampleUV = VogelDisk(i, sampleCount, gradient) * penumbraFilterMaxSize;
sampleUV = shadowUV + sampleUV;
float occDepth = TORQUE_TEX2DLOD( shadowMap2, float4(sampleUV,0,0) ).r;
if(occDepth < zShadow)
{
avgOccluderDepth += occDepth;
occluderCount += 1.0f;
}
}
if(occluderCount > 0.0f)
{
avgOccluderDepth /= occluderCount;
return AvgOccluderDepthPenumbra(1000.0f, zShadow, avgOccluderDepth);
}
else
{
return 0.0f;
}
}
float softShadow_sampleTaps( TORQUE_SAMPLER2DCMP(shadowMap1),
float2 screenPos,
float2 vpos,
float2 shadowPos, float2 shadowPos,
float filterRadius, float filterRadius,
float distToLight, float distToLight,
float esmFactor, float esmFactor,
float gradient,
float penumbra,
int startTap, int startTap,
int endTap ) int endTap )
{ {
float shadow = 0; float shadow = 0;
float2 tap = 0; float2 tap = 0;
for ( int t = startTap; t < endTap; t++ )
for ( int t = 0; t < NUM_TAPS; t++ )
{ {
tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius; tap = VogelDisk(t, NUM_TAPS, gradient);
tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius; tap = shadowPos + tap * penumbra * filterRadius;
float occluder = TORQUE_TEX2DLOD( shadowMap1, float4( shadowPos + tap, 0, 0 ) ).r; float occluder = TORQUE_TEX2DCMP( shadowMap1, tap, distToLight).r;
float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); shadow += esm;
shadow += esm / float( endTap - startTap );
} }
return shadow; return shadow;
} }
float softShadow_filter( TORQUE_SAMPLER2D(shadowMap), float softShadow_filter(
TORQUE_SAMPLER2D(shadowMap),
TORQUE_SAMPLER2DCMP(shadowMapCMP),
float2 screenPos,
float2 vpos, float2 vpos,
float2 shadowPos, float2 shadowPos,
float filterRadius, float filterRadius,
@ -111,46 +132,32 @@ float softShadow_filter( TORQUE_SAMPLER2D(shadowMap),
// If softshadow is undefined then we skip any complex // If softshadow is undefined then we skip any complex
// filtering... just do a single sample ESM. // filtering... just do a single sample ESM.
float occluder = TORQUE_TEX2DLOD(shadowMap, float4(shadowPos, 0, 0)).r; float occluder = TORQUE_TEX2DLOD( shadowMap, float4(shadowPos,0,0) ).r;
float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) ); float shadow = occluder;
#else #else
// Lookup the random rotation for this screen pixel.
float2 sinCos = ( TORQUE_TEX2DLOD(gTapRotationTex, float4(vpos * 16, 0, 0)).rg - 0.5) * 2; float gradient = 6.28318530718 * GradientNoise(screenPos);
float penumbra = Penumbra(TORQUE_SAMPLER2D_MAKEARG(shadowMap), gradient, shadowPos, distToLight, filterRadius, esmFactor, NUM_TAPS);
// Do the prediction taps first. if(penumbra < 1.0)
float shadow = softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap), penumbra = 1.0;
sinCos,
shadowPos, float shadow = softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMapCMP),
filterRadius, screenPos,
distToLight, vpos,
esmFactor, shadowPos,
0, filterRadius,
NUM_PRE_TAPS ); distToLight,
esmFactor,
// We live with only the pretap results if we don't gradient,
// have high quality shadow filtering enabled. penumbra,
#ifdef SOFTSHADOW_HIGH_QUALITY 0,
NUM_TAPS );
// Only do the expensive filtering if we're really
// in a partially shadowed area. // This averages the taps above with the results
if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 ) // of the prediction samples.
{ // if you change the number of taps, this value should be set to that.
shadow += softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap), shadow = 1.0 - shadow / float(NUM_TAPS);
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 #endif // SOFTSHADOW

View file

@ -153,9 +153,16 @@ float4 main( ConvexConnectP IN ) : SV_TARGET
#endif #endif
//get Punctual light contribution //get Punctual light contribution
lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed);
//get spot angle attenuation //get spot angle attenuation
lighting *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); float att = 1;
att *= getDistanceAtt(surfaceToLight.L, lightInvSqrRange);
att *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams, lightRange);
float3 lCol = lightColor.rgb *(lightBrightness / (4.0 * 3.14159265359));
float3 radince = lCol * att;
float3 factor = saturate(surfaceToLight.NdotL) * shadowed * radince;
lighting = evaluateStandardBRDF(surface,surfaceToLight) * factor;
//
} }
return float4(lighting, 0); return float4(lighting, 0);

View file

@ -30,11 +30,11 @@
TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1); TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
//contains gTapRotationTex sampler //contains gTapRotationTex sampler
#include "softShadow.hlsl" #include "softShadow.hlsl"
TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3); TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4); TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
TORQUE_UNIFORM_SAMPLER2DCMP(shadowMapCmp, 5);
uniform float lightBrightness; uniform float lightBrightness;
uniform float3 lightDirection; uniform float3 lightDirection;
@ -65,6 +65,8 @@ uniform float4 offsetX;
uniform float4 offsetY; uniform float4 offsetY;
float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap), float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap),
TORQUE_SAMPLER2DCMP(sourceShadowMapCMP),
float2 screenPos,
float2 texCoord, float2 texCoord,
float4x4 worldToLightProj, float4x4 worldToLightProj,
float3 worldPos, float3 worldPos,
@ -163,8 +165,16 @@ float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap),
float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
distToLight *= farPlaneScale; distToLight *= farPlaneScale;
return float4(debugColor, softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap), texCoord, shadowCoord, farPlaneScale * shadowSoftness, return float4(debugColor, softShadow_filter(
distToLight, dotNL, dot( finalMask, overDarkPSSM ) ) ); TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap),
TORQUE_SAMPLER2D_MAKEARG(sourceShadowMapCMP),
screenPos,
texCoord,
shadowCoord,
farPlaneScale * shadowSoftness,
distToLight,
dotNL,
dot( finalMask, overDarkPSSM ) ) );
}; };
@ -197,8 +207,19 @@ float4 main(FarFrustumQuadConnectP IN) : SV_TARGET
float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * surface.depth); float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * surface.depth);
float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
float4 shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(shadowMap), IN.uv0.xy, worldToLightProj, surface.P, scaleX, scaleY, offsetX, offsetY, float4 shadowed_colors = AL_VectorLightShadowCast(
farPlaneScalePSSM, surfaceToLight.NdotL); TORQUE_SAMPLER2D_MAKEARG(shadowMap),
TORQUE_SAMPLER2D_MAKEARG(shadowMapCmp),
IN.hpos.xy,
IN.uv0.xy,
worldToLightProj,
surface.P,
scaleX,
scaleY,
offsetX,
offsetY,
farPlaneScalePSSM,
surfaceToLight.NdotL);
float shadow = shadowed_colors.a; float shadow = shadowed_colors.a;