Lux URP Unlit Decal.shader 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. Shader "Lux URP/Projection/Decal Unlit"
  2. {
  3. Properties
  4. {
  5. [HeaderHelpLuxURP_URL(skzrp97i0tvt)]
  6. [Header(Surface Options)]
  7. [Space(8)]
  8. [Toggle(ORTHO_SUPPORT)]
  9. _OrthoSpport ("Enable Orthographic Support", Float) = 0
  10. [Toggle(HQ_SAMPLING)]
  11. _HQSampling ("Enable HQ Sampling", Float) = 0
  12. [Header(Surface Inputs)]
  13. [Space(8)]
  14. [HDR] _Color ("Color", Color) = (1,1,1,1)
  15. [NoScaleOffset] _BaseMap ("Albedo (RGB) Alpha (A)", 2D) = "white" {}
  16. [Header(Distance Fading)]
  17. [Space(8)]
  18. [LuxURPDistanceFadeDrawer]
  19. _DistanceFade ("Distance Fade Params", Vector) = (2500, 0.001, 0, 0)
  20. [Header(Stencil)]
  21. [Space(8)]
  22. [IntRange] _StencilRef ("Stencil Reference", Range (0, 255)) = 0
  23. [IntRange] _ReadMask (" Read Mask", Range (0, 255)) = 255
  24. [IntRange] _WriteMask (" Write Mask", Range (0, 255)) = 255
  25. [Enum(UnityEngine.Rendering.CompareFunction)]
  26. _StencilCompare ("Stencil Comparison", Int) = 6
  27. [Header(Advanced)]
  28. [Space(8)]
  29. [Toggle(_APPLYFOG)] _ApplyFog("Enable Fog", Float) = 0.0
  30. }
  31. SubShader
  32. {
  33. Tags
  34. {
  35. "RenderPipeline" = "UniversalPipeline"
  36. "RenderType" = "Opaque"
  37. "Queue" = "Transparent" // +59 smalltest to get drawn on top of transparents
  38. }
  39. Pass
  40. {
  41. Name "Unlit"
  42. //Tags{"LightMode" = "UniversalForward"}
  43. Stencil {
  44. Ref [_StencilRef]
  45. ReadMask [_ReadMask]
  46. WriteMask [_WriteMask]
  47. Comp [_StencilCompare]
  48. }
  49. Blend SrcAlpha OneMinusSrcAlpha
  50. // We draw backfaces to prevent clipping
  51. Cull Front
  52. // So we have to set ZTest to always
  53. ZTest Always
  54. // It is a decal!
  55. ZWrite Off
  56. HLSLPROGRAM
  57. // Required to compile gles 2.0 with standard srp library
  58. #pragma prefer_hlslcc gles
  59. #pragma exclude_renderers d3d11_9x
  60. #pragma target 2.0
  61. #pragma shader_feature_local ORTHO_SUPPORT
  62. #pragma shader_feature_local _APPLYFOG
  63. // -------------------------------------
  64. // Material Keywords
  65. #pragma shader_feature_local_fragment HQ_SAMPLING
  66. // -------------------------------------
  67. // Universal Pipeline keywords
  68. // -------------------------------------
  69. // Unity defined keywords
  70. #pragma multi_compile_fog
  71. //--------------------------------------
  72. // GPU Instancing
  73. #pragma multi_compile_instancing
  74. // #pragma multi_compile _ DOTS_INSTANCING_ON // needs shader target 4.5
  75. #pragma vertex vert
  76. #pragma fragment frag
  77. // Lighting include is needed because of GI
  78. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  79. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  80. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  81. #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
  82. CBUFFER_START(UnityPerMaterial)
  83. half4 _Color;
  84. float2 _DistanceFade;
  85. float4 _BaseMap_TexelSize; // what the fuck?! SRP batcher
  86. CBUFFER_END
  87. #if defined(SHADER_API_GLES)
  88. TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
  89. #else
  90. TEXTURE2D_X_FLOAT(_CameraDepthTexture);
  91. #endif
  92. float4 _CameraDepthTexture_TexelSize;
  93. //TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
  94. //float4 _BaseMap_TexelSize;
  95. struct VertexInput
  96. {
  97. float4 vertex : POSITION;
  98. float3 normal : NORMAL;
  99. UNITY_VERTEX_INPUT_INSTANCE_ID
  100. };
  101. struct VertexOutput
  102. {
  103. float4 positionCS : SV_POSITION;
  104. UNITY_VERTEX_INPUT_INSTANCE_ID
  105. UNITY_VERTEX_OUTPUT_STEREO
  106. float4 viewRayOS : TEXCOORD0;
  107. float3 camPosOS : TEXCOORD1;
  108. float4 screenUV : TEXCOORD2;
  109. #if defined(_APPLYFOG)
  110. float fogCoord : TEXCOORD3;
  111. #endif
  112. half fade : TEXCOORD4;
  113. };
  114. VertexOutput vert (VertexInput v)
  115. {
  116. VertexOutput output = (VertexOutput)0;
  117. UNITY_SETUP_INSTANCE_ID(v);
  118. UNITY_TRANSFER_INSTANCE_ID(v, output);
  119. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
  120. output.positionCS = TransformObjectToHClip(v.vertex.xyz);
  121. // We do all calculations in Object Space
  122. float4 positionVS = mul(UNITY_MATRIX_V, mul(UNITY_MATRIX_M, v.vertex)); //mul(UNITY_MATRIX_MV, v.vertex);
  123. float3 viewRayVS = positionVS.xyz;
  124. // positionVS.z here acts as view space to object space ratio (negative)
  125. output.viewRayOS.w = positionVS.z;
  126. // NOTE: Fix direction of the viewRay
  127. float4x4 ViewToObjectMatrix = mul(GetWorldToObjectMatrix(), UNITY_MATRIX_I_V);
  128. output.viewRayOS.xyz = mul((float3x3)ViewToObjectMatrix, -viewRayVS).xyz;
  129. output.camPosOS = ViewToObjectMatrix._m03_m13_m23;
  130. // Get the screen uvs needed to sample the depth texture
  131. output.screenUV = ComputeScreenPos(output.positionCS);
  132. #if defined(_APPLYFOG)
  133. output.fogCoord = ComputeFogFactor(output.positionCS.z);
  134. #endif
  135. // Set distance fade value
  136. float3 worldInstancePos = UNITY_MATRIX_M._m03_m13_m23;
  137. float3 diff = (_WorldSpaceCameraPos - worldInstancePos);
  138. float dist = dot(diff, diff);
  139. output.fade = saturate( (_DistanceFade.x - dist) * _DistanceFade.y );
  140. return output;
  141. }
  142. // HQ decal sampling from: http://www.humus.name/index.php?page=3D&ID=84
  143. // Decal MipmapLevel to avoid the 2x2 pixels artefacts on the edges where the decal is projected to.
  144. float2 ComputeDecalDDX(VertexOutput input, float2 uv, float2 decalUV) {
  145. float2 ScreenDeltaX = float2(1, 0);
  146. float depth0 = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * uv - ScreenDeltaX).x;
  147. depth0 = LinearEyeDepth(depth0, _ZBufferParams);
  148. float depth1 = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * uv + ScreenDeltaX).x;
  149. depth1 = LinearEyeDepth(depth1, _ZBufferParams);
  150. float2 UvDiffX0 = decalUV - ((input.camPosOS + input.viewRayOS.xyz * depth0).xz + float2(0.5, 0.5));
  151. float2 UvDiffX1 = ((input.camPosOS + input.viewRayOS.xyz * depth1).xz + float2(0.5, 0.5)) - decalUV;
  152. return dot(UvDiffX0, UvDiffX0) < dot(UvDiffX1, UvDiffX1) ? UvDiffX0 : UvDiffX1;
  153. }
  154. float2 ComputeDecalDDY(VertexOutput input, float2 uv, float2 decalUV) {
  155. float2 ScreenDeltaY = float2(0, 1);
  156. float depth0 = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * uv - ScreenDeltaY).x;
  157. depth0 = LinearEyeDepth(depth0, _ZBufferParams);
  158. float depth1 = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * uv + ScreenDeltaY).x;
  159. depth1 = LinearEyeDepth(depth1, _ZBufferParams);
  160. float2 UvDiffY0 = decalUV - ((input.camPosOS + input.viewRayOS.xyz * depth0).xz + float2(0.5, 0.5));
  161. float2 UvDiffY1 = ((input.camPosOS + input.viewRayOS.xyz * depth1).xz + float2(0.5, 0.5)) - decalUV;
  162. return dot(UvDiffY0, UvDiffY0) < dot(UvDiffY1, UvDiffY1) ? UvDiffY0 : UvDiffY1;
  163. }
  164. // HQ decal sampling END
  165. half4 frag (VertexOutput input ) : SV_Target
  166. {
  167. UNITY_SETUP_INSTANCE_ID(input);
  168. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  169. input.viewRayOS.xyz *= rcp(input.viewRayOS.w); // precision problem? calculating 1.0 / w in vertex shader.
  170. float2 uv = input.screenUV.xy / input.screenUV.w;
  171. // Fix screenUV for Single Pass Stereo Rendering
  172. #if defined(UNITY_SINGLE_PASS_STEREO)
  173. uv.x = uv.x * 0.5f + (float)unity_StereoEyeIndex * 0.5f;
  174. #endif
  175. #if defined(SHADER_API_GLES)
  176. float rawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, uv, 0);
  177. #else
  178. float rawDepth = LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * uv).x;
  179. #endif
  180. float3 positionOS;
  181. // Get Position in Object Space
  182. #if defined(ORTHO_SUPPORT)
  183. UNITY_BRANCH
  184. if(unity_OrthoParams.w == 1) {
  185. float depthOrtho = rawDepth;
  186. #if defined(UNITY_REVERSED_Z)
  187. // Needed to handle openGL
  188. #if UNITY_REVERSED_Z == 1
  189. depthOrtho = 1.0f - depthOrtho;
  190. #endif
  191. #endif
  192. // Get ortho Depth
  193. // Old code, works with HDRP10.1 again... crazy
  194. depthOrtho = lerp(_ProjectionParams.y, _ProjectionParams.z, depthOrtho);
  195. float2 rayOrtho = -float2( unity_OrthoParams.xy * ( input.screenUV.xy - 0.5) * 2 /* to clip space */);
  196. float4 vposOrtho = float4(rayOrtho, -depthOrtho, 1);
  197. float3 wposOrtho = mul(unity_CameraToWorld, vposOrtho).xyz;
  198. wposOrtho -= _WorldSpaceCameraPos * 2; // TODO: Why * 2 ????
  199. wposOrtho *= -1;
  200. float3 positionOrthoOS = mul( GetWorldToObjectMatrix(), float4(wposOrtho, 1)).xyz;
  201. // depthOrtho = lerp(_ProjectionParams.y, _ProjectionParams.z, depthOrtho);
  202. // float2 rayOrtho = float2( unity_OrthoParams.xy * ( input.screenUV.xy - 0.5) * 2 /* to clip space */);
  203. // float4 vposOrtho = float4(rayOrtho, -depthOrtho, 1);
  204. // float3 wposOrtho = mul(unity_CameraToWorld, vposOrtho).xyz;
  205. // float3 positionOrthoOS = mul( GetWorldToObjectMatrix(), float4(wposOrtho, 1)).xyz;
  206. positionOS = positionOrthoOS;
  207. }
  208. else {
  209. // Get perspective Depth
  210. float depth = LinearEyeDepth(rawDepth, _ZBufferParams);
  211. // Position in Object Space
  212. positionOS = input.camPosOS + input.viewRayOS.xyz * depth;
  213. }
  214. #else
  215. // Get perspective Depth
  216. float depth = LinearEyeDepth(rawDepth, _ZBufferParams);
  217. // Position in Object Space
  218. positionOS = input.camPosOS + input.viewRayOS.xyz * depth;
  219. #endif
  220. // Clip decal to volume
  221. clip(float3(0.5, 0.5, 0.5) - abs(positionOS.xyz));
  222. float2 texUV = positionOS.xz + float2(0.5, 0.5);
  223. // HQ Decal Sampling
  224. #if defined(HQ_SAMPLING) && !defined(ORTHO_SUPPORT)
  225. float2 UvPixelDiffX = ComputeDecalDDX(input, uv, texUV) * _BaseMap_TexelSize.zw;
  226. float2 UvPixelDiffY = ComputeDecalDDY(input, uv, texUV) * _BaseMap_TexelSize.zw;
  227. float MaxDiff = max(dot(UvPixelDiffX, UvPixelDiffX), dot(UvPixelDiffY, UvPixelDiffY));
  228. float Mip = 0.5 * log2(MaxDiff);
  229. half4 col = SAMPLE_TEXTURE2D_LOD(_BaseMap, sampler_BaseMap, texUV, Mip) * _Color;
  230. #else
  231. half4 col = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, texUV) * _Color;
  232. #endif
  233. // Distance Fade
  234. #if defined(ORTHO_SUPPORT)
  235. col.a *= ((unity_OrthoParams.w == 1.0h) ? 1.0h : input.fade);
  236. #else
  237. col.a *= input.fade;
  238. #endif
  239. #if defined(_APPLYFOG)
  240. col.rgb = MixFog(col.rgb, input.fogCoord);
  241. #endif
  242. return half4(col);
  243. }
  244. ENDHLSL
  245. }
  246. }
  247. FallBack "Hidden/InternalErrorShader"
  248. CustomEditor "LuxURPUniversalCustomShaderGUI"
  249. }