您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
149 行
7.1 KiB
149 行
7.1 KiB
#ifndef LIGHTLOOP_SHADOW_HLSL
|
|
#define LIGHTLOOP_SHADOW_HLSL
|
|
|
|
#define SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
|
|
#define SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
|
|
|
|
#define SHADOW_USE_VIEW_BIAS_SCALING 1 // Enable view bias scaling to mitigate light leaking across edges. Uses the light vector if SHADOW_USE_ONLY_VIEW_BASED_BIASING is defined, otherwise uses the normal.
|
|
// Note: Sample biasing work well but is very costly in term of VGPR, disable it for now
|
|
#define SHADOW_USE_SAMPLE_BIASING 0 // Enable per sample biasing for wide multi-tap PCF filters. Incompatible with SHADOW_USE_ONLY_VIEW_BASED_BIASING.
|
|
#define SHADOW_USE_DEPTH_BIAS 0 // Enable clip space z biasing
|
|
|
|
#include "ShadowContext.hlsl"
|
|
|
|
// This is an example of how to override the default dynamic resource dispatcher
|
|
// by hardcoding the resources used and calling the shadow sampling routines that take an explicit texture and sampler.
|
|
// It is the responsibility of the author to make sure that ShadowContext.hlsl binds the correct texture to the right slot,
|
|
// and that on the C# side the shadowContext bindDelegate binds the correct resource to the correct texture id.
|
|
|
|
|
|
// Caution: When updating algorithm here, think to update Lightloop.ShadowSetup() function
|
|
// (the various m_ShadowMgr.SetGlobalShadowOverride( GPUShadowType.Point, ShadowAlgorithm.PCF, ShadowVariant.V1, ShadowPrecision.High, useGlobalOverrides ));
|
|
// The enum value for the variant is in GPUShadowAlgorithm and is express like: PCF_tent_3x3 = ShadowAlgorithm.PCF << 3 | ShadowVariant.V2
|
|
|
|
//#define SHADOW_DISPATCH_USE_SEPARATE_CASCADE_ALGOS // enables separate cascade sampling variants for each cascade
|
|
//#define SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS // enables separate resources and algorithms for spot and point lights
|
|
|
|
// directional
|
|
#define SHADOW_DISPATCH_DIR_TEX 0
|
|
#define SHADOW_DISPATCH_DIR_SMP 0
|
|
#define SHADOW_DISPATCH_DIR_ALG GPUSHADOWALGORITHM_PCF_TENT_5X5 // all cascades
|
|
#define SHADOW_DISPATCH_DIR_ALG_0 GPUSHADOWALGORITHM_PCF_TENT_7X7 // 1st cascade
|
|
#define SHADOW_DISPATCH_DIR_ALG_1 GPUSHADOWALGORITHM_PCF_TENT_5X5 // 2nd cascade
|
|
#define SHADOW_DISPATCH_DIR_ALG_2 GPUSHADOWALGORITHM_PCF_TENT_3X3 // 3rd cascade
|
|
#define SHADOW_DISPATCH_DIR_ALG_3 GPUSHADOWALGORITHM_PCF_1TAP // 4th cascade
|
|
// point
|
|
#define SHADOW_DISPATCH_POINT_TEX 0
|
|
#define SHADOW_DISPATCH_POINT_SMP 0
|
|
#define SHADOW_DISPATCH_POINT_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
|
|
// spot
|
|
#define SHADOW_DISPATCH_SPOT_TEX 0
|
|
#define SHADOW_DISPATCH_SPOT_SMP 0
|
|
#define SHADOW_DISPATCH_SPOT_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
|
|
//punctual
|
|
#define SHADOW_DISPATCH_PUNC_TEX 0
|
|
#define SHADOW_DISPATCH_PUNC_SMP 0
|
|
#define SHADOW_DISPATCH_PUNC_ALG GPUSHADOWALGORITHM_PCF_TENT_3X3
|
|
|
|
// example of overriding directional lights
|
|
#ifdef SHADOW_DISPATCH_USE_CUSTOM_DIRECTIONAL
|
|
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L )
|
|
{
|
|
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_DIR_TEX];
|
|
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_DIR_SMP];
|
|
#ifdef SHADOW_DISPATCH_USE_SEPARATE_CASCADE_ALGOS
|
|
uint algo[kMaxShadowCascades] = { SHADOW_DISPATCH_DIR_ALG_0, SHADOW_DISPATCH_DIR_ALG_1, SHADOW_DISPATCH_DIR_ALG_2, SHADOW_DISPATCH_DIR_ALG_3 };
|
|
#else
|
|
uint algo = SHADOW_DISPATCH_DIR_ALG;
|
|
#endif
|
|
|
|
return EvalShadow_CascadedDepth_Blend( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L );
|
|
}
|
|
|
|
float GetDirectionalShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float2 positionSS )
|
|
{
|
|
return GetDirectionalShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L );
|
|
}
|
|
|
|
float3 GetDirectionalShadowClosestSample( ShadowContext shadowContext, real3 positionWS, real3 normalWS, int index, real4 L )
|
|
{
|
|
return EvalShadow_GetClosestSample_Cascade( shadowContext, shadowContext.tex2DArray[SHADOW_DISPATCH_DIR_TEX], positionWS, normalWS, index, L );
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
// example of overriding punctual lights
|
|
#ifdef SHADOW_DISPATCH_USE_CUSTOM_PUNCTUAL
|
|
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist )
|
|
{
|
|
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
|
|
// example for choosing different algos for point and spot lights
|
|
ShadowData sd = shadowContext.shadowDatas[shadowDataIndex];
|
|
uint shadowType;
|
|
UnpackShadowType( sd.shadowType, shadowType );
|
|
|
|
UNITY_BRANCH
|
|
if( shadowType == GPUSHADOWTYPE_POINT )
|
|
{
|
|
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_POINT_TEX];
|
|
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_POINT_SMP];
|
|
uint algo = SHADOW_DISPATCH_POINT_ALG;
|
|
return EvalShadow_PointDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
|
|
}
|
|
else
|
|
{
|
|
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_SPOT_TEX];
|
|
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_SPOT_SMP];
|
|
uint algo = SHADOW_DISPATCH_SPOT_ALG;
|
|
return EvalShadow_SpotDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
|
|
}
|
|
#else
|
|
// example for choosing the same algo
|
|
Texture2DArray tex = shadowContext.tex2DArray[SHADOW_DISPATCH_PUNC_TEX];
|
|
SamplerComparisonState compSamp = shadowContext.compSamplers[SHADOW_DISPATCH_PUNC_SMP];
|
|
uint algo = SHADOW_DISPATCH_PUNC_ALG;
|
|
return EvalShadow_PunctualDepth( shadowContext, algo, tex, compSamp, positionWS, normalWS, shadowDataIndex, L, L_dist );
|
|
#endif
|
|
}
|
|
float GetPunctualShadowAttenuation( ShadowContext shadowContext, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist, float2 positionSS )
|
|
{
|
|
return GetPunctualShadowAttenuation( shadowContext, positionWS, normalWS, shadowDataIndex, L, L_dist );
|
|
}
|
|
|
|
float3 GetPunctualShadowClosestSample( ShadowContext shadowContext, real3 positionWS, int index, real3 L )
|
|
{
|
|
return EvalShadow_GetClosestSample_Punctual( shadowContext, shadowContext.tex2DArray[SHADOW_DISPATCH_PUNC_TEX], positionWS, index, L );
|
|
}
|
|
|
|
float GetPunctualShadowClosestDistance( ShadowContext shadowContext, SamplerState sampl, real3 positionWS, int index, float3 L, float3 lightPositionWS)
|
|
{
|
|
return EvalShadow_SampleClosestDistance_Punctual( shadowContext, shadowContext.tex2DArray[SHADOW_DISPATCH_PUNC_TEX], sampl, positionWS, index, L, lightPositionWS );
|
|
}
|
|
|
|
#endif
|
|
|
|
// cleanup the defines
|
|
#undef SHADOW_DISPATCH_DIR_TEX
|
|
#undef SHADOW_DISPATCH_DIR_SMP
|
|
#undef SHADOW_DISPATCH_DIR_ALG
|
|
#undef SHADOW_DISPATCH_DIR_ALG_0
|
|
#undef SHADOW_DISPATCH_DIR_ALG_1
|
|
#undef SHADOW_DISPATCH_DIR_ALG_2
|
|
#undef SHADOW_DISPATCH_DIR_ALG_3
|
|
#undef SHADOW_DISPATCH_POINT_TEX
|
|
#undef SHADOW_DISPATCH_POINT_SMP
|
|
#undef SHADOW_DISPATCH_POINT_ALG
|
|
#undef SHADOW_DISPATCH_SPOT_TEX
|
|
#undef SHADOW_DISPATCH_SPOT_SMP
|
|
#undef SHADOW_DISPATCH_SPOT_ALG
|
|
#undef SHADOW_DISPATCH_PUNC_TEX
|
|
#undef SHADOW_DISPATCH_PUNC_SMP
|
|
#undef SHADOW_DISPATCH_PUNC_ALG
|
|
#ifdef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
|
|
#undef SHADOW_DISPATCH_USE_SEPARATE_PUNC_ALGOS
|
|
#endif
|
|
|
|
|
|
|
|
#endif // LIGHTLOOP_SHADOW_HLSL
|