2023-03-28 13:24:16 -04:00
#ifndef UNIVERSAL_SHADOWS_INCLUDED
#define UNIVERSAL_SHADOWS_INCLUDED
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl"
#include "Core.hlsl"
#define MAX_SHADOW_CASCADES 4
#if !defined(_RECEIVE_SHADOWS_OFF)
# if defined ( _MAIN_LIGHT_SHADOWS ) || defined ( _MAIN_LIGHT_SHADOWS_CASCADE ) || defined ( _MAIN_LIGHT_SHADOWS_SCREEN )
# define MAIN_LIGHT_CALCULATE_SHADOWS
# if defined ( _MAIN_LIGHT_SHADOWS ) || ( defined ( _MAIN_LIGHT_SHADOWS_SCREEN ) && ! defined ( _SURFACE_TYPE_TRANSPARENT ) )
# define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR
# endif
# endif
# if defined ( _ADDITIONAL_LIGHT_SHADOWS )
# define ADDITIONAL_LIGHT_CALCULATE_SHADOWS
# endif
#endif
#if defined(UNITY_DOTS_INSTANCING_ENABLED)
#define SHADOWMASK_NAME unity_ShadowMasks
#define SHADOWMASK_SAMPLER_NAME samplerunity_ShadowMasks
#define SHADOWMASK_SAMPLE_EXTRA_ARGS , unity_LightmapIndex.x
#else
#define SHADOWMASK_NAME unity_ShadowMask
#define SHADOWMASK_SAMPLER_NAME samplerunity_ShadowMask
#define SHADOWMASK_SAMPLE_EXTRA_ARGS
#endif
#if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
# define SAMPLE_SHADOWMASK ( uv ) SAMPLE_TEXTURE2D_LIGHTMAP ( SHADOWMASK_NAME , SHADOWMASK_SAMPLER_NAME , uv SHADOWMASK_SAMPLE_EXTRA_ARGS ) ;
#elif !defined (LIGHTMAP_ON)
# define SAMPLE_SHADOWMASK ( uv ) unity_ProbesOcclusion ;
#else
# define SAMPLE_SHADOWMASK ( uv ) half4 ( 1 , 1 , 1 , 1 ) ;
#endif
#define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR
#if defined(LIGHTMAP_ON) || defined(LIGHTMAP_SHADOW_MIXING) || defined(SHADOWS_SHADOWMASK)
#define CALCULATE_BAKED_SHADOWS
#endif
SCREENSPACE_TEXTURE ( _ScreenSpaceShadowmapTexture ) ;
SAMPLER ( sampler_ScreenSpaceShadowmapTexture ) ;
TEXTURE2D_SHADOW ( _MainLightShadowmapTexture ) ;
SAMPLER_CMP ( sampler_MainLightShadowmapTexture ) ;
TEXTURE2D_SHADOW ( _AdditionalLightsShadowmapTexture ) ;
SAMPLER_CMP ( sampler_AdditionalLightsShadowmapTexture ) ;
// GLES3 causes a performance regression in some devices when using CBUFFER.
#ifndef SHADER_API_GLES3
CBUFFER_START ( MainLightShadows )
#endif
// Last cascade is initialized with a no-op matrix. It always transforms
// shadow coord to half3(0, 0, NEAR_PLANE). We use this trick to avoid
// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES
float4x4 _MainLightWorldToShadow [ MAX_SHADOW_CASCADES + 1 ] ;
float4 _CascadeShadowSplitSpheres0 ;
float4 _CascadeShadowSplitSpheres1 ;
float4 _CascadeShadowSplitSpheres2 ;
float4 _CascadeShadowSplitSpheres3 ;
float4 _CascadeShadowSplitSphereRadii ;
half4 _MainLightShadowOffset0 ;
half4 _MainLightShadowOffset1 ;
half4 _MainLightShadowOffset2 ;
half4 _MainLightShadowOffset3 ;
half4 _MainLightShadowParams ; // (x: shadowStrength, y: 1.0 if soft shadows, 0.0 otherwise, z: main light fade scale, w: main light fade bias)
float4 _MainLightShadowmapSize ; // (xy: 1/width and 1/height, zw: width and height)
#ifndef SHADER_API_GLES3
CBUFFER_END
#endif
2023-05-07 18:43:11 -04:00
#if defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS)
# if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
StructuredBuffer < float4 > _AdditionalShadowParams_SSBO ; // Per-light data - TODO: test if splitting _AdditionalShadowParams_SSBO[lightIndex].w into a separate StructuredBuffer<int> buffer is faster
StructuredBuffer < float4x4 > _AdditionalLightsWorldToShadow_SSBO ; // Per-shadow-slice-data - A shadow casting light can have 6 shadow slices (if it's a point light)
half4 _AdditionalShadowOffset0 ;
half4 _AdditionalShadowOffset1 ;
half4 _AdditionalShadowOffset2 ;
half4 _AdditionalShadowOffset3 ;
half4 _AdditionalShadowFadeParams ; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0)
float4 _AdditionalShadowmapSize ; // (xy: 1/width and 1/height, zw: width and height)
# else
// GLES3 causes a performance regression in some devices when using CBUFFER.
# ifndef SHADER_API_GLES3
CBUFFER_START ( AdditionalLightShadows )
# endif
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
// Point lights can use 6 shadow slices. Some mobile GPUs performance decrease drastically with uniform
// blocks bigger than 8kb while others have a 64kb max uniform block size. This number ensures size of buffer
// AdditionalLightShadows stays reasonable. It also avoids shader compilation errors on SHADER_API_GLES30
// devices where max number of uniforms per shader GL_MAX_FRAGMENT_UNIFORM_VECTORS is low (224)
half4 _AdditionalShadowParams [ MAX_VISIBLE_LIGHTS ] ; // Per-light data
float4x4 _AdditionalLightsWorldToShadow [ MAX_VISIBLE_LIGHTS ] ; // Per-shadow-slice-data
half4 _AdditionalShadowOffset0 ;
half4 _AdditionalShadowOffset1 ;
half4 _AdditionalShadowOffset2 ;
half4 _AdditionalShadowOffset3 ;
half4 _AdditionalShadowFadeParams ; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0)
float4 _AdditionalShadowmapSize ; // (xy: 1/width and 1/height, zw: width and height)
# ifndef SHADER_API_GLES3
CBUFFER_END
# endif
# endif
2023-03-28 13:24:16 -04:00
#endif
float4 _ShadowBias ; // x: depth bias, y: normal bias
#define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= 0.0 || shadowCoord.z >= 1.0
struct ShadowSamplingData
{
half4 shadowOffset0 ;
half4 shadowOffset1 ;
half4 shadowOffset2 ;
half4 shadowOffset3 ;
float4 shadowmapSize ;
} ;
ShadowSamplingData GetMainLightShadowSamplingData ( )
{
ShadowSamplingData shadowSamplingData ;
// shadowOffsets are used in SampleShadowmapFiltered #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
shadowSamplingData . shadowOffset0 = _MainLightShadowOffset0 ;
shadowSamplingData . shadowOffset1 = _MainLightShadowOffset1 ;
shadowSamplingData . shadowOffset2 = _MainLightShadowOffset2 ;
shadowSamplingData . shadowOffset3 = _MainLightShadowOffset3 ;
// shadowmapSize is used in SampleShadowmapFiltered for other platforms
shadowSamplingData . shadowmapSize = _MainLightShadowmapSize ;
return shadowSamplingData ;
}
ShadowSamplingData GetAdditionalLightShadowSamplingData ( )
{
2023-05-07 18:43:11 -04:00
ShadowSamplingData shadowSamplingData = ( ShadowSamplingData ) 0 ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
# if defined ( ADDITIONAL_LIGHT_CALCULATE_SHADOWS )
// shadowOffsets are used in SampleShadowmapFiltered #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
shadowSamplingData . shadowOffset0 = _AdditionalShadowOffset0 ;
shadowSamplingData . shadowOffset1 = _AdditionalShadowOffset1 ;
shadowSamplingData . shadowOffset2 = _AdditionalShadowOffset2 ;
shadowSamplingData . shadowOffset3 = _AdditionalShadowOffset3 ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
// shadowmapSize is used in SampleShadowmapFiltered for other platforms
shadowSamplingData . shadowmapSize = _AdditionalShadowmapSize ;
# endif
2023-03-28 13:24:16 -04:00
return shadowSamplingData ;
}
// ShadowParams
// x: ShadowStrength
// y: 1.0 if shadow is soft, 0.0 otherwise
half4 GetMainLightShadowParams ( )
{
return _MainLightShadowParams ;
}
// ShadowParams
// x: ShadowStrength
// y: 1.0 if shadow is soft, 0.0 otherwise
// z: 1.0 if cast by a point light (6 shadow slices), 0.0 if cast by a spot light (1 shadow slice)
// w: first shadow slice index for this light, there can be 6 in case of point lights. (-1 for non-shadow-casting-lights)
half4 GetAdditionalLightShadowParams ( int lightIndex )
{
2023-05-07 18:43:11 -04:00
# if defined ( ADDITIONAL_LIGHT_CALCULATE_SHADOWS )
# if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
return _AdditionalShadowParams_SSBO [ lightIndex ] ;
# else
return _AdditionalShadowParams [ lightIndex ] ;
# endif
# else
// Same defaults as set in AdditionalLightsShadowCasterPass.cs
return half4 ( 0 , 0 , 0 , - 1 ) ;
# endif
2023-03-28 13:24:16 -04:00
}
half SampleScreenSpaceShadowmap ( float4 shadowCoord )
{
shadowCoord . xy / = shadowCoord . w ;
// The stereo transform has to happen after the manual perspective divide
shadowCoord . xy = UnityStereoTransformScreenSpaceTex ( shadowCoord . xy ) ;
#if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
half attenuation = SAMPLE_TEXTURE2D_ARRAY ( _ScreenSpaceShadowmapTexture , sampler_ScreenSpaceShadowmapTexture , shadowCoord . xy , unity_StereoEyeIndex ) . x ;
#else
half attenuation = half ( SAMPLE_TEXTURE2D ( _ScreenSpaceShadowmapTexture , sampler_ScreenSpaceShadowmapTexture , shadowCoord . xy ) . x ) ;
#endif
return attenuation ;
}
real SampleShadowmapFiltered ( TEXTURE2D_SHADOW_PARAM ( ShadowMap , sampler_ShadowMap ) , float4 shadowCoord , ShadowSamplingData samplingData )
{
real attenuation ;
#if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
// 4-tap hardware comparison
real4 attenuation4 ;
attenuation4 . x = real ( SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , shadowCoord . xyz + samplingData . shadowOffset0 . xyz ) ) ;
attenuation4 . y = real ( SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , shadowCoord . xyz + samplingData . shadowOffset1 . xyz ) ) ;
attenuation4 . z = real ( SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , shadowCoord . xyz + samplingData . shadowOffset2 . xyz ) ) ;
attenuation4 . w = real ( SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , shadowCoord . xyz + samplingData . shadowOffset3 . xyz ) ) ;
attenuation = dot ( attenuation4 , real ( 0.25 ) ) ;
#else
float fetchesWeights [ 9 ] ;
float2 fetchesUV [ 9 ] ;
SampleShadow_ComputeSamples_Tent_5x5 ( samplingData . shadowmapSize , shadowCoord . xy , fetchesWeights , fetchesUV ) ;
attenuation = fetchesWeights [ 0 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 0 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 1 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 1 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 2 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 2 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 3 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 3 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 4 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 4 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 5 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 5 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 6 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 6 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 7 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 7 ] . xy , shadowCoord . z ) ) ;
attenuation + = fetchesWeights [ 8 ] * SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , float3 ( fetchesUV [ 8 ] . xy , shadowCoord . z ) ) ;
#endif
return attenuation ;
}
real SampleShadowmap ( TEXTURE2D_SHADOW_PARAM ( ShadowMap , sampler_ShadowMap ) , float4 shadowCoord , ShadowSamplingData samplingData , half4 shadowParams , bool isPerspectiveProjection = true )
{
// Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time
if ( isPerspectiveProjection )
shadowCoord . xyz / = shadowCoord . w ;
real attenuation ;
real shadowStrength = shadowParams . x ;
#ifdef _SHADOWS_SOFT
if ( shadowParams . y != 0 )
{
attenuation = SampleShadowmapFiltered ( TEXTURE2D_SHADOW_ARGS ( ShadowMap , sampler_ShadowMap ) , shadowCoord , samplingData ) ;
}
else
#endif
{
// 1-tap hardware comparison
attenuation = real ( SAMPLE_TEXTURE2D_SHADOW ( ShadowMap , sampler_ShadowMap , shadowCoord . xyz ) ) ;
}
attenuation = LerpWhiteTo ( attenuation , shadowStrength ) ;
// Shadow coords that fall out of the light frustum volume must always return attenuation 1.0
// TODO: We could use branch here to save some perf on some platforms.
return BEYOND_SHADOW_FAR ( shadowCoord ) ? 1.0 : attenuation ;
}
half ComputeCascadeIndex ( float3 positionWS )
{
float3 fromCenter0 = positionWS - _CascadeShadowSplitSpheres0 . xyz ;
float3 fromCenter1 = positionWS - _CascadeShadowSplitSpheres1 . xyz ;
float3 fromCenter2 = positionWS - _CascadeShadowSplitSpheres2 . xyz ;
float3 fromCenter3 = positionWS - _CascadeShadowSplitSpheres3 . xyz ;
float4 distances2 = float4 ( dot ( fromCenter0 , fromCenter0 ) , dot ( fromCenter1 , fromCenter1 ) , dot ( fromCenter2 , fromCenter2 ) , dot ( fromCenter3 , fromCenter3 ) ) ;
half4 weights = half4 ( distances2 < _CascadeShadowSplitSphereRadii ) ;
weights . yzw = saturate ( weights . yzw - weights . xyz ) ;
return half ( 4.0 ) - dot ( weights , half4 ( 4 , 3 , 2 , 1 ) ) ;
}
float4 TransformWorldToShadowCoord ( float3 positionWS )
{
#ifdef _MAIN_LIGHT_SHADOWS_CASCADE
half cascadeIndex = ComputeCascadeIndex ( positionWS ) ;
#else
half cascadeIndex = half ( 0.0 ) ;
#endif
float4 shadowCoord = mul ( _MainLightWorldToShadow [ cascadeIndex ] , float4 ( positionWS , 1.0 ) ) ;
return float4 ( shadowCoord . xyz , 0 ) ;
}
half MainLightRealtimeShadow ( float4 shadowCoord )
{
2023-05-07 18:43:11 -04:00
# if ! defined ( MAIN_LIGHT_CALCULATE_SHADOWS )
return half ( 1.0 ) ;
# elif defined ( _MAIN_LIGHT_SHADOWS_SCREEN ) && ! defined ( _SURFACE_TYPE_TRANSPARENT )
return SampleScreenSpaceShadowmap ( shadowCoord ) ;
# else
ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData ( ) ;
half4 shadowParams = GetMainLightShadowParams ( ) ;
return SampleShadowmap ( TEXTURE2D_ARGS ( _MainLightShadowmapTexture , sampler_MainLightShadowmapTexture ) , shadowCoord , shadowSamplingData , shadowParams , false ) ;
# endif
2023-03-28 13:24:16 -04:00
}
// returns 0.0 if position is in light's shadow
// returns 1.0 if position is in light
half AdditionalLightRealtimeShadow ( int lightIndex , float3 positionWS , half3 lightDirection )
{
2023-05-07 18:43:11 -04:00
# if defined ( ADDITIONAL_LIGHT_CALCULATE_SHADOWS )
ShadowSamplingData shadowSamplingData = GetAdditionalLightShadowSamplingData ( ) ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
half4 shadowParams = GetAdditionalLightShadowParams ( lightIndex ) ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
int shadowSliceIndex = shadowParams . w ;
if ( shadowSliceIndex < 0 )
return 1.0 ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
half isPointLight = shadowParams . z ;
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
UNITY_BRANCH
if ( isPointLight )
{
// This is a point light, we have to find out which shadow slice to sample from
float cubemapFaceId = CubeMapFaceID ( - lightDirection ) ;
shadowSliceIndex + = cubemapFaceId ;
}
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
# if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
float4 shadowCoord = mul ( _AdditionalLightsWorldToShadow_SSBO [ shadowSliceIndex ] , float4 ( positionWS , 1.0 ) ) ;
# else
float4 shadowCoord = mul ( _AdditionalLightsWorldToShadow [ shadowSliceIndex ] , float4 ( positionWS , 1.0 ) ) ;
# endif
2023-03-28 13:24:16 -04:00
2023-05-07 18:43:11 -04:00
return SampleShadowmap ( TEXTURE2D_ARGS ( _AdditionalLightsShadowmapTexture , sampler_AdditionalLightsShadowmapTexture ) , shadowCoord , shadowSamplingData , shadowParams , true ) ;
# else
return half ( 1.0 ) ;
# endif
2023-03-28 13:24:16 -04:00
}
half GetMainLightShadowFade ( float3 positionWS )
{
float3 camToPixel = positionWS - _WorldSpaceCameraPos ;
float distanceCamToPixel2 = dot ( camToPixel , camToPixel ) ;
float fade = saturate ( distanceCamToPixel2 * float ( _MainLightShadowParams . z ) + float ( _MainLightShadowParams . w ) ) ;
return half ( fade ) ;
}
half GetAdditionalLightShadowFade ( float3 positionWS )
{
2023-05-07 18:43:11 -04:00
# if defined ( ADDITIONAL_LIGHT_CALCULATE_SHADOWS )
float3 camToPixel = positionWS - _WorldSpaceCameraPos ;
float distanceCamToPixel2 = dot ( camToPixel , camToPixel ) ;
float fade = saturate ( distanceCamToPixel2 * float ( _AdditionalShadowFadeParams . x ) + float ( _AdditionalShadowFadeParams . y ) ) ;
return half ( fade ) ;
# else
return half ( 1.0 ) ;
# endif
2023-03-28 13:24:16 -04:00
}
half MixRealtimeAndBakedShadows ( half realtimeShadow , half bakedShadow , half shadowFade )
{
#if defined(LIGHTMAP_SHADOW_MIXING)
return min ( lerp ( realtimeShadow , 1 , shadowFade ) , bakedShadow ) ;
#else
return lerp ( realtimeShadow , bakedShadow , shadowFade ) ;
#endif
}
half BakedShadow ( half4 shadowMask , half4 occlusionProbeChannels )
{
// Here occlusionProbeChannels used as mask selector to select shadows in shadowMask
// If occlusionProbeChannels all components are zero we use default baked shadow value 1.0
// This code is optimized for mobile platforms:
// half bakedShadow = any(occlusionProbeChannels) ? dot(shadowMask, occlusionProbeChannels) : 1.0h;
half bakedShadow = half ( 1.0 ) + dot ( shadowMask - half ( 1.0 ) , occlusionProbeChannels ) ;
return bakedShadow ;
}
half MainLightShadow ( float4 shadowCoord , float3 positionWS , half4 shadowMask , half4 occlusionProbeChannels )
{
half realtimeShadow = MainLightRealtimeShadow ( shadowCoord ) ;
#ifdef CALCULATE_BAKED_SHADOWS
half bakedShadow = BakedShadow ( shadowMask , occlusionProbeChannels ) ;
#else
half bakedShadow = half ( 1.0 ) ;
#endif
#ifdef MAIN_LIGHT_CALCULATE_SHADOWS
half shadowFade = GetMainLightShadowFade ( positionWS ) ;
#else
half shadowFade = half ( 1.0 ) ;
#endif
return MixRealtimeAndBakedShadows ( realtimeShadow , bakedShadow , shadowFade ) ;
}
half AdditionalLightShadow ( int lightIndex , float3 positionWS , half3 lightDirection , half4 shadowMask , half4 occlusionProbeChannels )
{
half realtimeShadow = AdditionalLightRealtimeShadow ( lightIndex , positionWS , lightDirection ) ;
#ifdef CALCULATE_BAKED_SHADOWS
half bakedShadow = BakedShadow ( shadowMask , occlusionProbeChannels ) ;
#else
half bakedShadow = half ( 1.0 ) ;
#endif
#ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS
half shadowFade = GetAdditionalLightShadowFade ( positionWS ) ;
#else
half shadowFade = half ( 1.0 ) ;
#endif
return MixRealtimeAndBakedShadows ( realtimeShadow , bakedShadow , shadowFade ) ;
}
float4 GetShadowCoord ( VertexPositionInputs vertexInput )
{
#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
return ComputeScreenPos ( vertexInput . positionCS ) ;
#else
return TransformWorldToShadowCoord ( vertexInput . positionWS ) ;
#endif
}
float3 ApplyShadowBias ( float3 positionWS , float3 normalWS , float3 lightDirection )
{
float invNdotL = 1.0 - saturate ( dot ( lightDirection , normalWS ) ) ;
float scale = invNdotL * _ShadowBias . y ;
// normal bias is negative since we want to apply an inset normal offset
positionWS = lightDirection * _ShadowBias . xxx + positionWS ;
positionWS = normalWS * scale . xxx + positionWS ;
return positionWS ;
}
///////////////////////////////////////////////////////////////////////////////
// Deprecated /
///////////////////////////////////////////////////////////////////////////////
// Renamed -> _MainLightShadowParams
#define _MainLightShadowData _MainLightShadowParams
// Deprecated: Use GetMainLightShadowFade or GetAdditionalLightShadowFade instead.
float GetShadowFade ( float3 positionWS )
{
float3 camToPixel = positionWS - _WorldSpaceCameraPos ;
float distanceCamToPixel2 = dot ( camToPixel , camToPixel ) ;
float fade = saturate ( distanceCamToPixel2 * float ( _MainLightShadowParams . z ) + float ( _MainLightShadowParams . w ) ) ;
return fade * fade ;
}
// Deprecated: Use GetShadowFade instead.
float ApplyShadowFade ( float shadowAttenuation , float3 positionWS )
{
float fade = GetShadowFade ( positionWS ) ;
return shadowAttenuation + ( 1 - shadowAttenuation ) * fade * fade ;
}
// Deprecated: Use GetMainLightShadowParams instead.
half GetMainLightShadowStrength ( )
{
return _MainLightShadowData . x ;
}
// Deprecated: Use GetAdditionalLightShadowParams instead.
half GetAdditionalLightShadowStrenth ( int lightIndex )
{
2023-05-07 18:43:11 -04:00
# if defined ( ADDITIONAL_LIGHT_CALCULATE_SHADOWS )
# if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
return _AdditionalShadowParams_SSBO [ lightIndex ] . x ;
# else
return _AdditionalShadowParams [ lightIndex ] . x ;
# endif
# else
return half ( 1.0 ) ;
# endif
2023-03-28 13:24:16 -04:00
}
// Deprecated: Use SampleShadowmap that takes shadowParams instead of strength.
real SampleShadowmap ( float4 shadowCoord , TEXTURE2D_SHADOW_PARAM ( ShadowMap , sampler_ShadowMap ) , ShadowSamplingData samplingData , half shadowStrength , bool isPerspectiveProjection = true )
{
half4 shadowParams = half4 ( shadowStrength , 1.0 , 0.0 , 0.0 ) ;
return SampleShadowmap ( TEXTURE2D_SHADOW_ARGS ( ShadowMap , sampler_ShadowMap ) , shadowCoord , samplingData , shadowParams , isPerspectiveProjection ) ;
}
// Deprecated: Use AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) in Shadows.hlsl instead, as it supports Point Light shadows
half AdditionalLightRealtimeShadow ( int lightIndex , float3 positionWS )
{
return AdditionalLightRealtimeShadow ( lightIndex , positionWS , half3 ( 1 , 0 , 0 ) ) ;
}
#endif