ParallaxCloud.shader 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. Shader "Custom/ParallaxCloud"
  2. {
  3. Properties
  4. {
  5. _MainTex ("BaseMap:基础贴图", 2D) = "white" {}
  6. _Color ("Color:颜色", Color) = (0.0, 0.0, 0.0, 1.0)
  7. _ParallaxSize ("ParallaxSize:视差映射强度", Range(0.0, 0.1)) = 0.0
  8. _ParallaxLayers ("ParallaxLayers:视差映射层数", Range(1.0, 50.0)) = 20
  9. _MoveSpeed ("MoveSpeed:移动速度", Range(-0.5, 0.5)) = 0.1
  10. _Alpha ("Alpha:透明度", Range(0, 1)) = 0.5
  11. _AlphaExtent ("AlphaExtent:透明对比度", Range(0.0, 5.0)) = 5.0
  12. }
  13. SubShader
  14. {
  15. Tags
  16. {
  17. "RenderPipeline"="UniversalPipeline"
  18. "Queue"="Transparent"
  19. "RenderType"="Transparent"
  20. }
  21. Pass
  22. {
  23. Blend SrcAlpha OneMinusSrcAlpha
  24. Cull off
  25. ZWrite off
  26. HLSLPROGRAM
  27. #pragma vertex vert
  28. #pragma fragment frag
  29. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
  30. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
  31. struct Attributes
  32. {
  33. float4 positionOS : POSITION;
  34. float3 normalOS : NORMAL;
  35. float2 uv : TEXCOORD0;
  36. float4 tangent : TANGENT;
  37. };
  38. struct Varyings
  39. {
  40. float4 positionCS : SV_POSITION;
  41. float3 positionWS : TEXCOORD0;
  42. float4 uv : TEXCOORD1;
  43. float3 nDirWS : TEXCOORD2;
  44. float3 tDirWS : TEXCOORD3;
  45. float3 bDirWS : TEXCOORD4;
  46. float4 screenPos : TEXCOORD5;
  47. };
  48. CBUFFER_START(UnityPerMaterial)
  49. half4 _MainTex_ST;
  50. half4 _Color;
  51. half _ParallaxSize;
  52. half _ParallaxLayers;
  53. half _MoveSpeed;
  54. half _Alpha;
  55. half _AlphaExtent;
  56. CBUFFER_END
  57. TEXTURE2D(_MainTex);
  58. SAMPLER(sampler_MainTex);
  59. TEXTURE2D(_NormalTex);
  60. SAMPLER(sampler_NormalTex);
  61. TEXTURE2D(_ParallaxTex);
  62. SAMPLER(sampler_ParallaxTex);
  63. sampler2D _CameraDepthTexture;
  64. Varyings vert(Attributes v)
  65. {
  66. Varyings o;
  67. o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
  68. o.positionWS = TransformObjectToWorld(v.positionOS.xyz);
  69. o.nDirWS = TransformObjectToWorldNormal(v.normalOS);
  70. o.tDirWS = normalize(TransformObjectToWorld(v.tangent.xyz));
  71. o.bDirWS = normalize(cross(o.nDirWS, o.tDirWS) * v.tangent.w);
  72. // o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex) + float2(frac(_Time.y * _MoveSpeed), 0.0);
  73. o.uv.xy= o.positionWS.xz*0.06+ float2(frac(_Time.y * _MoveSpeed), 0.0);
  74. o.uv.zw = v.uv;
  75. o.screenPos = ComputeScreenPos(o.positionCS);
  76. return o;
  77. }
  78. // 从深度值重建世界坐标
  79. float3 ReconstructWorldPosition(float2 uv, float depth)
  80. {
  81. // 1. 将 UV 转换为 NDC 空间 (Normalized Device Coordinates)
  82. float4 ndc = float4(uv * 2.0 - 1.0, depth, 1.0);
  83. // 2. 从 NDC 转换到裁剪空间
  84. float4 clipPos = ndc;
  85. clipPos.z = depth * 2.0 - 1.0; // 将深度从 [0,1] 转换为 [-1,1]
  86. // 3. 应用逆投影矩阵,转换到视图空间
  87. float4 viewPos = mul(unity_CameraInvProjection, clipPos); // 使用 Unity 内置的逆投影矩阵
  88. viewPos /= viewPos.w; // 透视除法
  89. // 4. 应用逆视图矩阵,转换到世界空间
  90. float4 worldPos = mul(UNITY_MATRIX_I_V, viewPos); // 使用 Unity 内置的逆视图矩阵
  91. return worldPos.xyz;
  92. }
  93. half4 frag(Varyings i) : SV_Target
  94. {
  95. float2 positionSS = i.positionCS.xy * (_ScreenParams.zw - 1);
  96. float depth = tex2D(_CameraDepthTexture, positionSS).r;
  97. float3 positionNDC = float3(positionSS * 2 - 1, depth);
  98. #if UNITY_UV_STARTS_AT_TOP
  99. positionNDC.y = -positionNDC.y;
  100. #endif
  101. #if REQUIRE_POSITION_VS
  102. float4 positionVS = mul(UNITY_MATRIX_I_P, float4(positionNDC, 1));
  103. positionVS /= positionVS.w;
  104. float4 positionWS = mul(UNITY_MATRIX_I_V, positionVS);
  105. #else
  106. float4 positionWS = mul(UNITY_MATRIX_I_VP, float4(positionNDC, 1));
  107. positionWS /= positionWS.w;
  108. #endif
  109. float dist = length(positionWS - i.positionWS);
  110. // return half4(dist * 0.1, 0, 0, 1.0);
  111. dist = dist * 0.2;
  112. dist = clamp(dist, 0, 1);
  113. float ptcpos=length(i.positionWS-_WorldSpaceCameraPos);
  114. ptcpos= 1-(ptcpos-100)/50;
  115. ptcpos=clamp(ptcpos,0,1);
  116. //Light mylight = GetMainLight();
  117. //half3 light = mylight.color;
  118. float3x3 TBN = float3x3(i.tDirWS, i.bDirWS, i.nDirWS);
  119. float3 vDir = normalize(i.positionWS - _WorldSpaceCameraPos.xyz);
  120. float3 vDirTS = mul(TBN, vDir);
  121. float3 var_MainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.zw).rgb;
  122. half2 offset = 0.0;
  123. half currentDepth = 0.0;
  124. half parallaxDepth = 0.0;
  125. half preParallaxDepth = 0.0;
  126. half heightStep = 1.0 / _ParallaxLayers;
  127. half2 offsetTemp = vDirTS.xy / -vDirTS.z * _ParallaxSize;
  128. for (int j = 0; j < _ParallaxLayers; j++)
  129. {
  130. parallaxDepth = 1.0 - SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, i.uv.xy + offset, 0).r *
  131. var_MainTex.r;
  132. if (currentDepth > parallaxDepth) break;
  133. preParallaxDepth = parallaxDepth;
  134. currentDepth += heightStep;
  135. offset = offsetTemp * currentDepth;
  136. }
  137. half preDepth = currentDepth - heightStep;
  138. half A_C = preDepth - preParallaxDepth;
  139. half D_B = parallaxDepth - currentDepth;
  140. half t = A_C / (D_B + A_C);
  141. half height = lerp(preDepth, currentDepth, t);
  142. offset += offsetTemp * height;
  143. i.uv.xy += offset;
  144. half3 finalColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.xy).rgb * var_MainTex.rgb;
  145. float alphaTex = max(var_MainTex.r * finalColor.r, 0.0);
  146. half alpha = max(pow(abs(lerp(alphaTex, 1.0, _Alpha)), _AlphaExtent), 0.0) * _Alpha * dist*ptcpos;
  147. return half4(finalColor * _Color.rgb, alpha);
  148. }
  149. ENDHLSL
  150. }
  151. }
  152. }