2021-09-09 20:42:29 -04:00

114 lines
5.4 KiB
HLSL

#ifndef LIGHTLOOP_HD_SHADOW_HLSL
#define LIGHTLOOP_HD_SHADOW_HLSL
#define SHADOW_OPTIMIZE_REGISTER_USAGE 1
#ifndef SHADOW_AUTO_FLIP_NORMAL // If (NdotL < 0), we flip the normal to correctly bias lit back-faces (used for transmission)
#define SHADOW_AUTO_FLIP_NORMAL 1 // Externally define as 0 to disable
#endif
#ifndef SHADOW_USE_DEPTH_BIAS // Enable clip space z biasing
#define SHADOW_USE_DEPTH_BIAS 1 // Externally define as 0 to disable
#endif
#if SHADOW_OPTIMIZE_REGISTER_USAGE == 1
# pragma warning( disable : 3557 ) // loop only executes for 1 iteration(s)
#endif
# include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowContext.hlsl"
// normalWS is the vertex normal if available or shading normal use to bias the shadow position
float GetDirectionalShadowAttenuation(HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L)
{
#if SHADOW_AUTO_FLIP_NORMAL
normalWS *= FastSign(dot(normalWS, L));
#endif
#if defined(SHADOW_ULTRA_LOW) || defined(SHADOW_LOW) || defined(SHADOW_MEDIUM)
return EvalShadow_CascadedDepth_Dither(shadowContext, _ShadowmapCascadeAtlas, s_linear_clamp_compare_sampler, positionSS, positionWS, normalWS, shadowDataIndex, L);
#else
return EvalShadow_CascadedDepth_Blend(shadowContext, _ShadowmapCascadeAtlas, s_linear_clamp_compare_sampler, positionSS, positionWS, normalWS, shadowDataIndex, L);
#endif
}
float GetPunctualShadowAttenuation(HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist, bool pointLight, bool perspecive)
{
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_GAMECORE) && (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER))
shadowDataIndex = WaveReadLaneFirst(shadowDataIndex);
#endif
#if SHADOW_AUTO_FLIP_NORMAL
normalWS *= FastSign(dot(normalWS, L));
#endif
// Note: Here we assume that all the shadow map cube faces have been added contiguously in the buffer to retreive the shadow information
HDShadowData sd = shadowContext.shadowDatas[shadowDataIndex];
if (pointLight)
{
sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot0;
sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot1;
sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot2;
sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].atlasOffset;
}
if (sd.isInCachedAtlas > 0) // This is a scalar branch.
{
return EvalShadow_PunctualDepth(sd, _CachedShadowmapAtlas, s_linear_clamp_compare_sampler, positionSS, positionWS, normalWS, L, L_dist, perspecive);
}
else
{
return EvalShadow_PunctualDepth(sd, _ShadowmapAtlas, s_linear_clamp_compare_sampler, positionSS, positionWS, normalWS, L, L_dist, perspecive);
}
}
float GetPunctualShadowClosestDistance(HDShadowContext shadowContext, SamplerState sampl, real3 positionWS, int shadowDataIndex, float3 L, float3 lightPositionWS, bool pointLight)
{
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_GAMECORE) && (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER))
shadowDataIndex = WaveReadLaneFirst(shadowDataIndex);
#endif
// Note: Here we assume that all the shadow map cube faces have been added contiguously in the buffer to retreive the shadow information
// TODO: if on the light type to retrieve the good shadow data
HDShadowData sd = shadowContext.shadowDatas[shadowDataIndex];
if (pointLight)
{
sd.shadowToWorld = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].shadowToWorld;
sd.atlasOffset = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].atlasOffset;
sd.rot0 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot0;
sd.rot1 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot1;
sd.rot2 = shadowContext.shadowDatas[shadowDataIndex + CubeMapFaceID(-L)].rot2;
}
if (sd.isInCachedAtlas > 0) // This is a scalar branch.
{
return EvalShadow_SampleClosestDistance_Punctual(sd, _CachedShadowmapAtlas, sampl, positionWS, L, lightPositionWS);
}
else
{
return EvalShadow_SampleClosestDistance_Punctual(sd, _ShadowmapAtlas, sampl, positionWS, L, lightPositionWS);
}
}
float GetRectAreaShadowAttenuation(HDShadowContext shadowContext, float2 positionSS, float3 positionWS, float3 normalWS, int shadowDataIndex, float3 L, float L_dist)
{
// We need to disable the scalarization here on xbox due to bad code generated by FXC for the eye shader.
// This shouldn't have an enormous impact since with Area lights we are already exploded in VGPR by this point.
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_GAMECORE) && (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER))
shadowDataIndex = WaveReadLaneFirst(shadowDataIndex);
#endif
HDShadowData sd = shadowContext.shadowDatas[shadowDataIndex];
if (sd.isInCachedAtlas > 0) // This is a scalar branch.
{
return EvalShadow_AreaDepth(sd, _CachedAreaLightShadowmapAtlas, positionSS, positionWS, normalWS, L, L_dist, true);
}
else
{
return EvalShadow_AreaDepth(sd, _ShadowmapAreaAtlas, positionSS, positionWS, normalWS, L, L_dist, true);
}
}
#endif // LIGHTLOOP_HD_SHADOW_HLSL