ParallaxCloud.shader 8.4 KB

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