|
|
|
|
|
|
sd.viewBias.w = shadowContext.shadowDatas[index].viewBias.w; |
|
|
|
} |
|
|
|
|
|
|
|
int EvalShadow_GetSplitIndex( ShadowContext shadowContext, int index, real3 positionWS, out uint payloadOffset, out real alpha ) |
|
|
|
int EvalShadow_GetSplitIndex( ShadowContext shadowContext, int index, real3 positionWS, out uint payloadOffset, out real alpha, out int cascadeCount ) |
|
|
|
{ |
|
|
|
payloadOffset = shadowContext.shadowDatas[index].payloadOffset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
payloadOffset = shadowContext.shadowDatas[index].payloadOffset + kMaxShadowCascades; |
|
|
|
real3 cascadeDir = asfloat( shadowContext.payloads[payloadOffset].xyz ); |
|
|
|
cascadeCount = shadowContext.payloads[payloadOffset].w; |
|
|
|
payloadOffset++; |
|
|
|
real border = asfloat( shadowContext.payloads[payloadOffset][shadowSplitIndex] ); |
|
|
|
payloadOffset++; |
|
|
|
|
|
|
real EvalShadow_CascadedDepth_Blend( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L ) |
|
|
|
{ |
|
|
|
// load the right shadow data for the current face |
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha ); |
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int cascadeCount; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < 0 ) |
|
|
|
return 1.0; |
|
|
|
|
|
|
real shadow1 = 1.0; |
|
|
|
|
|
|
|
shadowSplitIndex++; |
|
|
|
if( shadowSplitIndex < kMaxShadowCascades ) |
|
|
|
if( shadowSplitIndex < cascadeCount ) |
|
|
|
{ |
|
|
|
shadow1 = shadow; |
|
|
|
|
|
|
|
|
|
|
{ \ |
|
|
|
uint payloadOffset; \ |
|
|
|
real alpha; \ |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha ); \ |
|
|
|
int cascadeCount; \ |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); \ |
|
|
|
\ |
|
|
|
if( shadowSplitIndex < 0 ) \ |
|
|
|
return 1.0; \ |
|
|
|
|
|
|
real shadow1 = 1.0; \ |
|
|
|
\ |
|
|
|
shadowSplitIndex++; \ |
|
|
|
if( shadowSplitIndex < kMaxShadowCascades ) \ |
|
|
|
if( shadowSplitIndex < cascadeCount ) \ |
|
|
|
{ \ |
|
|
|
shadow1 = shadow; \ |
|
|
|
\ |
|
|
|
|
|
|
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real3 L ) |
|
|
|
{ |
|
|
|
// load the right shadow data for the current face |
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha); |
|
|
|
|
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int cascadeCount; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < 0 ) |
|
|
|
return 1.0; |
|
|
|
|
|
|
|
|
|
|
// get shadowmap texcoords |
|
|
|
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false ); |
|
|
|
|
|
|
|
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); |
|
|
|
int nextSplit = min( shadowSplitIndex+1, cascadeCount-1 ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) ) |
|
|
|
{ |
|
|
|
|
|
|
// sample the texture |
|
|
|
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS ); |
|
|
|
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithm, texIdx, sampIdx ); |
|
|
|
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); |
|
|
|
return shadowSplitIndex < (cascadeCount-1) ? shadow : lerp( shadow, 1.0, alpha ); |
|
|
|
} |
|
|
|
|
|
|
|
#define EvalShadow_CascadedDepth_( _samplerType ) \ |
|
|
|
|
|
|
uint payloadOffset; \ |
|
|
|
real alpha; \ |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex(shadowContext, index, positionWS, payloadOffset, alpha ); \ |
|
|
|
int cascadeCount; \ |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); \ |
|
|
|
\ |
|
|
|
if( shadowSplitIndex < 0 ) \ |
|
|
|
return 1.0; \ |
|
|
|
|
|
|
/* get shadowmap texcoords */ \ |
|
|
|
real3 posTC = EvalShadow_GetTexcoords( sd, positionWS, false ); \ |
|
|
|
\ |
|
|
|
int nextSplit = min( shadowSplitIndex+1, kMaxShadowCascades-1 ); \ |
|
|
|
int nextSplit = min( shadowSplitIndex+1, cascadeCount-1 ); \ |
|
|
|
\ |
|
|
|
if( shadowSplitIndex != nextSplit && step( EvalShadow_hash12( posTC.xy ), alpha ) ) \ |
|
|
|
{ \ |
|
|
|
|
|
|
/* sample the texture */ \ |
|
|
|
real2 sampleBias = EvalShadow_SampleBias_Ortho( sd, normalWS ); \ |
|
|
|
real shadow = SampleShadow_SelectAlgorithm( shadowContext, sd, payloadOffset, posTC, sampleBias, shadowAlgorithms[shadowSplitIndex], tex, samp ); \ |
|
|
|
return shadowSplitIndex < (kMaxShadowCascades-1) ? shadow : lerp( shadow, 1.0, alpha ); \ |
|
|
|
return shadowSplitIndex < (cascadeCount-1) ? shadow : lerp( shadow, 1.0, alpha ); \ |
|
|
|
} \ |
|
|
|
\ |
|
|
|
real EvalShadow_CascadedDepth_Dither( ShadowContext shadowContext, uint shadowAlgorithm, Texture2DArray tex, _samplerType samp, real3 positionWS, real3 normalWS, int index, real3 L ) \ |
|
|
|
|
|
|
// load the right shadow data for the current face |
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha ); |
|
|
|
|
|
|
|
int cascadeCount; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < 0 ) |
|
|
|
return 0.0; |
|
|
|
|
|
|
|
|
|
|
// load the right shadow data for the current face |
|
|
|
uint payloadOffset; |
|
|
|
real alpha; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha ); |
|
|
|
|
|
|
|
int cascadeCount; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < 0 ) |
|
|
|
return 0.0; |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
real EvalShadow_SampleClosestDistance_Cascade( ShadowContext shadowContext, Texture2DArray tex, SamplerState sampl, |
|
|
|
real3 positionWS, real3 normalWS, int index, real4 L, out real3 nearPlanePositionWS ) |
|
|
|
real3 positionWS, real3 normalWS, int index, real4 L, out real3 nearPlanePositionWS ) |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha ); |
|
|
|
int cascadeCount; |
|
|
|
int shadowSplitIndex = EvalShadow_GetSplitIndex( shadowContext, index, positionWS, payloadOffset, alpha, cascadeCount ); |
|
|
|
|
|
|
|
if( shadowSplitIndex < 0 ) |
|
|
|
return 0.0; |
|
|
|