Lux URP FX LightBeam.shader 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // https://api.unrealengine.com/udk/Three/VolumetricLightbeamTutorial.html
  2. // https://www.gamedev.net/forums/topic/692224-udk-volumetric-light-beam/
  3. Shader "Lux URP/FX/Lightbeam"
  4. {
  5. Properties
  6. {
  7. [HeaderHelpLuxURP_URL(m12h3vad3enc)]
  8. [Header(Surface Options)]
  9. [Space(8)]
  10. [Enum(UnityEngine.Rendering.CompareFunction)]
  11. _ZTest ("ZTest", Int) = 4
  12. [Enum(UnityEngine.Rendering.CullMode)]
  13. _Cull ("Culling", Float) = 2
  14. [Toggle(ORTHO_SUPPORT)]
  15. _OrthoSpport ("Enable Orthographic Support", Float) = 0
  16. [Header(Surface Inputs)]
  17. [Space(8)]
  18. [HDR] _Color ("Color", Color) = (1,1,1,1)
  19. [NoScaleOffset] _MainTex ("Fall Off (G)", 2D) = "white" {}
  20. [NoScaleOffset] _SpotTex ("Spot Mask (G)", 2D) = "white" {}
  21. _ConeWidth ("Cone Width", Range(1.0, 10.0)) = 8.0 // 8.0 from UDK
  22. _SpotFade ("Spot Mask Intensity", Range(0.51, 1.0)) = 0.6 // 0.6 from UDK
  23. [Header(Detail Noise)]
  24. [Space(8)]
  25. [Toggle(_MASKMAP)]
  26. _SpecGlossEnabled ("Enable detail noise", Float) = 0
  27. _DetailTex (" Detail Noise (G)", 2D) = "white" {}
  28. _DetailStrength (" Strength", Range(0.0, 1.0)) = 1.0
  29. _DetailScrollSpeed (" Scroll Speed 1:(XY) 2:(ZW)", Vector) = (0,0,0,0)
  30. [Header(Scene Fade)]
  31. [Space(8)]
  32. _near (" Near", Float) = 0.0
  33. _far (" Soft Edge Factor", Float) = 2.0
  34. [Header(Camera Fade)]
  35. [Space(8)]
  36. [LuxURPCameraFadeDrawer]
  37. _CameraFadeDistances ("Camera Fade Distances", Vector) = (0.3,1,0.3,1) // !!! x + y are used, z + w are displayed
  38. [Space(5)]
  39. _LimitLength ("Limit Length", Float) = 50.0
  40. }
  41. SubShader
  42. {
  43. Tags
  44. {
  45. "RenderPipeline" = "UniversalPipeline"
  46. "RenderType"="Opaque"
  47. "Queue"= "Transparent+50" // Make it fit built in transparent shaders' queue
  48. }
  49. Pass
  50. {
  51. Name "StandardUnlit"
  52. Tags{"LightMode" = "UniversalForward"}
  53. Blend SrcAlpha OneMinusSrcAlpha
  54. ColorMask RGB
  55. Cull [_Cull]
  56. ZTest [_ZTest]
  57. ZWrite Off
  58. HLSLPROGRAM
  59. // Required to compile gles 2.0 with standard srp library
  60. #pragma prefer_hlslcc gles
  61. #pragma exclude_renderers d3d11_9x
  62. #pragma target 2.0
  63. #pragma shader_feature_local _MASKMAP
  64. #pragma shader_feature_local ORTHO_SUPPORT
  65. // -------------------------------------
  66. // Lightweight Pipeline keywords
  67. // -------------------------------------
  68. // Unity defined keywords
  69. #pragma multi_compile_fog
  70. //--------------------------------------
  71. // GPU Instancing
  72. #pragma multi_compile_instancing
  73. #pragma vertex vert
  74. #pragma fragment frag
  75. // Lighting include is needed because of GI
  76. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  77. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  78. #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl"
  79. CBUFFER_START(UnityPerMaterial)
  80. half4 _Color;
  81. half _SpotFade;
  82. half _ConeWidth;
  83. float _near;
  84. float _far;
  85. float2 _CameraFadeDistances;
  86. float _LimitLength;
  87. //#if defined(_MASKMAP)
  88. half _DetailStrength;
  89. float4 _DetailScrollSpeed;
  90. float4 _DetailTex_ST;
  91. //#endif
  92. CBUFFER_END
  93. // Stereo-related bits - backported to LWRP
  94. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED)
  95. #define LUX_SLICE_ARRAY_INDEX unity_StereoEyeIndex
  96. #define LUX_TEXTURE2D_X TEXTURE2D_ARRAY
  97. #define LUX_TEXTURE2D_X_FLOAT TEXTURE2D_ARRAY_FLOAT
  98. #define LUX_LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, LUX_SLICE_ARRAY_INDEX)
  99. #define LUX_SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, LUX_SLICE_ARRAY_INDEX)
  100. #else
  101. #define LUX_SLICE_ARRAY_INDEX 0
  102. #define LUX_TEXTURE2D_X TEXTURE2D
  103. #define LUX_TEXTURE2D_X_FLOAT TEXTURE2D_FLOAT
  104. #define LUX_LOAD_TEXTURE2D_X LOAD_TEXTURE2D
  105. #define LUX_SAMPLE_TEXTURE2D_X SAMPLE_TEXTURE2D
  106. #endif
  107. TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
  108. TEXTURE2D(_SpotTex); SAMPLER(sampler_SpotTex);
  109. #if defined(SHADER_API_GLES)
  110. TEXTURE2D(_CameraDepthTexture); SAMPLER(sampler_CameraDepthTexture);
  111. #else
  112. LUX_TEXTURE2D_X_FLOAT(_CameraDepthTexture);
  113. #endif
  114. float4 _CameraDepthTexture_TexelSize;
  115. #if defined(_MASKMAP)
  116. TEXTURE2D(_DetailTex); SAMPLER(sampler_DetailTex);
  117. #endif
  118. struct VertexInput
  119. {
  120. float4 vertex : POSITION;
  121. float3 normal : NORMAL;
  122. float4 tangent : TANGENT;
  123. float2 texcoord : TEXCOORD0;
  124. UNITY_VERTEX_INPUT_INSTANCE_ID
  125. };
  126. struct VertexOutput
  127. {
  128. float4 positionCS : SV_POSITION;
  129. float fogCoord : TEXCOORD0;
  130. float4 uv : TEXCOORD1;
  131. float2 projectedPosition : TEXCOORD2;
  132. float distFade : TEXCOORD3;
  133. #if defined(_MASKMAP)
  134. float4 detail_texcoord : TEXCOORD4;
  135. #endif
  136. UNITY_VERTEX_INPUT_INSTANCE_ID
  137. UNITY_VERTEX_OUTPUT_STEREO
  138. };
  139. VertexOutput vert (VertexInput input)
  140. {
  141. VertexOutput o = (VertexOutput)0;
  142. UNITY_SETUP_INSTANCE_ID(input);
  143. UNITY_TRANSFER_INSTANCE_ID(input, o);
  144. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  145. VertexPositionInputs vertexInput = GetVertexPositionInputs(input.vertex.xyz);
  146. o.positionCS = vertexInput.positionCS;
  147. o.fogCoord = ComputeFogFactor(o.positionCS.z);
  148. #if defined(_MASKMAP)
  149. o.detail_texcoord.xy = TRANSFORM_TEX(input.texcoord, _DetailTex);
  150. o.detail_texcoord.zw = o.detail_texcoord.xy * 2;
  151. _DetailScrollSpeed *= _Time.x;
  152. o.detail_texcoord.xy += _DetailScrollSpeed.xy;
  153. o.detail_texcoord.zw += _DetailScrollSpeed.zw;
  154. #endif
  155. o.uv.y = input.texcoord.y;
  156. // Calculate Tangent Space viewDir
  157. // ObjSpaceViewDir
  158. float3 objSpaceCameraPos = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos.xyz, 1)).xyz;
  159. float3 ObjSpaceViewDir = objSpaceCameraPos - input.vertex.xyz;
  160. // TANGENT_SPACE_ROTATION
  161. float3 binormal = cross( normalize(input.normal), normalize(input.tangent.xyz) ) * input.tangent.w;
  162. float3x3 tangentSpaceRotation = float3x3(input.tangent.xyz, binormal, input.normal );
  163. // Reflect Vector
  164. float3 rVec = mul(tangentSpaceRotation, normalize(ObjSpaceViewDir));
  165. // Needed by back faces
  166. rVec.z = abs(rVec.z);
  167. rVec.z = sqrt( (rVec.z + _SpotFade) * _ConeWidth);
  168. rVec.x = rVec.x / rVec.z + 0.5f;
  169. rVec.y = rVec.y / rVec.z + 0.5f;
  170. o.uv.x = rVec.x;
  171. o.uv.zw = rVec.xy;
  172. o.projectedPosition = vertexInput.positionNDC.xy;
  173. o.distFade = saturate(_LimitLength - length(input.vertex.xyz));
  174. return o;
  175. }
  176. // ------------------------------------------------------------------
  177. // Helper functions to handle orthographic / perspective projection
  178. inline float GetOrthoDepthFromZBuffer (float rawDepth) {
  179. #if defined(UNITY_REVERSED_Z)
  180. // Needed to handle openGL
  181. #if UNITY_REVERSED_Z == 1
  182. rawDepth = 1.0f - rawDepth;
  183. #endif
  184. #endif
  185. return lerp(_ProjectionParams.y, _ProjectionParams.z, rawDepth);
  186. }
  187. inline float GetProperEyeDepth (float rawDepth) {
  188. #if defined(ORTHO_SUPPORT)
  189. float perspectiveSceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
  190. float orthoSceneDepth = GetOrthoDepthFromZBuffer(rawDepth);
  191. return lerp(perspectiveSceneDepth, orthoSceneDepth, unity_OrthoParams.w);
  192. #else
  193. return LinearEyeDepth(rawDepth, _ZBufferParams);
  194. #endif
  195. }
  196. half4 frag (VertexOutput input ) : SV_Target
  197. {
  198. UNITY_SETUP_INSTANCE_ID(input);
  199. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  200. half4 col = _Color;
  201. half mask01 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv.xy).g;
  202. half mask02 = SAMPLE_TEXTURE2D(_SpotTex, sampler_SpotTex, input.uv.zw).g;
  203. #if defined(_MASKMAP)
  204. half detailTex = SAMPLE_TEXTURE2D(_DetailTex, sampler_DetailTex, input.detail_texcoord.xy).g;
  205. detailTex *= SAMPLE_TEXTURE2D(_DetailTex, sampler_DetailTex, input.detail_texcoord.zw).g;
  206. col *= lerp(1, detailTex, _DetailStrength);
  207. #endif
  208. #if defined(ORTHO_SUPPORT)
  209. input.positionCS.w = lerp(input.positionCS.w, 1.0f, unity_OrthoParams.w);
  210. float thisZ = GetProperEyeDepth(input.positionCS.z);
  211. #else
  212. float thisZ = input.positionCS.w;
  213. #endif
  214. float2 screenUV = (input.projectedPosition.xy / input.positionCS.w);
  215. // Fix screenUV for Single Pass Stereo Rendering
  216. #if defined(UNITY_SINGLE_PASS_STEREO)
  217. screenUV.x = screenUV.x * 0.5f + (float)unity_StereoEyeIndex * 0.5f;
  218. #endif
  219. // Get scene depth
  220. #if defined(SHADER_API_GLES)
  221. float sceneZ = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV, 0);
  222. #else
  223. float sceneZ = LUX_LOAD_TEXTURE2D_X(_CameraDepthTexture, _CameraDepthTexture_TexelSize.zw * screenUV).x;
  224. #endif
  225. sceneZ = GetProperEyeDepth(sceneZ);
  226. // Surface fade
  227. float fade = saturate (_far * ((sceneZ - _near) - thisZ));
  228. // Camera fade
  229. fade *= saturate( (thisZ - _CameraFadeDistances.x) * _CameraFadeDistances.y);
  230. // Combine
  231. col.a *= mask01 * mask02 * fade * input.distFade;
  232. col.rgb = MixFog(_Color.rgb, input.fogCoord);
  233. return half4(col);
  234. }
  235. ENDHLSL
  236. }
  237. }
  238. FallBack "Hidden/InternalErrorShader"
  239. }