Lux URP Grass TextureDisplace.shader 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. // Shader uses custom editor to set double sided GI
  2. // Needs _Culling to be set properly
  3. Shader "Lux URP/Vegetation/Grass TextureDisplace"
  4. {
  5. Properties
  6. {
  7. [Header(Surface Options)]
  8. [Space(8)]
  9. [Enum(UnityEngine.Rendering.CullMode)]
  10. _Cull ("Culling", Float) = 0
  11. [Toggle(_ALPHATEST_ON)]
  12. _AlphaClip ("Alpha Clipping", Float) = 1.0
  13. _Cutoff (" Threshold", Range(0.0, 1.0)) = 0.5
  14. [ToggleOff(_RECEIVE_SHADOWS_OFF)]
  15. _ReceiveShadows ("Receive Shadows", Float) = 1.0
  16. [Header(Surface Inputs)]
  17. [Space(8)]
  18. [NoScaleOffset] [MainTexture]
  19. _BaseMap ("Albedo (RGB) Alpha (A)", 2D) = "white" {}
  20. [HideInInspector] [MainColor]
  21. _BaseColor ("Color", Color) = (1,1,1,1)
  22. [Space(5)]
  23. [Toggle(_NORMALMAP)]
  24. _EnableNormal ("Enable Normal Map", Float) = 0
  25. [NoScaleOffset] _BumpMap (" Normal Map", 2D) = "bump" {}
  26. _BumpScale (" Normal Scale", Float) = 1.0
  27. [Space(5)]
  28. _Smoothness ("Smoothness", Range(0.0, 1.0)) = 0.5
  29. _SpecColor ("Specular", Color) = (0.2, 0.2, 0.2)
  30. _Occlusion ("Occlusion", Range(0.0, 1.0)) = 1.0
  31. [Header(Wind)]
  32. [Space(8)]
  33. [KeywordEnum(Blue, Alpha)]
  34. _BendingMode ("Main Bending", Float) = 0
  35. [Space(5)]
  36. [LuxLWRPWindGrassDrawer]
  37. _WindMultiplier ("Wind Strength (X) Normal Strength (Y) Sample Size (Z) Lod Level (W)", Vector) = (1, 2, 1, 0)
  38. [Header(Displacement)]
  39. [Space(8)]
  40. _DisplacementSampleSize ("Sample Size", Range(0.0, 1)) = .5
  41. _DisplacementStrength ("Displacement XZ", Range(0.0, 16.0)) = 4
  42. _DisplacementStrengthVertical ("Displacement Y", Range(0.0, 16.0)) = 4
  43. _NormalDisplacement ("Normal Displacement", Range(-2, 2)) = 1
  44. [Header(Distance Fading)]
  45. [Space(8)]
  46. [LuxURPDistanceFadeDrawer]
  47. _DistanceFade ("Distance Fade Params", Vector) = (900, 0.005, 0, 0)
  48. [Header(Advanced)]
  49. [Space(8)]
  50. [Toggle(_BLINNPHONG)]
  51. _BlinnPhong ("Enable Blinn Phong Lighting", Float) = 0.0
  52. [Space(5)]
  53. [ToggleOff]
  54. _SpecularHighlights ("Enable Specular Highlights", Float) = 1.0
  55. [ToggleOff]
  56. _EnvironmentReflections ("Environment Reflections", Float) = 1.0
  57. // Needed by the inspector
  58. [HideInInspector] _Culling ("Culling", Float) = 0.0
  59. // Lightmapper and outline selection shader need _MainTex, _Color and _Cutoff
  60. [HideInInspector] _MainTex ("Albedo", 2D) = "white" {}
  61. [HideInInspector] _Color ("Color", Color) = (1,1,1,1)
  62. }
  63. SubShader
  64. {
  65. Tags
  66. {
  67. "RenderPipeline" = "UniversalPipeline"
  68. "RenderType" = "TransparentCutout"
  69. "IgnoreProjector" = "True"
  70. "Queue"="AlphaTest"
  71. }
  72. LOD 100
  73. Pass
  74. {
  75. Tags{"LightMode" = "UniversalForward"}
  76. ZWrite On
  77. Cull [_Cull]
  78. HLSLPROGRAM
  79. // Required to compile gles 2.0 with standard SRP library
  80. #pragma prefer_hlslcc gles
  81. #pragma exclude_renderers d3d11_9x
  82. // Shader target needs to be 3.0 due to tex2Dlod in the vertex shader
  83. #pragma target 3.0
  84. // -------------------------------------
  85. // Material Keywords
  86. #pragma shader_feature_local _NORMALMAP
  87. #pragma shader_feature_local _ALPHATEST_ON
  88. #define _SPECULAR_SETUP 1
  89. #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF
  90. #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF
  91. #pragma shader_feature_local _RECEIVE_SHADOWS_OFF
  92. #pragma shader_feature_local_fragment _BLINNPHONG
  93. #pragma shader_feature_local _BENDINGMODE_ALPHA
  94. // Needed to make BlinnPhong work
  95. #define _SPECULAR_COLOR
  96. // -------------------------------------
  97. // Universal Pipeline keywords
  98. #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
  99. #pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
  100. #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
  101. #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
  102. #pragma multi_compile_fragment _ _SHADOWS_SOFT
  103. #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION
  104. // No light map support here...
  105. //#pragma multi_compile _ LIGHTMAP_SHADOW_MIXING
  106. //#pragma multi_compile _ SHADOWS_SHADOWMASK
  107. // -------------------------------------
  108. // Unity defined keywords
  109. #pragma multi_compile _ DIRLIGHTMAP_COMBINED
  110. #pragma multi_compile _ LIGHTMAP_ON
  111. #pragma multi_compile_fog
  112. //--------------------------------------
  113. // GPU Instancing
  114. #pragma multi_compile_instancing
  115. #pragma multi_compile _ DOTS_INSTANCING_ON
  116. // Include base inputs and all other needed "base" includes
  117. #include "Includes/Lux URP Grass Inputs.hlsl"
  118. #pragma vertex LitPassVertex
  119. #pragma fragment LitPassFragment
  120. //--------------------------------------
  121. // Vertex shader
  122. VertexOutput LitPassVertex(VertexInput input)
  123. {
  124. VertexOutput output = (VertexOutput)0;
  125. UNITY_SETUP_INSTANCE_ID(input);
  126. UNITY_TRANSFER_INSTANCE_ID(input, output);
  127. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  128. // VSPro like vertex colors
  129. #if defined (_BENDINGMODE_ALPHA)
  130. #define bendAmount input.color.a
  131. #else
  132. #define bendAmount input.color.b
  133. #endif
  134. #define phase input.color.gg
  135. #define vocclusion input.color.r
  136. float3 worldInstancePos = UNITY_MATRIX_M._m03_m13_m23;
  137. #if !defined(_ALPHATEST_ON)
  138. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  139. float dist = dot(diff, diff);
  140. output.fadeOcclusion.x = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  141. // Shrinken mesh if alpha testing is disabled
  142. input.positionOS.xyz *= output.fadeOcclusion.x;
  143. #endif
  144. // Wind in WorldSpace -------------------------------
  145. VertexPositionInputs vertexInput;
  146. vertexInput.positionWS = TransformObjectToWorld(input.positionOS.xyz);
  147. float3 cachedPositionWS = vertexInput.positionWS;
  148. // Do the texture lookup as soon as possible
  149. half4 wind = SAMPLE_TEXTURE2D_LOD(_LuxLWRPWindRT, sampler_LuxLWRPWindRT, vertexInput.positionWS.xz * _LuxLWRPWindDirSize.w + phase * _WindMultiplier.z, _WindMultiplier.w);
  150. // Do as much as possible unrelated to the final position afterwards to hide latency
  151. VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
  152. half windStrength = bendAmount * _LuxLWRPWindStrengthMultipliers.x * _WindMultiplier.x;
  153. half3 windDir = _LuxLWRPWindDirSize.xyz;
  154. half2 normalWindDir = windDir.xz * _WindMultiplier.y;
  155. // Set distance fade value
  156. #if defined(_ALPHATEST_ON)
  157. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  158. float dist = dot(diff, diff);
  159. output.fadeOcclusion.x = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  160. #endif
  161. // Do other stuff here
  162. output.uv.xy = input.texcoord;
  163. output.fadeOcclusion.y = lerp(1.0h, vocclusion, _Occlusion);
  164. OUTPUT_LIGHTMAP_UV(input.lightmapUV, unity_LightmapST, output.lightmapUV);
  165. // From now on we rely on the texture sample being available
  166. wind.r = wind.r * (wind.g * 2.0h - 0.243h /* not a "real" normal as we want to keep the base direction */ );
  167. windStrength *= wind.r;
  168. vertexInput.positionWS.xz += windDir.xz * windStrength;
  169. // Do something to the normal as well
  170. normalInput.normalWS.xz += normalWindDir * windStrength;
  171. #ifdef _NORMALMAP
  172. normalInput.normalWS = NormalizeNormalPerVertex(normalInput.normalWS);
  173. #endif
  174. // Displacement
  175. float2 samplePos = lerp(worldInstancePos.xz, cachedPositionWS.xz, _DisplacementSampleSize) - _Lux_DisplacementPosition.xy; // lower left corner
  176. samplePos = samplePos * _Lux_DisplacementPosition.z; // _Lux_DisplacementPosition.z = one OverSize
  177. if(samplePos.x >= 0.0f && samplePos.x <= 1.0f) {
  178. if(samplePos.y >= 0.0f && samplePos.y <= 1.0f) {
  179. half2 radialMask = (samplePos.xy * 2 - 1);
  180. half finalMask = 1 - dot(radialMask, radialMask);
  181. finalMask = smoothstep(0, 0.5, finalMask);
  182. if (finalMask > 0) {
  183. half4 displacementSample = SAMPLE_TEXTURE2D_LOD(_Lux_DisplacementRT, sampler_Lux_DisplacementRT, samplePos, 0);
  184. half3 bend = ( (displacementSample.rgb * 2 - 1)) * bendAmount;
  185. // Blue usually is close to 1 (speaking of a normal). So we use saturate to get only the negative part.
  186. bend.z = (saturate(displacementSample.b * 2) - 1) * bendAmount;
  187. bend *= finalMask;
  188. half3 disp;
  189. disp.xz = bend.xy * _DisplacementStrength;
  190. disp.y = -(abs(bend.x) + abs(bend.y) - bend.z) * _DisplacementStrengthVertical;
  191. //vertexInput.positionWS = lerp(vertexInput.positionWS, cachedPositionWS + disp, saturate(length(disp)*4) );
  192. vertexInput.positionWS = lerp(vertexInput.positionWS, cachedPositionWS + disp, saturate(dot(disp, disp)*16) );
  193. // Do something to the normal. Sign looks fine (reversed).
  194. normalInput.normalWS = normalInput.normalWS + disp * PI * _NormalDisplacement;
  195. }
  196. }
  197. }
  198. // We have to recalculate ClipPos! / see: GetVertexPositionInputs in Core.hlsl
  199. vertexInput.positionVS = TransformWorldToView(vertexInput.positionWS);
  200. vertexInput.positionCS = TransformWorldToHClip(vertexInput.positionWS);
  201. float4 ndc = vertexInput.positionCS * 0.5f;
  202. vertexInput.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
  203. vertexInput.positionNDC.zw = vertexInput.positionCS.zw;
  204. // End Wind -------------------------------
  205. float3 viewDirWS = GetCameraPositionWS() - vertexInput.positionWS;
  206. half3 vertexLight = VertexLighting(vertexInput.positionWS, normalInput.normalWS);
  207. half fogFactor = ComputeFogFactor(vertexInput.positionCS.z);
  208. output.normalWS = normalInput.normalWS;
  209. output.viewDirWS = viewDirWS;
  210. #ifdef _NORMALMAP
  211. float sign = input.tangentOS.w * GetOddNegativeScale();
  212. output.tangentWS = float4(normalInput.tangentWS.xyz, sign);
  213. #endif
  214. OUTPUT_SH(output.normalWS.xyz, output.vertexSH);
  215. output.fogFactorAndVertexLight = half4(fogFactor, vertexLight);
  216. // #ifdef _ADDITIONAL_LIGHTS
  217. output.positionWS = vertexInput.positionWS;
  218. // #endif
  219. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  220. output.shadowCoord = GetShadowCoord(vertexInput);
  221. #endif
  222. output.positionCS = vertexInput.positionCS;
  223. return output;
  224. }
  225. //--------------------------------------
  226. // Fragment shader and functions
  227. //inline void InitializeGrassLitSurfaceData(float2 uv, half2 fadeOcclusion, out SurfaceDescription outSurfaceData)
  228. inline void InitializeGrassLitSurfaceData(float2 uv, half2 fadeOcclusion, out SurfaceData outSurfaceData)
  229. {
  230. half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
  231. // Add fade
  232. albedoAlpha.a *= fadeOcclusion.x;
  233. // Early out
  234. outSurfaceData.alpha = Alpha(albedoAlpha.a, 1, _Cutoff);
  235. outSurfaceData.albedo = albedoAlpha.rgb;
  236. outSurfaceData.metallic = 0;
  237. outSurfaceData.specular = _SpecColor.rgb;
  238. // Normal Map
  239. #if defined (_NORMALMAP)
  240. //outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap));
  241. half4 sampleNormal = SAMPLE_TEXTURE2D(_BumpMap, sampler_BumpMap, uv);
  242. outSurfaceData.normalTS = UnpackNormalScale(sampleNormal, _BumpScale);
  243. #else
  244. outSurfaceData.normalTS = float3(0, 0, 1);
  245. #endif
  246. outSurfaceData.smoothness = _Smoothness;
  247. outSurfaceData.occlusion = fadeOcclusion.y;
  248. outSurfaceData.emission = 0;
  249. outSurfaceData.clearCoatMask = 0;
  250. outSurfaceData.clearCoatSmoothness = 0;
  251. }
  252. void InitializeInputData(VertexOutput input, half3 normalTS, out InputData inputData)
  253. {
  254. inputData = (InputData)0;
  255. inputData.positionWS = input.positionWS;
  256. half3 viewDirWS = SafeNormalize(input.viewDirWS);
  257. #ifdef _NORMALMAP
  258. float sgn = input.tangentWS.w; // should be either +1 or -1
  259. float3 bitangent = sgn * cross(input.normalWS.xyz, input.tangentWS.xyz);
  260. inputData.normalWS = TransformTangentToWorld(normalTS, half3x3(input.tangentWS.xyz, bitangent, input.normalWS.xyz));
  261. #else
  262. inputData.normalWS = input.normalWS;
  263. #endif
  264. inputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);
  265. inputData.viewDirectionWS = viewDirWS;
  266. #if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)
  267. inputData.shadowCoord = input.shadowCoord;
  268. #elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)
  269. inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);
  270. #else
  271. inputData.shadowCoord = float4(0, 0, 0, 0);
  272. #endif
  273. inputData.fogCoord = input.fogFactorAndVertexLight.x;
  274. inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;
  275. inputData.bakedGI = SAMPLE_GI(input.lightmapUV, input.vertexSH, inputData.normalWS);
  276. inputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);
  277. //inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV);
  278. }
  279. half4 LitPassFragment(VertexOutput input) : SV_Target
  280. {
  281. UNITY_SETUP_INSTANCE_ID(input);
  282. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  283. // Get the surface description
  284. //SurfaceDescription surfaceData;
  285. SurfaceData surfaceData;
  286. InitializeGrassLitSurfaceData(input.uv.xy, input.fadeOcclusion, surfaceData);
  287. // Prepare surface data (like bring normal into world space) and get missing inputs like gi
  288. InputData inputData;
  289. InitializeInputData(input, surfaceData.normalTS, inputData);
  290. // Apply lighting
  291. #if defined(_BLINNPHONG)
  292. surfaceData.smoothness = max(0.01, surfaceData.smoothness);
  293. half4 color = LightweightFragmentBlinnPhong(inputData, surfaceData.albedo, half4(surfaceData.specular, surfaceData.smoothness), surfaceData.smoothness, surfaceData.emission, surfaceData.alpha);
  294. #else
  295. //half4 color = LightweightFragmentPBR(inputData, surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.occlusion, surfaceData.emission, surfaceData.alpha);
  296. half4 color = UniversalFragmentPBR(inputData, surfaceData);
  297. #endif
  298. // Add fog
  299. color.rgb = MixFog(color.rgb, inputData.fogCoord);
  300. return color;
  301. }
  302. ENDHLSL
  303. }
  304. // Shadows -----------------------------------------------------
  305. Pass
  306. {
  307. Name "ShadowCaster"
  308. Tags{"LightMode" = "ShadowCaster"}
  309. ZWrite On
  310. ZTest LEqual
  311. ColorMask 0
  312. Cull Off
  313. HLSLPROGRAM
  314. // Required to compile gles 2.0 with standard srp library
  315. #pragma prefer_hlslcc gles
  316. #pragma exclude_renderers d3d11_9x
  317. #pragma target 3.0
  318. // -------------------------------------
  319. // Material Keywords
  320. #pragma shader_feature_local _ALPHATEST_ON
  321. #pragma shader_feature_local _BENDINGMODE_ALPHA
  322. //--------------------------------------
  323. // GPU Instancing
  324. #pragma multi_compile_instancing
  325. #pragma multi_compile _ DOTS_INSTANCING_ON
  326. #pragma vertex ShadowPassVertex
  327. #pragma fragment ShadowPassFragment
  328. // Include base inputs and all other needed "base" includes
  329. #include "Includes/Lux URP Grass Inputs.hlsl"
  330. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
  331. // Shadow caster specific input
  332. float3 _LightDirection;
  333. VertexOutput ShadowPassVertex(VertexInput input)
  334. {
  335. VertexOutput output = (VertexOutput)0;
  336. UNITY_SETUP_INSTANCE_ID(input);
  337. UNITY_TRANSFER_INSTANCE_ID(input, output);
  338. // VSPro like vertex colors
  339. #if defined (_BENDINGMODE_ALPHA)
  340. #define bendAmount input.color.a
  341. #else
  342. #define bendAmount input.color.b
  343. #endif
  344. #define phase input.color.gg
  345. #define vocclusion input.color.r
  346. float3 worldInstancePos = UNITY_MATRIX_M._m03_m13_m23;
  347. // Shrink mesh if alpha testing is disabled
  348. #if !defined(_ALPHATEST_ON)
  349. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  350. float dist = dot(diff, diff);
  351. half fade = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  352. // Shrink mesh
  353. input.positionOS.xyz *= fade;
  354. #endif
  355. float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
  356. float3 cachedPositionWS = positionWS;
  357. // Wind in WorldSpace -------------------------------
  358. // Do the texture lookup as soon as possible
  359. half4 wind = SAMPLE_TEXTURE2D_LOD(_LuxLWRPWindRT, sampler_LuxLWRPWindRT, positionWS.xz * _LuxLWRPWindDirSize.w + phase * _WindMultiplier.z, _WindMultiplier.w);
  360. // Do as much as possible unrelated to the final position afterwards to hide latency
  361. // Calculate world space normal
  362. half3 normalWS = TransformObjectToWorldNormal(input.normalOS);
  363. // Set distance fade value
  364. #if defined(_ALPHATEST_ON)
  365. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  366. float dist = dot(diff, diff);
  367. output.fadeOcclusion.x = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  368. #endif
  369. // Do other stuff here
  370. #if defined(_ALPHATEST_ON)
  371. output.uv = input.texcoord;
  372. #endif
  373. half3 windDir = _LuxLWRPWindDirSize.xyz;
  374. half windStrength = bendAmount * _LuxLWRPWindStrengthMultipliers.x * _WindMultiplier.x;
  375. // From now on we rely on the texture sample being available
  376. wind.r = wind.r * (wind.g * 2.0h - 0.243h /* not a "real" normal as we want to keep the base direction */ );
  377. windStrength *= wind.r;
  378. positionWS.xz += windDir.xz * windStrength;
  379. // Displacement
  380. float2 samplePos = lerp(worldInstancePos.xz, cachedPositionWS.xz, _DisplacementSampleSize) - _Lux_DisplacementPosition.xy; // lower left corner
  381. samplePos = samplePos * _Lux_DisplacementPosition.z; // _Lux_DisplacementPosition.z = one OverSize
  382. if(samplePos.x >= 0.0f && samplePos.x <= 1.0f) {
  383. if(samplePos.y >= 0.0f && samplePos.y <= 1.0f) {
  384. half2 radialMask = (samplePos.xy * 2 - 1);
  385. half finalMask = 1 - dot(radialMask, radialMask);
  386. finalMask = smoothstep(0, 0.5, finalMask);
  387. if (finalMask > 0) {
  388. half4 displacementSample = SAMPLE_TEXTURE2D_LOD(_Lux_DisplacementRT, sampler_Lux_DisplacementRT, samplePos, 0);
  389. half3 bend = ( (displacementSample.rgb * 2 - 1)) * bendAmount;
  390. // Blue usually is close to 1 (speaking of a normal). So we use saturate to get only the negative part.
  391. bend.z = (saturate(displacementSample.b * 2) - 1) * bendAmount;
  392. bend *= finalMask;
  393. half3 disp;
  394. disp.xz = bend.xy * _DisplacementStrength;
  395. disp.y = -(abs(bend.x) + abs(bend.y) - bend.z) * _DisplacementStrengthVertical;
  396. positionWS = lerp(positionWS, cachedPositionWS + disp, saturate(dot(disp, disp)*16) );
  397. }
  398. }
  399. }
  400. // We have to recalculate ClipPos! / see: GetVertexPositionInputs in Core.hlsl
  401. // End Wind -------------------------------
  402. output.positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, _LightDirection));
  403. #if UNITY_REVERSED_Z
  404. output.positionCS.z = min(output.positionCS.z, output.positionCS.w * UNITY_NEAR_CLIP_VALUE);
  405. #else
  406. output.positionCS.z = max(output.positionCS.z, output.positionCS.w * UNITY_NEAR_CLIP_VALUE);
  407. #endif
  408. return output;
  409. }
  410. half4 ShadowPassFragment(VertexOutput input) : SV_TARGET
  411. {
  412. UNITY_SETUP_INSTANCE_ID(input);
  413. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  414. #if defined(_ALPHATEST_ON)
  415. Alpha(SampleAlbedoAlpha(input.uv.xy, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * input.fadeOcclusion.x, /*_BaseColor*/ half4(1,1,1,1), _Cutoff);
  416. #endif
  417. return 0;
  418. }
  419. ENDHLSL
  420. }
  421. // Depth -----------------------------------------------------
  422. Pass
  423. {
  424. Tags{"LightMode" = "DepthOnly"}
  425. ZWrite On
  426. ColorMask 0
  427. //AlphaToMask On
  428. Cull [_Cull]
  429. HLSLPROGRAM
  430. // Required to compile gles 2.0 with standard srp library
  431. #pragma prefer_hlslcc gles
  432. #pragma exclude_renderers d3d11_9x
  433. #pragma target 3.0
  434. #pragma vertex DepthOnlyVertex
  435. #pragma fragment DepthOnlyFragment
  436. // -------------------------------------
  437. // Material Keywords
  438. #pragma shader_feature_local _ALPHATEST_ON
  439. #pragma shader_feature_local _BENDINGMODE_ALPHA
  440. //--------------------------------------
  441. // GPU Instancing
  442. #pragma multi_compile_instancing
  443. #pragma multi_compile _ DOTS_INSTANCING_ON
  444. #define DEPTHONLYPASS
  445. #include "Includes/Lux URP Grass Inputs.hlsl"
  446. VertexOutput DepthOnlyVertex(VertexInput input)
  447. {
  448. VertexOutput output = (VertexOutput)0;
  449. UNITY_SETUP_INSTANCE_ID(input);
  450. UNITY_TRANSFER_INSTANCE_ID(input, output);
  451. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  452. // VSPro like vertex colors
  453. #define bendAmount input.color.b
  454. #define phase input.color.gg
  455. #define vocclusion input.color.r
  456. float3 worldInstancePos = UNITY_MATRIX_M._m03_m13_m23;
  457. // Shrink mesh if alpha testing is disabled
  458. #if !defined(_ALPHATEST_ON)
  459. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  460. float dist = dot(diff, diff);
  461. half fade = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  462. // Shrink mesh
  463. input.positionOS.xyz *= fade;
  464. #endif
  465. // Wind in WorldSpace -------------------------------
  466. VertexPositionInputs vertexInput;
  467. vertexInput.positionWS = TransformObjectToWorld(input.positionOS.xyz);
  468. float3 cachedPositionWS = vertexInput.positionWS;
  469. // Do the texture lookup as soon as possible
  470. half4 wind = SAMPLE_TEXTURE2D_LOD(_LuxLWRPWindRT, sampler_LuxLWRPWindRT, vertexInput.positionWS.xz * _LuxLWRPWindDirSize.w + phase * _WindMultiplier.z, _WindMultiplier.w);
  471. // Do as much as possible unrelated to the final position afterwards to hide latency
  472. // Calculate fade
  473. #if defined(_ALPHATEST_ON)
  474. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  475. float dist = dot(diff, diff);
  476. output.fadeOcclusion.x = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  477. #endif
  478. half windStrength = bendAmount * _LuxLWRPWindStrengthMultipliers.x * _WindMultiplier.x;
  479. half3 windDir = _LuxLWRPWindDirSize.xyz;
  480. #if defined(_ALPHATEST_ON)
  481. output.uv.xy = input.texcoord;
  482. #endif
  483. // From now on we rely on the texture sample being available
  484. wind.r = wind.r * (wind.g * 2.0h - 0.243h /* not a "real" normal as we want to keep the base direction */ );
  485. windStrength *= wind.r;
  486. vertexInput.positionWS.xz += windDir.xz * windStrength;
  487. // End Wind -------------------------------
  488. // Displacement
  489. float2 samplePos = lerp(worldInstancePos.xz, cachedPositionWS.xz, _DisplacementSampleSize) - _Lux_DisplacementPosition.xy; // lower left corner
  490. samplePos = samplePos * _Lux_DisplacementPosition.z; // _Lux_DisplacementPosition.z = one OverSize
  491. if(samplePos.x >= 0.0f && samplePos.x <= 1.0f) {
  492. if(samplePos.y >= 0.0f && samplePos.y <= 1.0f) {
  493. half2 radialMask = (samplePos.xy * 2 - 1);
  494. half finalMask = 1 - dot(radialMask, radialMask);
  495. finalMask = smoothstep(0, 0.5, finalMask);
  496. if (finalMask > 0) {
  497. half4 displacementSample = SAMPLE_TEXTURE2D_LOD(_Lux_DisplacementRT, sampler_Lux_DisplacementRT, samplePos, 0);
  498. half3 bend = ( (displacementSample.rgb * 2 - 1)) * bendAmount;
  499. // Blue usually is close to 1 (speaking of a normal). So we use saturate to get only the negative part.
  500. bend.z = (saturate(displacementSample.b * 2) - 1) * bendAmount;
  501. bend *= finalMask;
  502. half3 disp;
  503. disp.xz = bend.xy * _DisplacementStrength;
  504. disp.y = -(abs(bend.x) + abs(bend.y) - bend.z) * _DisplacementStrengthVertical;
  505. vertexInput.positionWS = lerp(vertexInput.positionWS, cachedPositionWS + disp, saturate(dot(disp, disp)*16) );
  506. }
  507. }
  508. }
  509. // We have to recalculate ClipPos!
  510. output.positionCS = TransformWorldToHClip(vertexInput.positionWS);
  511. return output;
  512. }
  513. half4 DepthOnlyFragment(VertexOutput input) : SV_TARGET
  514. {
  515. UNITY_SETUP_INSTANCE_ID(input);
  516. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  517. #if defined(_ALPHATEST_ON)
  518. Alpha(SampleAlbedoAlpha(input.uv.xy, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * input.fadeOcclusion.x, /*_BaseColor*/ half4(1,1,1,1), _Cutoff);
  519. #endif
  520. return 0;
  521. }
  522. ENDHLSL
  523. }
  524. // DepthNormal -----------------------------------------------------
  525. Pass
  526. {
  527. Name "DepthNormals"
  528. Tags{"LightMode" = "DepthNormals"}
  529. ZWrite On
  530. Cull [_Cull]
  531. HLSLPROGRAM
  532. // Required to compile gles 2.0 with standard srp library
  533. #pragma prefer_hlslcc gles
  534. #pragma exclude_renderers d3d11_9x
  535. #pragma target 3.0
  536. #pragma vertex DepthNormalsVertex
  537. #pragma fragment DepthNormalsFragment
  538. // -------------------------------------
  539. // Material Keywords
  540. #pragma shader_feature_local _ALPHATEST_ON
  541. #pragma shader_feature_local _BENDINGMODE_ALPHA
  542. //--------------------------------------
  543. // GPU Instancing
  544. #pragma multi_compile_instancing
  545. #pragma multi_compile _ DOTS_INSTANCING_ON
  546. #define DEPTHNORMALONLYPASS
  547. #include "Includes/Lux URP Grass Inputs.hlsl"
  548. VertexOutput DepthNormalsVertex(VertexInput input)
  549. {
  550. VertexOutput output = (VertexOutput)0;
  551. UNITY_SETUP_INSTANCE_ID(input);
  552. UNITY_TRANSFER_INSTANCE_ID(input, output);
  553. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  554. // VSPro like vertex colors
  555. #define bendAmount input.color.b
  556. #define phase input.color.gg
  557. #define vocclusion input.color.r
  558. float3 worldInstancePos = UNITY_MATRIX_M._m03_m13_m23;
  559. // Shrink mesh if alpha testing is disabled
  560. #if !defined(_ALPHATEST_ON)
  561. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  562. float dist = dot(diff, diff);
  563. half fade = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  564. // Shrink mesh
  565. input.positionOS.xyz *= fade;
  566. #endif
  567. // Wind in WorldSpace -------------------------------
  568. VertexPositionInputs vertexInput;
  569. vertexInput.positionWS = TransformObjectToWorld(input.positionOS.xyz);
  570. float3 cachedPositionWS = vertexInput.positionWS;
  571. // Do the texture lookup as soon as possible
  572. half4 wind = SAMPLE_TEXTURE2D_LOD(_LuxLWRPWindRT, sampler_LuxLWRPWindRT, vertexInput.positionWS.xz * _LuxLWRPWindDirSize.w + phase * _WindMultiplier.z, _WindMultiplier.w);
  573. // Do as much as possible unrelated to the final position afterwards to hide latency
  574. // Calculate fade
  575. #if defined(_ALPHATEST_ON)
  576. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  577. float dist = dot(diff, diff);
  578. output.fadeOcclusion.x = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  579. #endif
  580. VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);
  581. half windStrength = bendAmount * _LuxLWRPWindStrengthMultipliers.x * _WindMultiplier.x;
  582. half3 windDir = _LuxLWRPWindDirSize.xyz;
  583. half2 normalWindDir = windDir.xz * _WindMultiplier.y;
  584. #if defined(_ALPHATEST_ON)
  585. output.uv.xy = input.texcoord;
  586. #endif
  587. // From now on we rely on the texture sample being available
  588. wind.r = wind.r * (wind.g * 2.0h - 0.243h /* not a "real" normal as we want to keep the base direction */ );
  589. windStrength *= wind.r;
  590. vertexInput.positionWS.xz += windDir.xz * windStrength;
  591. // Do something to the normal as well
  592. normalInput.normalWS.xz += normalWindDir * windStrength;
  593. #ifdef _NORMALMAP
  594. normalInput.normalWS = NormalizeNormalPerVertex(normalInput.normalWS);
  595. #endif
  596. // End Wind -------------------------------
  597. // Displacement
  598. float2 samplePos = lerp(worldInstancePos.xz, cachedPositionWS.xz, _DisplacementSampleSize) - _Lux_DisplacementPosition.xy; // lower left corner
  599. samplePos = samplePos * _Lux_DisplacementPosition.z; // _Lux_DisplacementPosition.z = one OverSize
  600. if(samplePos.x >= 0.0f && samplePos.x <= 1.0f) {
  601. if(samplePos.y >= 0.0f && samplePos.y <= 1.0f) {
  602. half2 radialMask = (samplePos.xy * 2 - 1);
  603. half finalMask = 1 - dot(radialMask, radialMask);
  604. finalMask = smoothstep(0, 0.5, finalMask);
  605. if (finalMask > 0) {
  606. half4 displacementSample = SAMPLE_TEXTURE2D_LOD(_Lux_DisplacementRT, sampler_Lux_DisplacementRT, samplePos, 0);
  607. half3 bend = ( (displacementSample.rgb * 2 - 1)) * bendAmount;
  608. // Blue usually is close to 1 (speaking of a normal). So we use saturate to get only the negative part.
  609. bend.z = (saturate(displacementSample.b * 2) - 1) * bendAmount;
  610. bend *= finalMask;
  611. half3 disp;
  612. disp.xz = bend.xy * _DisplacementStrength;
  613. disp.y = -(abs(bend.x) + abs(bend.y) - bend.z) * _DisplacementStrengthVertical;
  614. vertexInput.positionWS = lerp(vertexInput.positionWS, cachedPositionWS + disp, saturate(dot(disp, disp)*16) );
  615. }
  616. }
  617. }
  618. // We have to recalculate ClipPos!
  619. output.positionCS = TransformWorldToHClip(vertexInput.positionWS);
  620. // Output normalWS as well here
  621. output.normalWS = normalInput.normalWS;
  622. return output;
  623. }
  624. half4 DepthNormalsFragment(VertexOutput input) : SV_TARGET
  625. {
  626. UNITY_SETUP_INSTANCE_ID(input);
  627. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  628. #if defined(_ALPHATEST_ON)
  629. Alpha(SampleAlbedoAlpha(input.uv.xy, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * input.fadeOcclusion.x, /*_BaseColor*/ half4(1,1,1,1), _Cutoff);
  630. #endif
  631. return float4(PackNormalOctRectEncode(TransformWorldToViewDir(input.normalWS, true)), 0.0, 0.0);
  632. }
  633. ENDHLSL
  634. }
  635. // Meta -----------------------------------------------------
  636. Pass
  637. {
  638. Tags{"LightMode" = "Meta"}
  639. Cull Off
  640. HLSLPROGRAM
  641. // Required to compile gles 2.0 with standard srp library
  642. #pragma prefer_hlslcc gles
  643. #pragma vertex LightweightVertexMeta
  644. #pragma fragment LightweightFragmentMeta
  645. #define _SPECULAR_SETUP 1
  646. #pragma shader_feature_local _ALPHATEST_ON
  647. // 1
  648. // First include all our custom stuff
  649. #include "Includes/Lux URP Grass Inputs.hlsl"
  650. //--------------------------------------
  651. // Fragment shader and functions - usually defined in LitInput.hlsl
  652. inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)
  653. {
  654. half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));
  655. outSurfaceData.alpha = Alpha(albedoAlpha.a, half4(1.0h, 1.0h, 1.0h, 1.0h), _Cutoff);
  656. outSurfaceData.albedo = albedoAlpha.rgb;
  657. outSurfaceData.metallic = 1.0h; // crazy?
  658. outSurfaceData.specular = _SpecColor.rgb;
  659. outSurfaceData.smoothness = _Smoothness;
  660. outSurfaceData.normalTS = half3(0,0,1);
  661. outSurfaceData.occlusion = 1;
  662. outSurfaceData.emission = 0.5h;
  663. outSurfaceData.clearCoatMask = 0;
  664. outSurfaceData.clearCoatSmoothness = 0;
  665. }
  666. // Finally include the meta pass related stuff
  667. #include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
  668. ENDHLSL
  669. }
  670. // End Passes -----------------------------------------------------
  671. }
  672. FallBack "Hidden/InternalErrorShader"
  673. CustomEditor "LuxURPCustomSingleSidedShaderGUI"
  674. }