Shadows.hlsl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #ifndef UNIVERSAL_SHADOWS_INCLUDED
  2. #define UNIVERSAL_SHADOWS_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  4. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Shadow/ShadowSamplingTent.hlsl"
  5. #include "Core.hlsl"
  6. #define MAX_SHADOW_CASCADES 4
  7. #if !defined(_RECEIVE_SHADOWS_OFF)
  8. #if defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN)
  9. #define MAIN_LIGHT_CALCULATE_SHADOWS
  10. #if defined(_MAIN_LIGHT_SHADOWS) || (defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT))
  11. #define REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR
  12. #endif
  13. #endif
  14. #if defined(_ADDITIONAL_LIGHT_SHADOWS)
  15. #define ADDITIONAL_LIGHT_CALCULATE_SHADOWS
  16. #endif
  17. #endif
  18. #if defined(UNITY_DOTS_INSTANCING_ENABLED)
  19. #define SHADOWMASK_NAME unity_ShadowMasks
  20. #define SHADOWMASK_SAMPLER_NAME samplerunity_ShadowMasks
  21. #define SHADOWMASK_SAMPLE_EXTRA_ARGS , unity_LightmapIndex.x
  22. #else
  23. #define SHADOWMASK_NAME unity_ShadowMask
  24. #define SHADOWMASK_SAMPLER_NAME samplerunity_ShadowMask
  25. #define SHADOWMASK_SAMPLE_EXTRA_ARGS
  26. #endif
  27. #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
  28. #define SAMPLE_SHADOWMASK(uv) SAMPLE_TEXTURE2D_LIGHTMAP(SHADOWMASK_NAME, SHADOWMASK_SAMPLER_NAME, uv SHADOWMASK_SAMPLE_EXTRA_ARGS);
  29. #elif !defined (LIGHTMAP_ON)
  30. #define SAMPLE_SHADOWMASK(uv) unity_ProbesOcclusion;
  31. #else
  32. #define SAMPLE_SHADOWMASK(uv) half4(1, 1, 1, 1);
  33. #endif
  34. #define REQUIRES_WORLD_SPACE_POS_INTERPOLATOR
  35. #if defined(LIGHTMAP_ON) || defined(LIGHTMAP_SHADOW_MIXING) || defined(SHADOWS_SHADOWMASK)
  36. #define CALCULATE_BAKED_SHADOWS
  37. #endif
  38. SCREENSPACE_TEXTURE(_ScreenSpaceShadowmapTexture);
  39. SAMPLER(sampler_ScreenSpaceShadowmapTexture);
  40. TEXTURE2D_SHADOW(_MainLightShadowmapTexture);
  41. SAMPLER_CMP(sampler_MainLightShadowmapTexture);
  42. TEXTURE2D_SHADOW(_AdditionalLightsShadowmapTexture);
  43. SAMPLER_CMP(sampler_AdditionalLightsShadowmapTexture);
  44. // GLES3 causes a performance regression in some devices when using CBUFFER.
  45. #ifndef SHADER_API_GLES3
  46. CBUFFER_START(MainLightShadows)
  47. #endif
  48. // Last cascade is initialized with a no-op matrix. It always transforms
  49. // shadow coord to half3(0, 0, NEAR_PLANE). We use this trick to avoid
  50. // branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES
  51. float4x4 _MainLightWorldToShadow[MAX_SHADOW_CASCADES + 1];
  52. float4 _CascadeShadowSplitSpheres0;
  53. float4 _CascadeShadowSplitSpheres1;
  54. float4 _CascadeShadowSplitSpheres2;
  55. float4 _CascadeShadowSplitSpheres3;
  56. float4 _CascadeShadowSplitSphereRadii;
  57. half4 _MainLightShadowOffset0;
  58. half4 _MainLightShadowOffset1;
  59. half4 _MainLightShadowOffset2;
  60. half4 _MainLightShadowOffset3;
  61. half4 _MainLightShadowParams; // (x: shadowStrength, y: 1.0 if soft shadows, 0.0 otherwise, z: main light fade scale, w: main light fade bias)
  62. float4 _MainLightShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
  63. #ifndef SHADER_API_GLES3
  64. CBUFFER_END
  65. #endif
  66. #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
  67. StructuredBuffer<float4> _AdditionalShadowParams_SSBO; // Per-light data - TODO: test if splitting _AdditionalShadowParams_SSBO[lightIndex].w into a separate StructuredBuffer<int> buffer is faster
  68. StructuredBuffer<float4x4> _AdditionalLightsWorldToShadow_SSBO; // Per-shadow-slice-data - A shadow casting light can have 6 shadow slices (if it's a point light)
  69. half4 _AdditionalShadowOffset0;
  70. half4 _AdditionalShadowOffset1;
  71. half4 _AdditionalShadowOffset2;
  72. half4 _AdditionalShadowOffset3;
  73. half4 _AdditionalShadowFadeParams; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0)
  74. float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
  75. #else
  76. #if defined(SHADER_API_MOBILE) || (defined(SHADER_API_GLCORE) && !defined(SHADER_API_SWITCH)) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) // Workaround because SHADER_API_GLCORE is also defined when SHADER_API_SWITCH is
  77. // Point lights can use 6 shadow slices, but on some mobile GPUs performance decrease drastically with uniform blocks bigger than 8kb. This number ensures size of buffer AdditionalLightShadows stays reasonable.
  78. // 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)
  79. // Keep in sync with MAX_PUNCTUAL_LIGHT_SHADOW_SLICES_IN_UBO in AdditionalLightsShadowCasterPass.cs
  80. #define MAX_PUNCTUAL_LIGHT_SHADOW_SLICES_IN_UBO (MAX_VISIBLE_LIGHTS)
  81. #else
  82. // Point lights can use 6 shadow slices, but on some platforms max uniform block size is 64kb. This number ensures size of buffer AdditionalLightShadows does not exceed this 64kb limit.
  83. // Keep in sync with MAX_PUNCTUAL_LIGHT_SHADOW_SLICES_IN_UBO in AdditionalLightsShadowCasterPass.cs
  84. #define MAX_PUNCTUAL_LIGHT_SHADOW_SLICES_IN_UBO 545
  85. #endif
  86. // GLES3 causes a performance regression in some devices when using CBUFFER.
  87. #ifndef SHADER_API_GLES3
  88. CBUFFER_START(AdditionalLightShadows)
  89. #endif
  90. half4 _AdditionalShadowParams[MAX_VISIBLE_LIGHTS]; // Per-light data
  91. float4x4 _AdditionalLightsWorldToShadow[MAX_PUNCTUAL_LIGHT_SHADOW_SLICES_IN_UBO]; // Per-shadow-slice-data
  92. half4 _AdditionalShadowOffset0;
  93. half4 _AdditionalShadowOffset1;
  94. half4 _AdditionalShadowOffset2;
  95. half4 _AdditionalShadowOffset3;
  96. half4 _AdditionalShadowFadeParams; // x: additional light fade scale, y: additional light fade bias, z: 0.0, w: 0.0)
  97. float4 _AdditionalShadowmapSize; // (xy: 1/width and 1/height, zw: width and height)
  98. #ifndef SHADER_API_GLES3
  99. CBUFFER_END
  100. #endif
  101. #endif
  102. float4 _ShadowBias; // x: depth bias, y: normal bias
  103. #define BEYOND_SHADOW_FAR(shadowCoord) shadowCoord.z <= 0.0 || shadowCoord.z >= 1.0
  104. struct ShadowSamplingData
  105. {
  106. half4 shadowOffset0;
  107. half4 shadowOffset1;
  108. half4 shadowOffset2;
  109. half4 shadowOffset3;
  110. float4 shadowmapSize;
  111. };
  112. ShadowSamplingData GetMainLightShadowSamplingData()
  113. {
  114. ShadowSamplingData shadowSamplingData;
  115. // shadowOffsets are used in SampleShadowmapFiltered #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
  116. shadowSamplingData.shadowOffset0 = _MainLightShadowOffset0;
  117. shadowSamplingData.shadowOffset1 = _MainLightShadowOffset1;
  118. shadowSamplingData.shadowOffset2 = _MainLightShadowOffset2;
  119. shadowSamplingData.shadowOffset3 = _MainLightShadowOffset3;
  120. // shadowmapSize is used in SampleShadowmapFiltered for other platforms
  121. shadowSamplingData.shadowmapSize = _MainLightShadowmapSize;
  122. return shadowSamplingData;
  123. }
  124. ShadowSamplingData GetAdditionalLightShadowSamplingData()
  125. {
  126. ShadowSamplingData shadowSamplingData;
  127. // shadowOffsets are used in SampleShadowmapFiltered #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
  128. shadowSamplingData.shadowOffset0 = _AdditionalShadowOffset0;
  129. shadowSamplingData.shadowOffset1 = _AdditionalShadowOffset1;
  130. shadowSamplingData.shadowOffset2 = _AdditionalShadowOffset2;
  131. shadowSamplingData.shadowOffset3 = _AdditionalShadowOffset3;
  132. // shadowmapSize is used in SampleShadowmapFiltered for other platforms
  133. shadowSamplingData.shadowmapSize = _AdditionalShadowmapSize;
  134. return shadowSamplingData;
  135. }
  136. // ShadowParams
  137. // x: ShadowStrength
  138. // y: 1.0 if shadow is soft, 0.0 otherwise
  139. half4 GetMainLightShadowParams()
  140. {
  141. return _MainLightShadowParams;
  142. }
  143. // ShadowParams
  144. // x: ShadowStrength
  145. // y: 1.0 if shadow is soft, 0.0 otherwise
  146. // z: 1.0 if cast by a point light (6 shadow slices), 0.0 if cast by a spot light (1 shadow slice)
  147. // w: first shadow slice index for this light, there can be 6 in case of point lights. (-1 for non-shadow-casting-lights)
  148. half4 GetAdditionalLightShadowParams(int lightIndex)
  149. {
  150. #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
  151. return _AdditionalShadowParams_SSBO[lightIndex];
  152. #else
  153. return _AdditionalShadowParams[lightIndex];
  154. #endif
  155. }
  156. half SampleScreenSpaceShadowmap(float4 shadowCoord)
  157. {
  158. shadowCoord.xy /= shadowCoord.w;
  159. // The stereo transform has to happen after the manual perspective divide
  160. shadowCoord.xy = UnityStereoTransformScreenSpaceTex(shadowCoord.xy);
  161. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
  162. half attenuation = SAMPLE_TEXTURE2D_ARRAY(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, shadowCoord.xy, unity_StereoEyeIndex).x;
  163. #else
  164. half attenuation = half(SAMPLE_TEXTURE2D(_ScreenSpaceShadowmapTexture, sampler_ScreenSpaceShadowmapTexture, shadowCoord.xy).x);
  165. #endif
  166. return attenuation;
  167. }
  168. real SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData)
  169. {
  170. real attenuation;
  171. #if defined(SHADER_API_MOBILE) || defined(SHADER_API_SWITCH)
  172. // 4-tap hardware comparison
  173. real4 attenuation4;
  174. attenuation4.x = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset0.xyz));
  175. attenuation4.y = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset1.xyz));
  176. attenuation4.z = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset2.xyz));
  177. attenuation4.w = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset3.xyz));
  178. attenuation = dot(attenuation4, real(0.25));
  179. #else
  180. float fetchesWeights[9];
  181. float2 fetchesUV[9];
  182. SampleShadow_ComputeSamples_Tent_5x5(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV);
  183. attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z));
  184. attenuation += fetchesWeights[1] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[1].xy, shadowCoord.z));
  185. attenuation += fetchesWeights[2] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[2].xy, shadowCoord.z));
  186. attenuation += fetchesWeights[3] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[3].xy, shadowCoord.z));
  187. attenuation += fetchesWeights[4] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[4].xy, shadowCoord.z));
  188. attenuation += fetchesWeights[5] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[5].xy, shadowCoord.z));
  189. attenuation += fetchesWeights[6] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[6].xy, shadowCoord.z));
  190. attenuation += fetchesWeights[7] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[7].xy, shadowCoord.z));
  191. attenuation += fetchesWeights[8] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[8].xy, shadowCoord.z));
  192. #endif
  193. return attenuation;
  194. }
  195. real SampleShadowmap(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), float4 shadowCoord, ShadowSamplingData samplingData, half4 shadowParams, bool isPerspectiveProjection = true)
  196. {
  197. // Compiler will optimize this branch away as long as isPerspectiveProjection is known at compile time
  198. if (isPerspectiveProjection)
  199. shadowCoord.xyz /= shadowCoord.w;
  200. real attenuation;
  201. real shadowStrength = shadowParams.x;
  202. #ifdef _SHADOWS_SOFT
  203. if(shadowParams.y != 0)
  204. {
  205. attenuation = SampleShadowmapFiltered(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData);
  206. }
  207. else
  208. #endif
  209. {
  210. // 1-tap hardware comparison
  211. attenuation = real(SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz));
  212. }
  213. attenuation = LerpWhiteTo(attenuation, shadowStrength);
  214. // Shadow coords that fall out of the light frustum volume must always return attenuation 1.0
  215. // TODO: We could use branch here to save some perf on some platforms.
  216. return BEYOND_SHADOW_FAR(shadowCoord) ? 1.0 : attenuation;
  217. }
  218. half ComputeCascadeIndex(float3 positionWS)
  219. {
  220. float3 fromCenter0 = positionWS - _CascadeShadowSplitSpheres0.xyz;
  221. float3 fromCenter1 = positionWS - _CascadeShadowSplitSpheres1.xyz;
  222. float3 fromCenter2 = positionWS - _CascadeShadowSplitSpheres2.xyz;
  223. float3 fromCenter3 = positionWS - _CascadeShadowSplitSpheres3.xyz;
  224. float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
  225. half4 weights = half4(distances2 < _CascadeShadowSplitSphereRadii);
  226. weights.yzw = saturate(weights.yzw - weights.xyz);
  227. return half(4.0) - dot(weights, half4(4, 3, 2, 1));
  228. }
  229. float4 TransformWorldToShadowCoord(float3 positionWS)
  230. {
  231. #ifdef _MAIN_LIGHT_SHADOWS_CASCADE
  232. half cascadeIndex = ComputeCascadeIndex(positionWS);
  233. #else
  234. half cascadeIndex = half(0.0);
  235. #endif
  236. float4 shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(positionWS, 1.0));
  237. return float4(shadowCoord.xyz, 0);
  238. }
  239. half MainLightRealtimeShadow(float4 shadowCoord)
  240. {
  241. #if !defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  242. return half(1.0);
  243. #elif defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
  244. return SampleScreenSpaceShadowmap(shadowCoord);
  245. #else
  246. ShadowSamplingData shadowSamplingData = GetMainLightShadowSamplingData();
  247. half4 shadowParams = GetMainLightShadowParams();
  248. return SampleShadowmap(TEXTURE2D_ARGS(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture), shadowCoord, shadowSamplingData, shadowParams, false);
  249. #endif
  250. }
  251. // returns 0.0 if position is in light's shadow
  252. // returns 1.0 if position is in light
  253. half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection)
  254. {
  255. #if !defined(ADDITIONAL_LIGHT_CALCULATE_SHADOWS)
  256. return half(1.0);
  257. #endif
  258. ShadowSamplingData shadowSamplingData = GetAdditionalLightShadowSamplingData();
  259. half4 shadowParams = GetAdditionalLightShadowParams(lightIndex);
  260. int shadowSliceIndex = shadowParams.w;
  261. if (shadowSliceIndex < 0)
  262. return 1.0;
  263. half isPointLight = shadowParams.z;
  264. UNITY_BRANCH
  265. if (isPointLight)
  266. {
  267. // This is a point light, we have to find out which shadow slice to sample from
  268. float cubemapFaceId = CubeMapFaceID(-lightDirection);
  269. shadowSliceIndex += cubemapFaceId;
  270. }
  271. #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
  272. float4 shadowCoord = mul(_AdditionalLightsWorldToShadow_SSBO[shadowSliceIndex], float4(positionWS, 1.0));
  273. #else
  274. float4 shadowCoord = mul(_AdditionalLightsWorldToShadow[shadowSliceIndex], float4(positionWS, 1.0));
  275. #endif
  276. return SampleShadowmap(TEXTURE2D_ARGS(_AdditionalLightsShadowmapTexture, sampler_AdditionalLightsShadowmapTexture), shadowCoord, shadowSamplingData, shadowParams, true);
  277. }
  278. half GetMainLightShadowFade(float3 positionWS)
  279. {
  280. float3 camToPixel = positionWS - _WorldSpaceCameraPos;
  281. float distanceCamToPixel2 = dot(camToPixel, camToPixel);
  282. float fade = saturate(distanceCamToPixel2 * float(_MainLightShadowParams.z) + float(_MainLightShadowParams.w));
  283. return half(fade);
  284. }
  285. half GetAdditionalLightShadowFade(float3 positionWS)
  286. {
  287. float3 camToPixel = positionWS - _WorldSpaceCameraPos;
  288. float distanceCamToPixel2 = dot(camToPixel, camToPixel);
  289. float fade = saturate(distanceCamToPixel2 * float(_AdditionalShadowFadeParams.x) + float(_AdditionalShadowFadeParams.y));
  290. return half(fade);
  291. }
  292. half MixRealtimeAndBakedShadows(half realtimeShadow, half bakedShadow, half shadowFade)
  293. {
  294. #if defined(LIGHTMAP_SHADOW_MIXING)
  295. return min(lerp(realtimeShadow, 1, shadowFade), bakedShadow);
  296. #else
  297. return lerp(realtimeShadow, bakedShadow, shadowFade);
  298. #endif
  299. }
  300. half BakedShadow(half4 shadowMask, half4 occlusionProbeChannels)
  301. {
  302. // Here occlusionProbeChannels used as mask selector to select shadows in shadowMask
  303. // If occlusionProbeChannels all components are zero we use default baked shadow value 1.0
  304. // This code is optimized for mobile platforms:
  305. // half bakedShadow = any(occlusionProbeChannels) ? dot(shadowMask, occlusionProbeChannels) : 1.0h;
  306. half bakedShadow = half(1.0) + dot(shadowMask - half(1.0), occlusionProbeChannels);
  307. return bakedShadow;
  308. }
  309. half MainLightShadow(float4 shadowCoord, float3 positionWS, half4 shadowMask, half4 occlusionProbeChannels)
  310. {
  311. half realtimeShadow = MainLightRealtimeShadow(shadowCoord);
  312. #ifdef CALCULATE_BAKED_SHADOWS
  313. half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels);
  314. #else
  315. half bakedShadow = half(1.0);
  316. #endif
  317. #ifdef MAIN_LIGHT_CALCULATE_SHADOWS
  318. half shadowFade = GetMainLightShadowFade(positionWS);
  319. #else
  320. half shadowFade = half(1.0);
  321. #endif
  322. return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade);
  323. }
  324. half AdditionalLightShadow(int lightIndex, float3 positionWS, half3 lightDirection, half4 shadowMask, half4 occlusionProbeChannels)
  325. {
  326. half realtimeShadow = AdditionalLightRealtimeShadow(lightIndex, positionWS, lightDirection);
  327. #ifdef CALCULATE_BAKED_SHADOWS
  328. half bakedShadow = BakedShadow(shadowMask, occlusionProbeChannels);
  329. #else
  330. half bakedShadow = half(1.0);
  331. #endif
  332. #ifdef ADDITIONAL_LIGHT_CALCULATE_SHADOWS
  333. half shadowFade = GetAdditionalLightShadowFade(positionWS);
  334. #else
  335. half shadowFade = half(1.0);
  336. #endif
  337. return MixRealtimeAndBakedShadows(realtimeShadow, bakedShadow, shadowFade);
  338. }
  339. float4 GetShadowCoord(VertexPositionInputs vertexInput)
  340. {
  341. #if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
  342. return ComputeScreenPos(vertexInput.positionCS);
  343. #else
  344. return TransformWorldToShadowCoord(vertexInput.positionWS);
  345. #endif
  346. }
  347. float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection)
  348. {
  349. float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));
  350. float scale = invNdotL * _ShadowBias.y;
  351. // normal bias is negative since we want to apply an inset normal offset
  352. positionWS = lightDirection * _ShadowBias.xxx + positionWS;
  353. positionWS = normalWS * scale.xxx + positionWS;
  354. return positionWS;
  355. }
  356. ///////////////////////////////////////////////////////////////////////////////
  357. // Deprecated /
  358. ///////////////////////////////////////////////////////////////////////////////
  359. // Renamed -> _MainLightShadowParams
  360. #define _MainLightShadowData _MainLightShadowParams
  361. // Deprecated: Use GetMainLightShadowFade or GetAdditionalLightShadowFade instead.
  362. float GetShadowFade(float3 positionWS)
  363. {
  364. float3 camToPixel = positionWS - _WorldSpaceCameraPos;
  365. float distanceCamToPixel2 = dot(camToPixel, camToPixel);
  366. float fade = saturate(distanceCamToPixel2 * float(_MainLightShadowParams.z) + float(_MainLightShadowParams.w));
  367. return fade * fade;
  368. }
  369. // Deprecated: Use GetShadowFade instead.
  370. float ApplyShadowFade(float shadowAttenuation, float3 positionWS)
  371. {
  372. float fade = GetShadowFade(positionWS);
  373. return shadowAttenuation + (1 - shadowAttenuation) * fade * fade;
  374. }
  375. // Deprecated: Use GetMainLightShadowParams instead.
  376. half GetMainLightShadowStrength()
  377. {
  378. return _MainLightShadowData.x;
  379. }
  380. // Deprecated: Use GetAdditionalLightShadowParams instead.
  381. half GetAdditionalLightShadowStrenth(int lightIndex)
  382. {
  383. #if USE_STRUCTURED_BUFFER_FOR_LIGHT_DATA
  384. return _AdditionalShadowParams_SSBO[lightIndex].x;
  385. #else
  386. return _AdditionalShadowParams[lightIndex].x;
  387. #endif
  388. }
  389. // Deprecated: Use SampleShadowmap that takes shadowParams instead of strength.
  390. real SampleShadowmap(float4 shadowCoord, TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap), ShadowSamplingData samplingData, half shadowStrength, bool isPerspectiveProjection = true)
  391. {
  392. half4 shadowParams = half4(shadowStrength, 1.0, 0.0, 0.0);
  393. return SampleShadowmap(TEXTURE2D_SHADOW_ARGS(ShadowMap, sampler_ShadowMap), shadowCoord, samplingData, shadowParams, isPerspectiveProjection);
  394. }
  395. // Deprecated: Use AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS, half3 lightDirection) in Shadows.hlsl instead, as it supports Point Light shadows
  396. half AdditionalLightRealtimeShadow(int lightIndex, float3 positionWS)
  397. {
  398. return AdditionalLightRealtimeShadow(lightIndex, positionWS, half3(1, 0, 0));
  399. }
  400. #endif