Guest User

Untitled

a guest
May 12th, 2016
251
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Upgrade NOTE: commented out 'float4x4 _CameraToWorld', a built-in variable
  2. // Upgrade NOTE: replaced '_CameraToWorld' with 'unity_CameraToWorld'
  3. // Upgrade NOTE: replaced 'unity_World2Shadow' with 'unity_WorldToShadow'
  4.  
  5. // Collects cascaded shadows into screen space buffer
  6. Shader "Hidden/Internal-PrePassCollectShadows" {
  7. Properties {
  8. _ShadowMapTexture ("", any) = "" {}
  9. }
  10.  
  11. CGINCLUDE
  12. #include "UnityCG.cginc"
  13.  
  14. // Configuration
  15.  
  16.  
  17. // Should receiver plane bias be used? This estimates receiver slope using derivatives,
  18. // and tries to tilt the PCF kernel along it. However, since we're doing it in screenspace
  19. // from the depth texture, the derivatives are wrong on edges or intersections of objects,
  20. // leading to possible shadow artifacts. So it's disabled by default.
  21. #define UNITY_USE_RECEIVER_PLANE_BIAS 0
  22. #define UNITY_RECEIVER_PLANE_MIN_FRACTIONAL_ERROR 0.05f
  23.  
  24.  
  25. // Blend between shadow cascades to hide the transition seams?
  26. #define UNITY_USE_CASCADE_BLENDING 0
  27. #define UNITY_CASCADE_BLEND_DISTANCE 0.1
  28.  
  29.  
  30. struct appdata {
  31. float4 vertex : POSITION;
  32. float2 texcoord : TEXCOORD0;
  33. float3 normal : NORMAL;
  34. };
  35.  
  36. struct v2f {
  37. float2 uv : TEXCOORD0;
  38.  
  39. // View space ray, for perspective case
  40. float3 ray : TEXCOORD1;
  41. // Orthographic view space positions (need xy as well for oblique matrices)
  42. float3 orthoPosNear : TEXCOORD2;
  43. float3 orthoPosFar : TEXCOORD3;
  44.  
  45. float4 pos : SV_POSITION;
  46. };
  47.  
  48. v2f vert (appdata v)
  49. {
  50. v2f o;
  51. o.uv = v.texcoord;
  52. o.ray = v.normal;
  53. float4 clipPos = mul(UNITY_MATRIX_MVP, v.vertex);
  54. o.pos = clipPos;
  55.  
  56. // To compute view space position from Z buffer for orthographic case,
  57. // we need different code than for perspective case. We want to avoid
  58. // doing matrix multiply in the pixel shader: less operations, and less
  59. // constant registers used. Particularly with constant registers, having
  60. // unity_CameraInvProjection in the pixel shader would push the PS over SM2.0
  61. // limits.
  62.  
  63. clipPos.y *= _ProjectionParams.x;
  64. float3 orthoPosNear = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y,-1,1)).xyz;
  65. float3 orthoPosFar = mul(unity_CameraInvProjection, float4(clipPos.x,clipPos.y, 1,1)).xyz;
  66. orthoPosNear.z *= -1;
  67. orthoPosFar.z *= -1;
  68. o.orthoPosNear = orthoPosNear;
  69. o.orthoPosFar = orthoPosFar;
  70.  
  71. return o;
  72. }
  73.  
  74. sampler2D_float _CameraDepthTexture;
  75. // sizes of cascade projections, relative to first one
  76. float4 unity_ShadowCascadeScales;
  77.  
  78. CBUFFER_START(UnityPerCamera2)
  79. // float4x4 _CameraToWorld;
  80. CBUFFER_END
  81.  
  82. UNITY_DECLARE_SHADOWMAP(_ShadowMapTexture);
  83. float4 _ShadowMapTexture_TexelSize;
  84.  
  85. //
  86. // Keywords based defines
  87. //
  88. #if defined (SHADOWS_SPLIT_SPHERES)
  89. #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights_splitSpheres(wpos)
  90. #define GET_SHADOW_FADE(wpos, z) getShadowFade_SplitSpheres(wpos)
  91. #else
  92. #define GET_CASCADE_WEIGHTS(wpos, z) getCascadeWeights( wpos, z )
  93. #define GET_SHADOW_FADE(wpos, z) getShadowFade(z)
  94. #endif
  95.  
  96. #if defined (SHADOWS_SINGLE_CASCADE)
  97. #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord_SingleCascade(wpos)
  98. #else
  99. #define GET_SHADOW_COORDINATES(wpos,cascadeWeights) getShadowCoord(wpos,cascadeWeights)
  100. #endif
  101.  
  102. // prototypes
  103. inline fixed4 getCascadeWeights(float3 wpos, float z); // calculates the cascade weights based on the world position of the fragment and plane positions
  104. inline fixed4 getCascadeWeights_splitSpheres(float3 wpos); // calculates the cascade weights based on world pos and split spheres positions
  105. inline float getShadowFade_SplitSpheres( float3 wpos );
  106. inline float getShadowFade( float3 wpos, float z );
  107. inline float4 getShadowCoord_SingleCascade( float4 wpos ); // converts the shadow coordinates for shadow map using the world position of fragment (optimized for single fragment)
  108. inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights );// converts the shadow coordinates for shadow map using the world position of fragment
  109. half sampleShadowmap_PCF5x5 (float4 coord); // samples the shadowmap based on PCF filtering (5x5 kernel)
  110. half unity_sampleShadowmap( float4 coord ); // sample shadowmap SM2.0+
  111.  
  112. /**
  113. * Gets the cascade weights based on the world position of the fragment.
  114. * Returns a float4 with only one component set that corresponds to the appropriate cascade.
  115. */
  116. inline fixed4 getCascadeWeights(float3 wpos, float z)
  117. {
  118. fixed4 zNear = float4( z >= _LightSplitsNear );
  119. fixed4 zFar = float4( z < _LightSplitsFar );
  120. fixed4 weights = zNear * zFar;
  121. return weights;
  122. }
  123.  
  124. /**
  125. * Gets the cascade weights based on the world position of the fragment and the poisitions of the split spheres for each cascade.
  126. * Returns a float4 with only one component set that corresponds to the appropriate cascade.
  127. */
  128. inline fixed4 getCascadeWeights_splitSpheres(float3 wpos)
  129. {
  130. float3 fromCenter0 = wpos.xyz - unity_ShadowSplitSpheres[0].xyz;
  131. float3 fromCenter1 = wpos.xyz - unity_ShadowSplitSpheres[1].xyz;
  132. float3 fromCenter2 = wpos.xyz - unity_ShadowSplitSpheres[2].xyz;
  133. float3 fromCenter3 = wpos.xyz - unity_ShadowSplitSpheres[3].xyz;
  134. float4 distances2 = float4(dot(fromCenter0,fromCenter0), dot(fromCenter1,fromCenter1), dot(fromCenter2,fromCenter2), dot(fromCenter3,fromCenter3));
  135. fixed4 weights = float4(distances2 < unity_ShadowSplitSqRadii);
  136. weights.yzw = saturate(weights.yzw - weights.xyz);
  137. return weights;
  138. }
  139.  
  140. /**
  141. * Returns the shadow fade based on the 'z' position of the fragment
  142. */
  143. inline float getShadowFade( float z )
  144. {
  145. return saturate(z * _LightShadowData.z + _LightShadowData.w);
  146. }
  147.  
  148. /**
  149. * Returns the shadow fade based on the world position of the fragment, and the distance from the shadow fade center
  150. */
  151. inline float getShadowFade_SplitSpheres( float3 wpos )
  152. {
  153. float sphereDist = distance(wpos.xyz, unity_ShadowFadeCenterAndType.xyz);
  154. half shadowFade = saturate(sphereDist * _LightShadowData.z + _LightShadowData.w);
  155. return shadowFade;
  156. }
  157.  
  158. /**
  159. * Returns the shadowmap coordinates for the given fragment based on the world position and z-depth.
  160. * These coordinates belong to the shadowmap atlas that contains the maps for all cascades.
  161. */
  162. inline float4 getShadowCoord( float4 wpos, fixed4 cascadeWeights )
  163. {
  164. float3 sc0 = mul (unity_WorldToShadow[0], wpos).xyz;
  165. float3 sc1 = mul (unity_WorldToShadow[1], wpos).xyz;
  166. float3 sc2 = mul (unity_WorldToShadow[2], wpos).xyz;
  167. float3 sc3 = mul (unity_WorldToShadow[3], wpos).xyz;
  168. return float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
  169. }
  170.  
  171. /**
  172. * Same as the getShadowCoord; but optimized for single cascade
  173. */
  174. inline float4 getShadowCoord_SingleCascade( float4 wpos )
  175. {
  176. return float4( mul (unity_WorldToShadow[0], wpos).xyz, 0);
  177. }
  178.  
  179. /**
  180. * Computes the receiver plane depth bias for the given shadow coord in screen space.
  181. * Inspirations:
  182. * http://mynameismjp.wordpress.com/2013/09/10/shadow-maps/
  183. * http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Isidoro-ShadowMapping.pdf
  184. */
  185. float2 getReceiverPlaneDepthBias (float3 shadowCoord)
  186. {
  187. float2 biasUV;
  188. float3 dx = ddx (shadowCoord);
  189. float3 dy = ddy (shadowCoord);
  190.  
  191. biasUV.x = dy.y * dx.z - dx.y * dy.z;
  192. biasUV.y = dx.x * dy.z - dy.x * dx.z;
  193. biasUV *= 1.0f / ((dx.x * dy.y) - (dx.y * dy.x));
  194. return biasUV;
  195. }
  196.  
  197. /**
  198. * Combines the different components of a shadow coordinate and returns the final coordinate.
  199. */
  200. inline float3 combineShadowcoordComponents (float2 baseUV, float2 deltaUV, float depth, float2 receiverPlaneDepthBias)
  201. {
  202. float3 uv = float3( baseUV + deltaUV, depth );
  203. uv.z += dot (deltaUV, receiverPlaneDepthBias); // apply the depth bias
  204. return uv;
  205. }
  206.  
  207. /**
  208. * PCF shadowmap filtering based on a 3x3 kernel (optimized with 4 taps)
  209. *
  210. * Algorithm: http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/
  211. * Implementation example: http://mynameismjp.wordpress.com/2013/09/10/shadow-maps/
  212. */
  213. half sampleShadowmap_PCF3x3 (float4 coord, float2 receiverPlaneDepthBias)
  214. {
  215. const float2 offset = float2(0.5,0.5);
  216. float2 uv = (coord.xy * _ShadowMapTexture_TexelSize.zw) + offset;
  217. float2 base_uv = (floor(uv) - offset) * _ShadowMapTexture_TexelSize.xy;
  218. float2 st = frac(uv);
  219.  
  220. float2 uw = float2( 3-2*st.x, 1+2*st.x );
  221. float2 u = float2( (2-st.x) / uw.x - 1, (st.x)/uw.y + 1 );
  222. u *= _ShadowMapTexture_TexelSize.x;
  223.  
  224. float2 vw = float2( 3-2*st.y, 1+2*st.y );
  225. float2 v = float2( (2-st.y) / vw.x - 1, (st.y)/vw.y + 1);
  226. v *= _ShadowMapTexture_TexelSize.y;
  227.  
  228. half shadow;
  229. half sum = 0;
  230.  
  231. sum += uw[0] * vw[0] * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u[0], v[0]), coord.z, receiverPlaneDepthBias) );
  232. sum += uw[1] * vw[0] * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u[1], v[0]), coord.z, receiverPlaneDepthBias) );
  233. sum += uw[0] * vw[1] * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u[0], v[1]), coord.z, receiverPlaneDepthBias) );
  234. sum += uw[1] * vw[1] * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u[1], v[1]), coord.z, receiverPlaneDepthBias) );
  235.  
  236. shadow = sum / 16.0f;
  237. shadow = lerp (_LightShadowData.r, 1.0f, shadow);
  238.  
  239. return shadow;
  240. }
  241.  
  242. /**
  243. * PCF shadowmap filtering based on a 5x5 kernel (optimized with 9 taps)
  244. *
  245. * Algorithm: http://the-witness.net/news/2013/09/shadow-mapping-summary-part-1/
  246. * Implementation example: http://mynameismjp.wordpress.com/2013/09/10/shadow-maps/
  247. */
  248. half sampleShadowmap_PCF5x5 (float4 coord, float2 receiverPlaneDepthBias)
  249. {
  250.  
  251. #if defined(SHADOWS_NATIVE)
  252.  
  253. const float2 offset = float2(0.5,0.5);
  254. float2 uv = (coord.xy * _ShadowMapTexture_TexelSize.zw) + offset;
  255. float2 base_uv = (floor(uv) - offset) * _ShadowMapTexture_TexelSize.xy;
  256. float2 st = frac(uv);
  257.  
  258. float3 uw = float3( 4-3*st.x, 7, 1+3*st.x );
  259. float3 u = float3( (3-2*st.x) / uw.x - 2, (3+st.x)/uw.y, st.x/uw.z + 2 );
  260. u *= _ShadowMapTexture_TexelSize.x;
  261.  
  262. float3 vw = float3( 4-3*st.y, 7, 1+3*st.y );
  263. float3 v = float3( (3-2*st.y) / vw.x - 2, (3+st.y)/vw.y, st.y/vw.z + 2 );
  264. v *= _ShadowMapTexture_TexelSize.y;
  265.  
  266. half shadow;
  267. half sum = 0.0f;
  268.  
  269. half3 accum = uw * vw.x;
  270. sum += accum.x * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.x,v.x), coord.z, receiverPlaneDepthBias) );
  271. sum += accum.y * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.y,v.x), coord.z, receiverPlaneDepthBias) );
  272. sum += accum.z * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.z,v.x), coord.z, receiverPlaneDepthBias) );
  273.  
  274. accum = uw * vw.y;
  275. sum += accum.x * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.x,v.y), coord.z, receiverPlaneDepthBias) );
  276. sum += accum.y * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.y,v.y), coord.z, receiverPlaneDepthBias) );
  277. sum += accum.z * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.z,v.y), coord.z, receiverPlaneDepthBias) );
  278.  
  279. accum = uw * vw.z;
  280. sum += accum.x * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.x,v.z), coord.z, receiverPlaneDepthBias) );
  281. sum += accum.y * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.y,v.z), coord.z, receiverPlaneDepthBias) );
  282. sum += accum.z * UNITY_SAMPLE_SHADOW( _ShadowMapTexture, combineShadowcoordComponents( base_uv, float2(u.z,v.z), coord.z, receiverPlaneDepthBias) );
  283.  
  284. shadow = sum / 144.0f;
  285.  
  286. #else // #if defined(SHADOWS_NATIVE)
  287.  
  288. // when we don't have hardware PCF sampling, then the above 5x5 optimized PCF really does not work.
  289. // Fallback to a simple 3x3 sampling with averaged results.
  290.  
  291. half shadow = 0;
  292. float2 base_uv = coord.xy;
  293. float2 ts = _ShadowMapTexture_TexelSize.xy;
  294. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2(-ts.x,-ts.y), coord.z, receiverPlaneDepthBias));
  295. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( 0,-ts.y), coord.z, receiverPlaneDepthBias));
  296. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( ts.x,-ts.y), coord.z, receiverPlaneDepthBias));
  297. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2(-ts.x, 0), coord.z, receiverPlaneDepthBias));
  298. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( 0, 0), coord.z, receiverPlaneDepthBias));
  299. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( ts.x, 0), coord.z, receiverPlaneDepthBias));
  300. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2(-ts.x, ts.y), coord.z, receiverPlaneDepthBias));
  301. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( 0, ts.y), coord.z, receiverPlaneDepthBias));
  302. shadow += UNITY_SAMPLE_SHADOW(_ShadowMapTexture, combineShadowcoordComponents(base_uv, float2( ts.x, ts.y), coord.z, receiverPlaneDepthBias));
  303. shadow /= 9.0;
  304.  
  305. #endif // else of #if defined(SHADOWS_NATIVE)
  306.  
  307. shadow = lerp (_LightShadowData.r, 1.0f, shadow);
  308.  
  309.  
  310. return shadow;
  311. }
  312.  
  313. /**
  314. * Samples the shadowmap at the given coordinates.
  315. */
  316. half unity_sampleShadowmap( float4 coord )
  317. {
  318. half shadow = UNITY_SAMPLE_SHADOW(_ShadowMapTexture,coord);
  319. shadow = lerp(_LightShadowData.r, 1.0, shadow);
  320. return shadow;
  321. }
  322.  
  323. fixed4 frag_hard (v2f i) : SV_Target
  324. {
  325. float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
  326.  
  327. // 0..1 linear depth, 0 at near plane, 1 at far plane.
  328. float depth = lerp (Linear01Depth(zdepth), zdepth, unity_OrthoParams.w);
  329.  
  330. // view position calculation for perspective & ortho cases
  331. float3 vposPersp = i.ray * depth;
  332. float3 vposOrtho = lerp(i.orthoPosNear, i.orthoPosFar, zdepth);
  333. // pick the perspective or ortho position as needed
  334. float3 vpos = lerp (vposPersp, vposOrtho, unity_OrthoParams.w);
  335.  
  336. float4 wpos = mul (unity_CameraToWorld, float4(vpos,1));
  337.  
  338. fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (wpos, vpos.z);
  339. half shadow = unity_sampleShadowmap( GET_SHADOW_COORDINATES(wpos, cascadeWeights) );
  340. shadow += GET_SHADOW_FADE(wpos, vpos.z);
  341.  
  342. fixed4 res = shadow;
  343. return res;
  344. }
  345. ENDCG
  346.  
  347.  
  348. // ----------------------------------------------------------------------------------------
  349. // Subshader for hard shadows:
  350. // Just collect shadows into the buffer. Used on pre-SM3 GPUs and when hard shadows are picked.
  351.  
  352. SubShader {
  353. Pass {
  354. ZWrite Off ZTest Always Cull Off
  355.  
  356. CGPROGRAM
  357. #pragma vertex vert
  358. #pragma fragment frag_hard
  359. #pragma multi_compile_shadowcollector
  360.  
  361. ENDCG
  362. }
  363. }
  364.  
  365. // ----------------------------------------------------------------------------------------
  366. // Subshader that does PCF 5x5 filtering while collecting shadows.
  367. // Requires SM3 GPU.
  368.  
  369. Subshader {
  370. Tags {"ShadowmapFilter"="PCF_5x5"}
  371.  
  372. Pass {
  373. ZWrite Off ZTest Always Cull Off
  374.  
  375. CGPROGRAM
  376. #pragma vertex vert
  377. #pragma fragment frag_pcf5x5
  378. #pragma multi_compile_shadowcollector
  379. #pragma target 3.0
  380.  
  381. // 3.0 fragment shader
  382. fixed4 frag_pcf5x5 (v2f i) : SV_Target
  383. {
  384. float zdepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);
  385. // 0..1 linear depth, 0 at near plane, 1 at far plane.
  386. float depth = lerp (Linear01Depth(zdepth), zdepth, unity_OrthoParams.w);
  387.  
  388. // view position calculation for perspective & ortho cases
  389. float3 vposPersp = i.ray * depth;
  390. float3 vposOrtho = lerp(i.orthoPosNear, i.orthoPosFar, zdepth);
  391. // pick the perspective or ortho position as needed
  392. float3 vpos = lerp (vposPersp, vposOrtho, unity_OrthoParams.w);
  393.  
  394. // sample the cascade the pixel belongs to
  395. float4 wpos = mul (unity_CameraToWorld, float4(vpos,1));
  396. fixed4 cascadeWeights = GET_CASCADE_WEIGHTS (wpos, vpos.z);
  397. float4 coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights);
  398.  
  399. float2 receiverPlaneDepthBiasCascade0 = 0.0;
  400. float2 receiverPlaneDepthBias = 0.0;
  401. #if UNITY_USE_RECEIVER_PLANE_BIAS
  402. // Reveiver plane depth bias: need to calculate it based on shadow coordinate
  403. // as it would be in first cascade; otherwise derivatives
  404. // at cascade boundaries will be all wrong. So compute
  405. // it from cascade 0 UV, and scale based on which cascade we're in.
  406. //
  407. float3 coordCascade0 = getShadowCoord_SingleCascade(wpos);
  408. receiverPlaneDepthBiasCascade0 = getReceiverPlaneDepthBias (coordCascade0.xyz);
  409. float biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales);
  410.  
  411. receiverPlaneDepthBias = receiverPlaneDepthBiasCascade0 * biasMultiply;
  412.  
  413. // Static depth biasing to make up for incorrect fractional
  414. // sampling on the shadow map grid; from "A Sampling of Shadow Techniques"
  415. // (http://mynameismjp.wordpress.com/2013/09/10/shadow-maps/)
  416. float fractionalSamplingError = 2 * dot(_ShadowMapTexture_TexelSize.xy, abs(receiverPlaneDepthBias));
  417. coord.z -= min(fractionalSamplingError, UNITY_RECEIVER_PLANE_MIN_FRACTIONAL_ERROR);
  418. #endif
  419.  
  420.  
  421. half shadow = sampleShadowmap_PCF5x5( coord, receiverPlaneDepthBias );
  422.  
  423.  
  424. // Blend between shadow cascades if enabled
  425. //
  426. // Not working yet with split spheres, and no need when 1 cascade
  427. #if UNITY_USE_CASCADE_BLENDING && !defined(SHADOWS_SPLIT_SPHERES) && !defined(SHADOWS_SINGLE_CASCADE)
  428. half4 z4 = (float4(vpos.z,vpos.z,vpos.z,vpos.z) - _LightSplitsNear) / (_LightSplitsFar-_LightSplitsNear);
  429. half alpha = dot (z4 * cascadeWeights, half4(1,1,1,1));
  430.  
  431. UNITY_BRANCH
  432. if (alpha > 1-UNITY_CASCADE_BLEND_DISTANCE)
  433. {
  434. // get alpha to 0..1 range over the blend distance
  435. alpha = (alpha-(1-UNITY_CASCADE_BLEND_DISTANCE)) / UNITY_CASCADE_BLEND_DISTANCE;
  436.  
  437. // sample next cascade
  438. cascadeWeights = fixed4 (0, cascadeWeights.xyz);
  439. coord = GET_SHADOW_COORDINATES(wpos, cascadeWeights);
  440.  
  441. #if UNITY_USE_RECEIVER_PLANE_BIAS
  442. biasMultiply = dot(cascadeWeights,unity_ShadowCascadeScales);
  443. receiverPlaneDepthBias = receiverPlaneDepthBiasCascade0 * biasMultiply;
  444. fractionalSamplingError = 2 * dot(_ShadowMapTexture_TexelSize.xy, abs(receiverPlaneDepthBias));
  445. coord.z -= min(fractionalSamplingError, UNITY_RECEIVER_PLANE_MIN_FRACTIONAL_ERROR);
  446. #endif
  447.  
  448. half shadowNextCascade = sampleShadowmap_PCF3x3 (coord, receiverPlaneDepthBias);
  449.  
  450. shadow = lerp (shadow, shadowNextCascade, alpha);
  451. }
  452. #endif
  453.  
  454. shadow += GET_SHADOW_FADE(wpos, vpos.z);
  455. return shadow;
  456. }
  457. ENDCG
  458. }
  459. }
  460.  
  461. Fallback Off
  462. }
RAW Paste Data