Lux URP Terrain Blend.shader 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. // TODO: https://community.khronos.org/t/slope-scale-depth-bias-in-opengl-3-2-core/62194/3
  2. Shader "Lux URP/Terrain/Blend"
  3. {
  4. Properties
  5. {
  6. [HeaderHelpLuxURP_URL(rti5rpeh441g)]
  7. [Header(Surface Blending)]
  8. [Space(8)]
  9. //_Offset ("Offset", Range(-300, 0)) = 0
  10. _Shift ("Depth Shift", Range(0.0, 0.3)) = 0.1
  11. [Space(5)]
  12. [NoScaleOffset]
  13. _TerrainHeightNormal ("Terrain Height Normal", 2D) = "white" {}
  14. [LuxURPVectorThreeDrawer]
  15. _TerrainPos ("Terrain Position", Vector) = (0,0,0,0)
  16. [LuxURPVectorThreeDrawer]
  17. _TerrainSize ("Terrain Size", Vector) = (1,1,1,0)
  18. [Space(5)]
  19. _AlphaShift ("Alpha Shift", Range(-5, 5)) = 0
  20. _AlphaWidth ("Alpha Contraction", Range(1, 20)) = 4
  21. [Space(5)]
  22. _ShadowShiftThreshold ("Shadow Shift Threshold", Range(0, 0.1)) = 0.05
  23. _ShadowShift ("Shadow Shift", Range(0, 1)) = 1
  24. _ShadowShiftView ("Shadow Shift View", Range(0, 1)) = 0
  25. [Space(5)]
  26. _NormalShift ("Normal Shift", Range(-5, 5)) = 0
  27. _NormalWidth ("Normal Contraction", Range(0, 20)) = 0
  28. _NormalThreshold ("Normal Threshold", Range(0,1)) = .2
  29. [Header(Surface Options)]
  30. [Space(8)]
  31. [Enum(UnityEngine.Rendering.CullMode)]
  32. _Cull ("Culling", Float) = 2
  33. [Enum(Off,0,On,1)]
  34. _ZWrite ("ZWrite", Int) = 1
  35. // [Toggle(_ALPHATEST_ON)]
  36. // _AlphaClip ("Alpha Clipping", Float) = 0.0
  37. // _Cutoff (" Threshold", Range(0.0, 1.0)) = 0.5
  38. [ToggleOff(_RECEIVE_SHADOWS_OFF)]
  39. _ReceiveShadows ("Receive Shadows", Float) = 1.0
  40. [Header(Surface Inputs)]
  41. [Space(8)]
  42. [MainColor]
  43. _BaseColor ("Color", Color) = (1,1,1,1)
  44. [MainTexture]
  45. _BaseMap ("Albedo (RGB) Alpha (A)", 2D) = "white" {}
  46. [Space(5)]
  47. _Smoothness ("Smoothness", Range(0.0, 1.0)) = 0.5
  48. _SpecColor ("Specular", Color) = (0.2, 0.2, 0.2)
  49. [Space(5)]
  50. [Toggle(_NORMALMAP)]
  51. _ApplyNormal ("Enable Normal Map", Float) = 0.0
  52. [NoScaleOffset]
  53. _BumpMap (" Normal Map", 2D) = "bump" {}
  54. _BumpScale (" Normal Scale", Float) = 1.0
  55. [Header(Advanced)]
  56. [Space(8)]
  57. [ToggleOff]
  58. _SpecularHighlights ("Enable Specular Highlights", Float) = 1.0
  59. [ToggleOff]
  60. _EnvironmentReflections ("Environment Reflections", Float) = 1.0
  61. [Space(5)]
  62. [Toggle(_RECEIVE_SHADOWS_OFF)]
  63. _Shadows ("Disable Receive Shadows", Float) = 0.0
  64. // Needed by the inspector
  65. [HideInInspector] _Culling ("Culling", Float) = 0.0
  66. // Lightmapper and outline selection shader need _MainTex, _Color and _Cutoff
  67. [HideInInspector] _MainTex ("Albedo", 2D) = "white" {}
  68. [HideInInspector] _Color ("Color", Color) = (1,1,1,1)
  69. [HideInInspector] _Cutoff ("Alpha Cutoff", Range(0.0, 1.0)) = 0.0
  70. }
  71. SubShader
  72. {
  73. Tags
  74. {
  75. "RenderPipeline" = "UniversalPipeline"
  76. "RenderType" = "Opaque"
  77. "Queue" = "Geometry+2"
  78. }
  79. LOD 100
  80. Pass
  81. {
  82. Name "ForwardLit"
  83. Tags{"LightMode" = "UniversalForward"}
  84. Blend SrcAlpha OneMinusSrcAlpha
  85. ZWrite [_ZWrite]
  86. Cull [_Cull]
  87. HLSLPROGRAM
  88. // Required to compile gles 2.0 with standard SRP library
  89. #pragma prefer_hlslcc gles
  90. #pragma exclude_renderers d3d11_9x
  91. #pragma target 2.0
  92. #if !defined(DEPTH_SEMANTIC)
  93. #if defined(SHADER_API_D3D11)
  94. #define DEPTH_SEMANTIC SV_DepthGreaterEqual
  95. #else
  96. #define DEPTH_SEMANTIC SV_Depth
  97. #endif
  98. #endif
  99. // -------------------------------------
  100. // Material Keywords
  101. #define _SPECULAR_SETUP 1
  102. #pragma shader_feature_local _NORMALMAP
  103. // #pragma shader_feature _ALPHATEST_ON
  104. // We have to sample SH per pixel
  105. #if defined (EVALUATE_SH_VERTEX)
  106. #undef EVALUATE_SH_VERTEX
  107. #endif
  108. #if defined(EVALUATE_SH_MIXED)
  109. #undef EVALUATE_SH_MIXED
  110. #endif
  111. #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
  112. #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
  113. #pragma shader_feature_local _RECEIVE_SHADOWS_OFF
  114. // -------------------------------------
  115. // Universal Pipeline keywords
  116. #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
  117. #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
  118. #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
  119. #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
  120. #pragma multi_compile_fragment _ _SHADOWS_SOFT
  121. #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
  122. #pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
  123. #pragma multi_compile _ SHADOWS_SHADOWMASK
  124. // -------------------------------------
  125. // Unity defined keywords
  126. #pragma multi_compile _ DIRLIGHTMAP_COMBINED
  127. #pragma multi_compile _ LIGHTMAP_ON
  128. #pragma multi_compile_fog
  129. //--------------------------------------
  130. // GPU Instancing
  131. #pragma multi_compile_instancing
  132. // #pragma multi_compile _ DOTS_INSTANCING_ON // needs shader target 4.5
  133. // Include base inputs and all other needed "base" includes
  134. #include "Includes/Lux URP Terrain Blend Inputs.hlsl"
  135. #pragma vertex LitPassVertex
  136. #pragma fragment LitPassFragment
  137. //--------------------------------------
  138. // Vertex shader
  139. VertexOutput LitPassVertex(VertexInput input)
  140. {
  141. VertexOutput output = (VertexOutput)0;
  142. UNITY_SETUP_INSTANCE_ID(input);
  143. UNITY_TRANSFER_INSTANCE_ID(input, output);
  144. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  145. VertexPositionInputs vertexInput;
  146. vertexInput = GetVertexPositionInputs(input.positionOS.xyz);
  147. VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
  148. float3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS;
  149. half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
  150. half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  151. // Pull positionCS.z towards camera / fine but clipping issues if we come very close. NANs?
  152. float fac = _ProjectionParams.y * 10;
  153. #if UNITY_REVERSED_Z
  154. vertexInput.positionCS.z += _Shift / max(_ProjectionParams.y, vertexInput.positionCS.w) * fac;
  155. #else
  156. vertexInput.positionCS.z -= _Shift / max(_ProjectionParams.y, vertexInput.positionCS.w) * fac;
  157. #endif
  158. output.uv.xy = TRANSFORM_TEX(input.texcoord, _BaseMap);
  159. // already normalized from normal transform to WS.
  160. output.normalWS = normalInput.normalWS;
  161. output.viewDirWS = viewDirWS;
  162. #ifdef _NORMALMAP
  163. float sign = input.tangentOS.w * GetOddNegativeScale();
  164. output.tangentWS = float4(normalInput.tangentWS.xyz, sign);
  165. #endif
  166. OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
  167. OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
  168. output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  169. //#ifdef _ADDITIONAL_LIGHTS
  170. output.positionWS = vertexInput.positionWS;
  171. //#endif
  172. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  173. output.shadowCoord = GetShadowCoord(vertexInput);
  174. #endif
  175. output.positionCS = vertexInput.positionCS;
  176. return output;
  177. }
  178. //--------------------------------------
  179. // Fragment shader and functions
  180. inline void InitializeSurfaceData(
  181. float2 uv,
  182. out SurfaceData outSurfaceData)
  183. {
  184. half4 albedoAlpha = SampleAlbedoAlpha(uv.xy, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
  185. outSurfaceData.alpha = Alpha(albedoAlpha.a, 1, _Cutoff);
  186. outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
  187. outSurfaceData.metallic = 0;
  188. outSurfaceData.specular = _SpecColor.rgb;
  189. outSurfaceData.smoothness = _Smoothness;
  190. outSurfaceData.smoothness *= albedoAlpha.a;
  191. outSurfaceData.occlusion = 1;
  192. // Normal Map
  193. #if defined (_NORMALMAP)
  194. outSurfaceData.normalTS = SampleNormal(uv.xy, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);
  195. #else
  196. outSurfaceData.normalTS = half3(0,0,1);
  197. #endif
  198. outSurfaceData.emission = 0;
  199. outSurfaceData.clearCoatMask = 0;
  200. outSurfaceData.clearCoatSmoothness = 0;
  201. }
  202. void InitializeInputData(VertexOutput input, half3 normalTS, half occlusion, half facing, out InputData inputData)
  203. {
  204. inputData = (InputData)0;
  205. #if defined(REQUIRES_WORLD_SPACE_POS_INTERPOLATOR)
  206. inputData.positionWS = input.positionWS;
  207. #endif
  208. half3 viewDirWS = SafeNormalize(input.viewDirWS);
  209. #if defined(_NORMALMAP)
  210. normalTS.z *= facing;
  211. float sgn = input.tangentWS.w; // should be either +1 or -1
  212. float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
  213. inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent.xyz, input.normalWS.xyz));
  214. #else
  215. inputData.normalWS = input.normalWS * facing;
  216. #endif
  217. inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
  218. inputData.viewDirectionWS = viewDirWS;
  219. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  220. inputData.shadowCoord = input.shadowCoord;
  221. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  222. inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  223. #else
  224. inputData.shadowCoord = float4(0, 0, 0, 0);
  225. #endif
  226. inputData.fogCoord = input.fogFactorAndVertexLight.x;
  227. inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
  228. inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH * occlusion, inputData.normalWS);
  229. //inputData.normalizedScreenSpaceUV = input.positionCS.xy;
  230. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
  231. inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
  232. }
  233. inline float DecodeFloatRG( float2 enc ) {
  234. float2 kDecodeDot = float2(1.0, 1/255.0);
  235. return dot( enc, kDecodeDot );
  236. }
  237. // half4 LitPassFragment(VertexOutput input, half facing : VFACE, out float outDepth : DEPTH_SEMANTIC) : SV_Target
  238. half4 LitPassFragment(VertexOutput input, half facing : VFACE) : SV_Target {
  239. UNITY_SETUP_INSTANCE_ID(input);
  240. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  241. // Get the surface description
  242. SurfaceData surfaceData;
  243. InitializeSurfaceData(input.uv, surfaceData);
  244. // Get terrain height
  245. float2 terrainUV = (input.positionWS.xz - _TerrainPos.xz) / _TerrainSize.xz;
  246. terrainUV = (terrainUV * (_TerrainHeightNormal_TexelSize.zw - 1.0f) + 0.5 ) * _TerrainHeightNormal_TexelSize.xy;
  247. half4 terrainSample = SAMPLE_TEXTURE2D_LOD(_TerrainHeightNormal, sampler_TerrainHeightNormal, terrainUV, 0);
  248. float terrainHeight = DecodeFloatRG(terrainSample.rg) * _TerrainSize.y + _TerrainPos.y;
  249. surfaceData.alpha = smoothstep(0.0h, 1.0h, 1.0h - saturate( (terrainHeight - input.positionWS.y + _AlphaShift) * _AlphaWidth ) );
  250. // Blend geometry normal towards the terrain normal
  251. half3 terrainNormal;
  252. // This is not a tangent normal! So we have to swizzle y and z.
  253. terrainNormal.xz = terrainSample.ba * 2.0 - 1.0;
  254. terrainNormal.y = sqrt(1.0 - saturate(dot(terrainNormal.xz, terrainNormal.xz)));
  255. half normalBlend = saturate( (terrainHeight - input.positionWS.y + _NormalShift) * _NormalWidth );
  256. normalBlend = normalBlend * (smoothstep( 0, _NormalThreshold, saturate(dot(terrainNormal.xyz, input.normalWS.xyz ))));
  257. normalBlend = 1.0h - normalBlend;
  258. input.normalWS.xyz = lerp( terrainNormal.xyz, input.normalWS.xyz, normalBlend);
  259. // Prepare surface data (like bring normal into world space and get missing inputs like gi)
  260. InputData inputData;
  261. InitializeInputData(input, surfaceData.normalTS, surfaceData.occlusion, facing, inputData);
  262. // shadowShift contains the (tweaked) distance to the terrain surface for pixels under the terrain
  263. float shadowShift = -min(0, input.positionWS.y - _ShadowShiftThreshold - terrainHeight);
  264. float3 viewShift = shadowShift * _ShadowShiftView * inputData.viewDirectionWS;
  265. shadowShift *= _ShadowShift;
  266. float3 finalShift = float3(0, shadowShift, 0) + viewShift;
  267. // Calculate shadowCoord. We have to do it per pixel :(
  268. #if defined(_MAIN_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
  269. #if defined(_MAIN_LIGHT_SHADOWS_CASCADE)
  270. half cascadeIndex = ComputeCascadeIndex(input.positionWS);
  271. #else
  272. half cascadeIndex = 0;
  273. #endif
  274. // As we do not want shadows on the blended parts from the geometry they intersect with we have to "somehow" shift the shadowCoords.
  275. // Shifting along view dir: Best so far...
  276. // inputData.shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(input.positionWS + inputData.viewDirectionWS * _ShadowShift /*_AlphaShift*/, 1.0));
  277. // Pulling pixels towards the light fails if we look along the light direction...
  278. // inputData.shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(input.positionWS + _MainLightPosition.xyz * _ShadowShift /*_AlphaShift*/, 1.0));
  279. // Shifting along the terrain normal?
  280. // inputData.shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(input.positionWS + terrainNormal * _ShadowShift * shadowShift , 1.0));
  281. // We simply lift the shadow sampling coord
  282. inputData.shadowCoord = mul(_MainLightWorldToShadow[cascadeIndex], float4(input.positionWS + finalShift, 1.0));
  283. #endif
  284. // Tweak viewDir
  285. half3 tweakedViewDir = GetCameraPositionWS() - float3(input.positionWS.x, terrainHeight, input.positionWS.z);
  286. tweakedViewDir = SafeNormalize(tweakedViewDir);
  287. inputData.viewDirectionWS = lerp(tweakedViewDir, inputData.viewDirectionWS, normalBlend);
  288. // Apply lighting
  289. //half4 color = UniversalFragmentPBR
  290. half4 color = LuxFragmentBlendPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha,
  291. finalShift
  292. );
  293. // Add fog
  294. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  295. return color;
  296. }
  297. ENDHLSL
  298. }
  299. // Shadows -----------------------------------------------------
  300. Pass
  301. {
  302. Name "ShadowCaster"
  303. Tags{"LightMode" = "ShadowCaster"}
  304. ZWrite On
  305. ZTest LEqual
  306. ColorMask 0
  307. Cull Back
  308. HLSLPROGRAM
  309. // Required to compile gles 2.0 with standard srp library
  310. #pragma prefer_hlslcc gles
  311. #pragma exclude_renderers d3d11_9x
  312. #pragma target 2.0
  313. // -------------------------------------
  314. // Material Keywords
  315. //#pragma shader_feature _ALPHATEST_ON
  316. //--------------------------------------
  317. // GPU Instancing
  318. #pragma multi_compile_instancing
  319. // #pragma multi_compile _ DOTS_INSTANCING_ON // needs shader target 4.5
  320. #pragma vertex ShadowPassVertex
  321. #pragma fragment ShadowPassFragment
  322. // Include base inputs and all other needed "base" includes
  323. #include "Includes/Lux URP Terrain Blend Inputs.hlsl"
  324. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
  325. // Shadow caster specific input
  326. float3 _LightDirection;
  327. VertexOutput ShadowPassVertex(VertexInput input)
  328. {
  329. VertexOutput output = (VertexOutput)0;
  330. UNITY_SETUP_INSTANCE_ID(input);
  331. UNITY_TRANSFER_INSTANCE_ID(input, output);
  332. #if defined(_ALPHATEST_ON)
  333. output.uv.xy = TRANSFORM_TEX(input.texcoord, _BaseMap);
  334. #endif
  335. float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
  336. float3 normalWS = TransformObjectToWorldDir(input.normalOS);
  337. output.positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));
  338. #if UNITY_REVERSED_Z
  339. output.positionCS.z = min(output.positionCS.z, output.positionCS.w * UNITY_NEAR_CLIP_VALUE);
  340. #else
  341. output.positionCS.z = max(output.positionCS.z, output.positionCS.w * UNITY_NEAR_CLIP_VALUE);
  342. #endif
  343. return output;
  344. }
  345. half4 ShadowPassFragment(VertexOutput input) : SV_TARGET
  346. {
  347. UNITY_SETUP_INSTANCE_ID(input);
  348. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  349. #if defined(_ALPHATEST_ON)
  350. half mask = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).a;
  351. clip (mask - _Cutoff);
  352. #endif
  353. return 0;
  354. }
  355. ENDHLSL
  356. }
  357. // Depth -----------------------------------------------------
  358. Pass
  359. {
  360. Tags{"LightMode" = "DepthOnly"}
  361. ZWrite On
  362. ColorMask 0
  363. Cull Back
  364. HLSLPROGRAM
  365. // Required to compile gles 2.0 with standard srp library
  366. #pragma prefer_hlslcc gles
  367. #pragma exclude_renderers d3d11_9x
  368. #pragma target 2.0
  369. #pragma vertex DepthOnlyVertex
  370. #pragma fragment DepthOnlyFragment
  371. // -------------------------------------
  372. // Material Keywords
  373. // #pragma shader_feature _ALPHATEST_ON
  374. //--------------------------------------
  375. // GPU Instancing
  376. #pragma multi_compile_instancing
  377. // #pragma multi_compile _ DOTS_INSTANCING_ON // needs shader target 4.5
  378. #define DEPTHONLYPASS
  379. #include "Includes/Lux URP Terrain Blend Inputs.hlsl"
  380. VertexOutput DepthOnlyVertex(VertexInput input)
  381. {
  382. VertexOutput output = (VertexOutput)0;
  383. UNITY_SETUP_INSTANCE_ID(input);
  384. UNITY_TRANSFER_INSTANCE_ID(input, output);
  385. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  386. #if defined(_ALPHATEST_ON)
  387. output.uv.xy = TRANSFORM_TEX(input.texcoord, _BaseMap);
  388. #endif
  389. output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
  390. return output;
  391. }
  392. half4 DepthOnlyFragment(VertexOutput input) : SV_TARGET
  393. {
  394. UNITY_SETUP_INSTANCE_ID(input);
  395. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  396. #if defined(_ALPHATEST_ON)
  397. half mask = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv.xy).a;
  398. clip (mask - _Cutoff);
  399. #endif
  400. return 0;
  401. }
  402. ENDHLSL
  403. }
  404. // This pass is used when drawing to a _CameraNormalsTexture texture
  405. Pass
  406. {
  407. Name "DepthNormals"
  408. Tags{"LightMode" = "DepthNormals"}
  409. ZWrite On
  410. Cull[_Cull]
  411. HLSLPROGRAM
  412. #pragma exclude_renderers d3d11_9x
  413. #pragma target 2.0
  414. #pragma vertex DepthNormalVertex
  415. #pragma fragment DepthNormalFragment
  416. // -------------------------------------
  417. // Material Keywords
  418. //--------------------------------------
  419. // GPU Instancing
  420. #pragma multi_compile_instancing
  421. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  422. CBUFFER_START(UnityPerMaterial)
  423. float3 _TerrainPos;
  424. float3 _TerrainSize;
  425. float4 _TerrainHeightNormal_TexelSize;
  426. float _Shift;
  427. half _AlphaShift;
  428. half _AlphaWidth;
  429. float _ShadowShiftThreshold;
  430. float _ShadowShift;
  431. float _ShadowShiftView;
  432. half _NormalShift;
  433. half _NormalWidth;
  434. half _NormalThreshold;
  435. half _BumpScale;
  436. half4 _BaseColor;
  437. half _Cutoff;
  438. float4 _BaseMap_ST;
  439. half _Smoothness;
  440. half4 _SpecColor;
  441. //half _OcclusionStrength;
  442. CBUFFER_END
  443. TEXTURE2D(_TerrainHeightNormal); SAMPLER(sampler_TerrainHeightNormal);
  444. // Material Inputs
  445. struct VertexInput {
  446. float3 positionOS : POSITION;
  447. float3 normalOS : NORMAL;
  448. UNITY_VERTEX_INPUT_INSTANCE_ID
  449. };
  450. struct VertexOutput {
  451. float4 positionCS : SV_POSITION;
  452. float3 positionWS : TEXCOORD0;
  453. float3 normalWS : TEXCOORD1;
  454. UNITY_VERTEX_INPUT_INSTANCE_ID
  455. UNITY_VERTEX_OUTPUT_STEREO
  456. };
  457. inline float DecodeFloatRG( float2 enc ) {
  458. float2 kDecodeDot = float2(1.0, 1/255.0);
  459. return dot( enc, kDecodeDot );
  460. }
  461. VertexOutput DepthNormalVertex(VertexInput input)
  462. {
  463. VertexOutput output = (VertexOutput)0;
  464. UNITY_SETUP_INSTANCE_ID(input);
  465. UNITY_TRANSFER_INSTANCE_ID(input, output);
  466. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  467. output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
  468. output.normalWS = TransformObjectToWorldDir(input.normalOS, true);
  469. output.positionWS = TransformObjectToWorld(input.positionOS).xyz;
  470. // Start skipped
  471. // // Get terrain height
  472. // float2 terrainUV = (output.positionWS.xz - _TerrainPos.xz) / _TerrainSize.xz;
  473. // terrainUV = (terrainUV * (_TerrainHeightNormal_TexelSize.zw - 1.0f) + 0.5 ) * _TerrainHeightNormal_TexelSize.xy;
  474. // half4 terrainSample = SAMPLE_TEXTURE2D_LOD(_TerrainHeightNormal, sampler_TerrainHeightNormal, terrainUV, 0);
  475. // float terrainHeight = DecodeFloatRG(terrainSample.rg) * _TerrainSize.y + _TerrainPos.y;
  476. // float alpha = smoothstep(0.0f, 1.0f, 1.0f - saturate( (terrainHeight - output.positionWS.y + _AlphaShift) * _AlphaWidth ) );
  477. // // Blend geometry normal towards the terrain normal
  478. // half3 terrainNormal;
  479. // // This is not a tangent normal! So we have to swizzle y and z.
  480. // terrainNormal.xz = terrainSample.ba * 2.0 - 1.0;
  481. // terrainNormal.y = sqrt(1.0 - saturate(dot(terrainNormal.xz, terrainNormal.xz)));
  482. // half normalBlend = saturate( (terrainHeight - output.positionWS.y + _NormalShift) * _NormalWidth );
  483. // normalBlend = normalBlend * (smoothstep( 0, _NormalThreshold, saturate(dot(terrainNormal.xyz, output.normalWS.xyz ))));
  484. // normalBlend = 1.0h - normalBlend;
  485. // //output.normalWS = lerp( terrainNormal.xyz, output.normalWS, normalBlend);
  486. // // End skipped
  487. // Pull positionCS.z towards camera / fine but clipping issues if we come very close. NANs?
  488. float fac = _ProjectionParams.y * 10;
  489. #if UNITY_REVERSED_Z
  490. output.positionCS.z += _Shift / max(_ProjectionParams.y, output.positionCS.w) * fac;
  491. #else
  492. output.positionCS.z -= _Shift / max(_ProjectionParams.y, output.positionCS.w) * fac;
  493. #endif
  494. return output;
  495. }
  496. half4 DepthNormalFragment(VertexOutput input) : SV_TARGET
  497. {
  498. UNITY_SETUP_INSTANCE_ID(input);
  499. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  500. // Get terrain height
  501. // float2 terrainUV = (input.positionWS.xz - _TerrainPos.xz) / _TerrainSize.xz;
  502. // terrainUV = (terrainUV * (_TerrainHeightNormal_TexelSize.zw - 1.0f) + 0.5 ) * _TerrainHeightNormal_TexelSize.xy;
  503. // half4 terrainSample = SAMPLE_TEXTURE2D_LOD(_TerrainHeightNormal, sampler_TerrainHeightNormal, terrainUV, 0);
  504. // float terrainHeight = DecodeFloatRG(terrainSample.rg) * _TerrainSize.y + _TerrainPos.y;
  505. // float alpha = smoothstep(0.0f, 1.0f, 1.0f - saturate( (terrainHeight - input.positionWS.y + _AlphaShift) * _AlphaWidth ) );
  506. // // Blend geometry normal towards the terrain normal
  507. // half3 terrainNormal;
  508. // // This is not a tangent normal! So we have to swizzle y and z.
  509. // terrainNormal.xz = terrainSample.ba * 2.0 - 1.0;
  510. // terrainNormal.y = sqrt(1.0 - saturate(dot(terrainNormal.xz, terrainNormal.xz)));
  511. // half normalBlend = saturate( (terrainHeight - input.positionWS.y + _NormalShift) * _NormalWidth );
  512. // // normalBlend = normalBlend * (smoothstep( 0, _NormalThreshold, saturate(dot(terrainNormal.xyz, input.normalWS.xyz ))));
  513. // // Always blend normal if below the terrain
  514. // float blendFactor = smoothstep( 0, _NormalThreshold, saturate(dot(terrainNormal.xyz, input.normalWS.xyz )));
  515. // blendFactor = (terrainHeight > input.positionWS.y) ? 1 : blendFactor;
  516. // normalBlend = normalBlend * blendFactor;
  517. // normalBlend = 1.0h - normalBlend;
  518. // We better do not tweak the normal here - as it further increases the "error" between depth and normal.
  519. // So the code above is just obsolete.
  520. // input.normalWS.xyz = lerp( terrainNormal.xyz, input.normalWS.xyz, normalBlend);
  521. float3 normal = input.normalWS;
  522. return float4(PackNormalOctRectEncode(TransformWorldToViewDir(normal, true)), 0.0, 0.0);
  523. }
  524. ENDHLSL
  525. }
  526. // Meta -----------------------------------------------------
  527. Pass
  528. {
  529. Tags{"LightMode" = "Meta"}
  530. Cull Off
  531. HLSLPROGRAM
  532. // Required to compile gles 2.0 with standard srp library
  533. #pragma prefer_hlslcc gles
  534. #pragma vertex UniversalVertexMeta
  535. #pragma fragment UniversalFragmentMeta
  536. //#define _SPECULAR_SETUP
  537. // First include all our custom stuff
  538. #include "Includes/Lux URP Terrain Blend Inputs.hlsl"
  539. //--------------------------------------
  540. // Fragment shader and functions
  541. inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
  542. {
  543. half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
  544. outSurfaceData.alpha = 1;
  545. outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
  546. outSurfaceData.metallic = 0;
  547. outSurfaceData.specular = _SpecColor.rgb;
  548. outSurfaceData.smoothness = _Smoothness;
  549. outSurfaceData.normalTS = half3(0,0,1);
  550. outSurfaceData.occlusion = 1;
  551. outSurfaceData.emission = 0;
  552. outSurfaceData.clearCoatMask = 0;
  553. outSurfaceData.clearCoatSmoothness = 0;
  554. }
  555. // Finally include the meta pass related stuff
  556. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
  557. ENDHLSL
  558. }
  559. // End Passes -----------------------------------------------------
  560. }
  561. FallBack "Hidden/InternalErrorShader"
  562. }