TerrainLitPasses.hlsl 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. #ifndef UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
  2. #define UNIVERSAL_TERRAIN_LIT_PASSES_INCLUDED
  3. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  4. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityGBuffer.hlsl"
  5. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
  6. struct Attributes
  7. {
  8. float4 positionOS : POSITION;
  9. float3 normalOS : NORMAL;
  10. float2 texcoord : TEXCOORD0;
  11. UNITY_VERTEX_INPUT_INSTANCE_ID
  12. };
  13. struct Varyings
  14. {
  15. float4 uvMainAndLM : TEXCOORD0; // xy: control, zw: lightmap
  16. #ifndef TERRAIN_SPLAT_BASEPASS
  17. float4 uvSplat01 : TEXCOORD1; // xy: splat0, zw: splat1
  18. float4 uvSplat23 : TEXCOORD2; // xy: splat2, zw: splat3
  19. #endif
  20. #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
  21. half4 normal : TEXCOORD3; // xyz: normal, w: viewDir.x
  22. half4 tangent : TEXCOORD4; // xyz: tangent, w: viewDir.y
  23. half4 bitangent : TEXCOORD5; // xyz: bitangent, w: viewDir.z
  24. #else
  25. half3 normal : TEXCOORD3;
  26. half3 vertexSH : TEXCOORD4; // SH
  27. #endif
  28. #ifdef _ADDITIONAL_LIGHTS_VERTEX
  29. half4 fogFactorAndVertexLight : TEXCOORD6; // x: fogFactor, yzw: vertex light
  30. #else
  31. half fogFactor : TEXCOORD6;
  32. #endif
  33. float3 positionWS : TEXCOORD7;
  34. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  35. float4 shadowCoord : TEXCOORD8;
  36. #endif
  37. #if defined(DYNAMICLIGHTMAP_ON)
  38. float2 dynamicLightmapUV : TEXCOORD9;
  39. #endif
  40. float4 clipPos : SV_POSITION;
  41. UNITY_VERTEX_OUTPUT_STEREO
  42. };
  43. void InitializeInputData(Varyings IN, half3 normalTS, out InputData inputData)
  44. {
  45. inputData = (InputData)0;
  46. inputData.positionWS = IN.positionWS;
  47. inputData.positionCS = IN.clipPos;
  48. #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
  49. half3 viewDirWS = half3(IN.normal.w, IN.tangent.w, IN.bitangent.w);
  50. inputData.tangentToWorld = half3x3(-IN.tangent.xyz, IN.bitangent.xyz, IN.normal.xyz);
  51. inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld);
  52. half3 SH = 0;
  53. #elif defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
  54. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(IN.positionWS);
  55. float2 sampleCoords = (IN.uvMainAndLM.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy;
  56. half3 normalWS = TransformObjectToWorldNormal(normalize(SAMPLE_TEXTURE2D(_TerrainNormalmapTexture, sampler_TerrainNormalmapTexture, sampleCoords).rgb * 2 - 1));
  57. half3 tangentWS = cross(GetObjectToWorldMatrix()._13_23_33, normalWS);
  58. inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(-tangentWS, cross(normalWS, tangentWS), normalWS));
  59. half3 SH = 0;
  60. #else
  61. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(IN.positionWS);
  62. inputData.normalWS = IN.normal;
  63. half3 SH = IN.vertexSH;
  64. #endif
  65. inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
  66. inputData.viewDirectionWS = viewDirWS;
  67. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  68. inputData.shadowCoord = IN.shadowCoord;
  69. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  70. inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  71. #else
  72. inputData.shadowCoord = float4(0, 0, 0, 0);
  73. #endif
  74. #ifdef _ADDITIONAL_LIGHTS_VERTEX
  75. inputData.fogCoord = InitializeInputDataFog(float4(IN.positionWS, 1.0), IN.fogFactorAndVertexLight.x);
  76. inputData.vertexLighting = IN.fogFactorAndVertexLight.yzw;
  77. #else
  78. inputData.fogCoord = InitializeInputDataFog(float4(IN.positionWS, 1.0), IN.fogFactor);
  79. #endif
  80. #if defined(DYNAMICLIGHTMAP_ON)
  81. inputData.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, IN.dynamicLightmapUV, SH, inputData.normalWS);
  82. #else
  83. inputData.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, SH, inputData.normalWS);
  84. #endif
  85. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(IN.clipPos);
  86. inputData.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw)
  87. #if defined(DEBUG_DISPLAY)
  88. #if defined(DYNAMICLIGHTMAP_ON)
  89. inputData.dynamicLightmapUV = IN.dynamicLightmapUV;
  90. #endif
  91. #if defined(LIGHTMAP_ON)
  92. inputData.staticLightmapUV = IN.uvMainAndLM.zw;
  93. #else
  94. inputData.vertexSH = SH;
  95. #endif
  96. #endif
  97. }
  98. #ifndef TERRAIN_SPLAT_BASEPASS
  99. void NormalMapMix(float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, inout half3 mixedNormal)
  100. {
  101. #if defined(_NORMALMAP)
  102. half3 nrm = half(0.0);
  103. nrm += splatControl.r * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal0, sampler_Normal0, uvSplat01.xy), _NormalScale0);
  104. nrm += splatControl.g * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal1, sampler_Normal0, uvSplat01.zw), _NormalScale1);
  105. nrm += splatControl.b * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal2, sampler_Normal0, uvSplat23.xy), _NormalScale2);
  106. nrm += splatControl.a * UnpackNormalScale(SAMPLE_TEXTURE2D(_Normal3, sampler_Normal0, uvSplat23.zw), _NormalScale3);
  107. // avoid risk of NaN when normalizing.
  108. #if HAS_HALF
  109. nrm.z += half(0.01);
  110. #else
  111. nrm.z += 1e-5f;
  112. #endif
  113. mixedNormal = normalize(nrm.xyz);
  114. #endif
  115. }
  116. void SplatmapMix(float4 uvMainAndLM, float4 uvSplat01, float4 uvSplat23, inout half4 splatControl, out half weight, out half4 mixedDiffuse, out half4 defaultSmoothness, inout half3 mixedNormal)
  117. {
  118. half4 diffAlbedo[4];
  119. diffAlbedo[0] = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplat01.xy);
  120. diffAlbedo[1] = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, uvSplat01.zw);
  121. diffAlbedo[2] = SAMPLE_TEXTURE2D(_Splat2, sampler_Splat0, uvSplat23.xy);
  122. diffAlbedo[3] = SAMPLE_TEXTURE2D(_Splat3, sampler_Splat0, uvSplat23.zw);
  123. // This might be a bit of a gamble -- the assumption here is that if the diffuseMap has no
  124. // alpha channel, then diffAlbedo[n].a = 1.0 (and _DiffuseHasAlphaN = 0.0)
  125. // Prior to coming in, _SmoothnessN is actually set to max(_DiffuseHasAlphaN, _SmoothnessN)
  126. // This means that if we have an alpha channel, _SmoothnessN is locked to 1.0 and
  127. // otherwise, the true slider value is passed down and diffAlbedo[n].a == 1.0.
  128. defaultSmoothness = half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a);
  129. defaultSmoothness *= half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3);
  130. #ifndef _TERRAIN_BLEND_HEIGHT // density blending
  131. if(_NumLayersCount <= 4)
  132. {
  133. // 20.0 is the number of steps in inputAlphaMask (Density mask. We decided 20 empirically)
  134. half4 opacityAsDensity = saturate((half4(diffAlbedo[0].a, diffAlbedo[1].a, diffAlbedo[2].a, diffAlbedo[3].a) - (1 - splatControl)) * 20.0);
  135. opacityAsDensity += 0.001h * splatControl; // if all weights are zero, default to what the blend mask says
  136. half4 useOpacityAsDensityParam = { _DiffuseRemapScale0.w, _DiffuseRemapScale1.w, _DiffuseRemapScale2.w, _DiffuseRemapScale3.w }; // 1 is off
  137. splatControl = lerp(opacityAsDensity, splatControl, useOpacityAsDensityParam);
  138. }
  139. #endif
  140. // Now that splatControl has changed, we can compute the final weight and normalize
  141. weight = dot(splatControl, 1.0h);
  142. #ifdef TERRAIN_SPLAT_ADDPASS
  143. clip(weight <= 0.005h ? -1.0h : 1.0h);
  144. #endif
  145. #ifndef _TERRAIN_BASEMAP_GEN
  146. // Normalize weights before lighting and restore weights in final modifier functions so that the overal
  147. // lighting result can be correctly weighted.
  148. splatControl /= (weight + HALF_MIN);
  149. #endif
  150. mixedDiffuse = 0.0h;
  151. mixedDiffuse += diffAlbedo[0] * half4(_DiffuseRemapScale0.rgb * splatControl.rrr, 1.0h);
  152. mixedDiffuse += diffAlbedo[1] * half4(_DiffuseRemapScale1.rgb * splatControl.ggg, 1.0h);
  153. mixedDiffuse += diffAlbedo[2] * half4(_DiffuseRemapScale2.rgb * splatControl.bbb, 1.0h);
  154. mixedDiffuse += diffAlbedo[3] * half4(_DiffuseRemapScale3.rgb * splatControl.aaa, 1.0h);
  155. NormalMapMix(uvSplat01, uvSplat23, splatControl, mixedNormal);
  156. }
  157. #endif
  158. #ifdef _TERRAIN_BLEND_HEIGHT
  159. void HeightBasedSplatModify(inout half4 splatControl, in half4 masks[4])
  160. {
  161. // heights are in mask blue channel, we multiply by the splat Control weights to get combined height
  162. half4 splatHeight = half4(masks[0].b, masks[1].b, masks[2].b, masks[3].b) * splatControl.rgba;
  163. half maxHeight = max(splatHeight.r, max(splatHeight.g, max(splatHeight.b, splatHeight.a)));
  164. // Ensure that the transition height is not zero.
  165. half transition = max(_HeightTransition, 1e-5);
  166. // This sets the highest splat to "transition", and everything else to a lower value relative to that, clamping to zero
  167. // Then we clamp this to zero and normalize everything
  168. half4 weightedHeights = splatHeight + transition - maxHeight.xxxx;
  169. weightedHeights = max(0, weightedHeights);
  170. // We need to add an epsilon here for active layers (hence the blendMask again)
  171. // so that at least a layer shows up if everything's too low.
  172. weightedHeights = (weightedHeights + 1e-6) * splatControl;
  173. // Normalize (and clamp to epsilon to keep from dividing by zero)
  174. half sumHeight = max(dot(weightedHeights, half4(1, 1, 1, 1)), 1e-6);
  175. splatControl = weightedHeights / sumHeight.xxxx;
  176. }
  177. #endif
  178. void SplatmapFinalColor(inout half4 color, half fogCoord)
  179. {
  180. color.rgb *= color.a;
  181. #ifndef TERRAIN_GBUFFER // Technically we don't need fogCoord, but it is still passed from the vertex shader.
  182. #ifdef TERRAIN_SPLAT_ADDPASS
  183. color.rgb = MixFogColor(color.rgb, half3(0,0,0), fogCoord);
  184. #else
  185. color.rgb = MixFog(color.rgb, fogCoord);
  186. #endif
  187. #endif
  188. }
  189. ///////////////////////////////////////////////////////////////////////////////
  190. // Vertex and Fragment functions //
  191. ///////////////////////////////////////////////////////////////////////////////
  192. // Used in Standard Terrain shader
  193. Varyings SplatmapVert(Attributes v)
  194. {
  195. Varyings o = (Varyings)0;
  196. UNITY_SETUP_INSTANCE_ID(v);
  197. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  198. TerrainInstancing(v.positionOS, v.normalOS, v.texcoord);
  199. VertexPositionInputs Attributes = GetVertexPositionInputs(v.positionOS.xyz);
  200. o.uvMainAndLM.xy = v.texcoord;
  201. o.uvMainAndLM.zw = v.texcoord * unity_LightmapST.xy + unity_LightmapST.zw;
  202. #ifndef TERRAIN_SPLAT_BASEPASS
  203. o.uvSplat01.xy = TRANSFORM_TEX(v.texcoord, _Splat0);
  204. o.uvSplat01.zw = TRANSFORM_TEX(v.texcoord, _Splat1);
  205. o.uvSplat23.xy = TRANSFORM_TEX(v.texcoord, _Splat2);
  206. o.uvSplat23.zw = TRANSFORM_TEX(v.texcoord, _Splat3);
  207. #endif
  208. #if defined(DYNAMICLIGHTMAP_ON)
  209. o.dynamicLightmapUV = v.texcoord * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
  210. #endif
  211. #if defined(_NORMALMAP) && !defined(ENABLE_TERRAIN_PERPIXEL_NORMAL)
  212. half3 viewDirWS = GetWorldSpaceNormalizeViewDir(Attributes.positionWS);
  213. float4 vertexTangent = float4(cross(float3(0, 0, 1), v.normalOS), 1.0);
  214. VertexNormalInputs normalInput = GetVertexNormalInputs(v.normalOS, vertexTangent);
  215. o.normal = half4(normalInput.normalWS, viewDirWS.x);
  216. o.tangent = half4(normalInput.tangentWS, viewDirWS.y);
  217. o.bitangent = half4(normalInput.bitangentWS, viewDirWS.z);
  218. #else
  219. o.normal = TransformObjectToWorldNormal(v.normalOS);
  220. o.vertexSH = SampleSH(o.normal);
  221. #endif
  222. half fogFactor = 0;
  223. #if !defined(_FOG_FRAGMENT)
  224. fogFactor = ComputeFogFactor(Attributes.positionCS.z);
  225. #endif
  226. #ifdef _ADDITIONAL_LIGHTS_VERTEX
  227. o.fogFactorAndVertexLight.x = fogFactor;
  228. o.fogFactorAndVertexLight.yzw = VertexLighting(Attributes.positionWS, o.normal.xyz);
  229. #else
  230. o.fogFactor = fogFactor;
  231. #endif
  232. o.positionWS = Attributes.positionWS;
  233. o.clipPos = Attributes.positionCS;
  234. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  235. o.shadowCoord = GetShadowCoord(Attributes);
  236. #endif
  237. return o;
  238. }
  239. void ComputeMasks(out half4 masks[4], half4 hasMask, Varyings IN)
  240. {
  241. masks[0] = 0.5h;
  242. masks[1] = 0.5h;
  243. masks[2] = 0.5h;
  244. masks[3] = 0.5h;
  245. #ifdef _MASKMAP
  246. masks[0] = lerp(masks[0], SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy), hasMask.x);
  247. masks[1] = lerp(masks[1], SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw), hasMask.y);
  248. masks[2] = lerp(masks[2], SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy), hasMask.z);
  249. masks[3] = lerp(masks[3], SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw), hasMask.w);
  250. #endif
  251. masks[0] *= _MaskMapRemapScale0.rgba;
  252. masks[0] += _MaskMapRemapOffset0.rgba;
  253. masks[1] *= _MaskMapRemapScale1.rgba;
  254. masks[1] += _MaskMapRemapOffset1.rgba;
  255. masks[2] *= _MaskMapRemapScale2.rgba;
  256. masks[2] += _MaskMapRemapOffset2.rgba;
  257. masks[3] *= _MaskMapRemapScale3.rgba;
  258. masks[3] += _MaskMapRemapOffset3.rgba;
  259. }
  260. // Used in Standard Terrain shader
  261. #ifdef TERRAIN_GBUFFER
  262. FragmentOutput SplatmapFragment(Varyings IN)
  263. #else
  264. half4 SplatmapFragment(Varyings IN) : SV_TARGET
  265. #endif
  266. {
  267. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
  268. #ifdef _ALPHATEST_ON
  269. ClipHoles(IN.uvMainAndLM.xy);
  270. #endif
  271. half3 normalTS = half3(0.0h, 0.0h, 1.0h);
  272. #ifdef TERRAIN_SPLAT_BASEPASS
  273. half3 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).rgb;
  274. half smoothness = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uvMainAndLM.xy).a;
  275. half metallic = SAMPLE_TEXTURE2D(_MetallicTex, sampler_MetallicTex, IN.uvMainAndLM.xy).r;
  276. half alpha = 1;
  277. half occlusion = 1;
  278. #else
  279. half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3);
  280. half4 masks[4];
  281. ComputeMasks(masks, hasMask, IN);
  282. float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy;
  283. half4 splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV);
  284. half alpha = dot(splatControl, 1.0h);
  285. #ifdef _TERRAIN_BLEND_HEIGHT
  286. // disable Height Based blend when there are more than 4 layers (multi-pass breaks the normalization)
  287. if (_NumLayersCount <= 4)
  288. HeightBasedSplatModify(splatControl, masks);
  289. #endif
  290. half weight;
  291. half4 mixedDiffuse;
  292. half4 defaultSmoothness;
  293. SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS);
  294. half3 albedo = mixedDiffuse.rgb;
  295. half4 defaultMetallic = half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3);
  296. half4 defaultOcclusion = half4(_MaskMapRemapScale0.g, _MaskMapRemapScale1.g, _MaskMapRemapScale2.g, _MaskMapRemapScale3.g) +
  297. half4(_MaskMapRemapOffset0.g, _MaskMapRemapOffset1.g, _MaskMapRemapOffset2.g, _MaskMapRemapOffset3.g);
  298. half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a);
  299. defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask);
  300. half smoothness = dot(splatControl, defaultSmoothness);
  301. half4 maskMetallic = half4(masks[0].r, masks[1].r, masks[2].r, masks[3].r);
  302. defaultMetallic = lerp(defaultMetallic, maskMetallic, hasMask);
  303. half metallic = dot(splatControl, defaultMetallic);
  304. half4 maskOcclusion = half4(masks[0].g, masks[1].g, masks[2].g, masks[3].g);
  305. defaultOcclusion = lerp(defaultOcclusion, maskOcclusion, hasMask);
  306. half occlusion = dot(splatControl, defaultOcclusion);
  307. #endif
  308. InputData inputData;
  309. InitializeInputData(IN, normalTS, inputData);
  310. SETUP_DEBUG_TEXTURE_DATA(inputData, IN.uvMainAndLM.xy, _BaseMap);
  311. #if defined(_DBUFFER)
  312. half3 specular = half3(0.0h, 0.0h, 0.0h);
  313. ApplyDecal(IN.clipPos,
  314. albedo,
  315. specular,
  316. inputData.normalWS,
  317. metallic,
  318. occlusion,
  319. smoothness);
  320. #endif
  321. #ifdef TERRAIN_GBUFFER
  322. BRDFData brdfData;
  323. InitializeBRDFData(albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, alpha, brdfData);
  324. // Baked lighting.
  325. half4 color;
  326. Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask);
  327. MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask);
  328. color.rgb = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS);
  329. color.a = alpha;
  330. SplatmapFinalColor(color, inputData.fogCoord);
  331. // Dynamic lighting: emulate SplatmapFinalColor() by scaling gbuffer material properties. This will not give the same results
  332. // as forward renderer because we apply blending pre-lighting instead of post-lighting.
  333. // Blending of smoothness and normals is also not correct but close enough?
  334. brdfData.albedo.rgb *= alpha;
  335. brdfData.diffuse.rgb *= alpha;
  336. brdfData.specular.rgb *= alpha;
  337. brdfData.reflectivity *= alpha;
  338. inputData.normalWS = inputData.normalWS * alpha;
  339. smoothness *= alpha;
  340. return BRDFDataToGbuffer(brdfData, inputData, smoothness, color.rgb, occlusion);
  341. #else
  342. half4 color = UniversalFragmentPBR(inputData, albedo, metallic, /* specular */ half3(0.0h, 0.0h, 0.0h), smoothness, occlusion, /* emission */ half3(0, 0, 0), alpha);
  343. SplatmapFinalColor(color, inputData.fogCoord);
  344. return half4(color.rgb, 1.0h);
  345. #endif
  346. }
  347. // Shadow pass
  348. // Shadow Casting Light geometric parameters. These variables are used when applying the shadow Normal Bias and are set by UnityEngine.Rendering.Universal.ShadowUtils.SetupShadowCasterConstantBuffer in com.unity.render-pipelines.universal/Runtime/ShadowUtils.cs
  349. // For Directional lights, _LightDirection is used when applying shadow Normal Bias.
  350. // For Spot lights and Point lights, _LightPosition is used to compute the actual light direction because it is different at each shadow caster geometry vertex.
  351. float3 _LightDirection;
  352. float3 _LightPosition;
  353. struct AttributesLean
  354. {
  355. float4 position : POSITION;
  356. float3 normalOS : NORMAL;
  357. float2 texcoord : TEXCOORD0;
  358. UNITY_VERTEX_INPUT_INSTANCE_ID
  359. };
  360. struct VaryingsLean
  361. {
  362. float4 clipPos : SV_POSITION;
  363. float2 texcoord : TEXCOORD0;
  364. UNITY_VERTEX_OUTPUT_STEREO
  365. };
  366. VaryingsLean ShadowPassVertex(AttributesLean v)
  367. {
  368. VaryingsLean o = (VaryingsLean)0;
  369. UNITY_SETUP_INSTANCE_ID(v);
  370. TerrainInstancing(v.position, v.normalOS, v.texcoord);
  371. float3 positionWS = TransformObjectToWorld(v.position.xyz);
  372. float3 normalWS = TransformObjectToWorldNormal(v.normalOS);
  373. #if _CASTING_PUNCTUAL_LIGHT_SHADOW
  374. float3 lightDirectionWS = normalize(_LightPosition - positionWS);
  375. #else
  376. float3 lightDirectionWS = _LightDirection;
  377. #endif
  378. float4 clipPos = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
  379. #if UNITY_REVERSED_Z
  380. clipPos.z = min(clipPos.z, UNITY_NEAR_CLIP_VALUE);
  381. #else
  382. clipPos.z = max(clipPos.z, UNITY_NEAR_CLIP_VALUE);
  383. #endif
  384. o.clipPos = clipPos;
  385. o.texcoord = v.texcoord;
  386. return o;
  387. }
  388. half4 ShadowPassFragment(VaryingsLean IN) : SV_TARGET
  389. {
  390. #ifdef _ALPHATEST_ON
  391. ClipHoles(IN.texcoord);
  392. #endif
  393. return 0;
  394. }
  395. // Depth pass
  396. VaryingsLean DepthOnlyVertex(AttributesLean v)
  397. {
  398. VaryingsLean o = (VaryingsLean)0;
  399. UNITY_SETUP_INSTANCE_ID(v);
  400. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  401. TerrainInstancing(v.position, v.normalOS);
  402. o.clipPos = TransformObjectToHClip(v.position.xyz);
  403. o.texcoord = v.texcoord;
  404. return o;
  405. }
  406. half4 DepthOnlyFragment(VaryingsLean IN) : SV_TARGET
  407. {
  408. #ifdef _ALPHATEST_ON
  409. ClipHoles(IN.texcoord);
  410. #endif
  411. #ifdef SCENESELECTIONPASS
  412. // We use depth prepass for scene selection in the editor, this code allow to output the outline correctly
  413. return half4(_ObjectId, _PassValue, 1.0, 1.0);
  414. #endif
  415. return 0;
  416. }
  417. #endif