EnviroVolumetricCloudsReproject.shader 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. Shader "Hidden/EnviroVolumetricCloudsReproject"
  2. {
  3. Properties
  4. {
  5. //_MainTex ("Texture", any) = "white" {}
  6. }
  7. SubShader
  8. {
  9. Tags { "RenderType"="Opaque" }
  10. LOD 100
  11. Pass
  12. {
  13. CGPROGRAM
  14. #pragma vertex vert
  15. #pragma fragment frag
  16. #pragma multi_compile _ ENVIRO_DEPTH_BLENDING
  17. #pragma multi_compile _ ENVIROURP
  18. #include "UnityCG.cginc"
  19. UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
  20. float4 _MainTex_TexelSize;
  21. UNITY_DECLARE_SCREENSPACE_TEXTURE(_UndersampleCloudTex);
  22. float4 _UndersampleCloudTex_TexelSize;
  23. UNITY_DECLARE_SCREENSPACE_TEXTURE(_DownsampledDepth);
  24. float4x4 _PrevVP;
  25. float4x4 _CamToWorld;
  26. float4 _ProjectionExtents;
  27. float4 _ProjectionExtentsRight;
  28. float2 _TexelSize;
  29. float _BlendTime;
  30. struct appdata
  31. {
  32. float4 vertex : POSITION;
  33. float2 uv : TEXCOORD0;
  34. UNITY_VERTEX_INPUT_INSTANCE_ID
  35. };
  36. struct v2f
  37. {
  38. float4 vertex : SV_POSITION;
  39. float2 uv : TEXCOORD0;
  40. float2 ray : TEXCOORD1;
  41. float4 screenPos : TEXCOORD2;
  42. UNITY_VERTEX_OUTPUT_STEREO
  43. };
  44. v2f vert(appdata v)
  45. {
  46. v2f o;
  47. UNITY_SETUP_INSTANCE_ID(v);
  48. UNITY_INITIALIZE_OUTPUT(v2f, o);
  49. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  50. #if defined(ENVIROURP)
  51. o.vertex = float4(v.vertex.xyz,1.0);
  52. #if UNITY_UV_STARTS_AT_TOP
  53. o.vertex.y *= -1;
  54. #endif
  55. #else
  56. o.vertex = UnityObjectToClipPos(v.vertex);
  57. #endif
  58. o.uv = v.uv;
  59. if(unity_StereoEyeIndex == 0)
  60. o.ray = (2.0 * v.uv - 1.0) * _ProjectionExtents.xy + _ProjectionExtents.zw;
  61. else
  62. o.ray = (2.0 * v.uv - 1.0) * _ProjectionExtentsRight.xy + _ProjectionExtentsRight.zw;
  63. o.screenPos = ComputeScreenPos(o.vertex);
  64. return o;
  65. }
  66. float2 PrevUV(float4 wspos, out half outOfBound)
  67. {
  68. float4x4 prev = mul(unity_CameraProjection,_PrevVP);
  69. float4 prevUV = mul(prev, wspos);
  70. prevUV.xy = 0.5 * (prevUV.xy / prevUV.w) + 0.5;
  71. half oobmax = max(0.0 - prevUV.x, 0.0 - prevUV.y);
  72. half oobmin = max(prevUV.x - 1.0, prevUV.y - 1.0);
  73. outOfBound = step(0, max(oobmin, oobmax));
  74. return prevUV;
  75. }
  76. float4 ClipAABB(float4 aabbMin, float4 aabbMax, float4 prevSample)
  77. {
  78. float4 p_clip = 0.5 * (aabbMax + aabbMin);
  79. float4 e_clip = 0.5 * (aabbMax - aabbMin);
  80. float4 v_clip = prevSample - p_clip;
  81. float4 v_unit = v_clip / e_clip;
  82. float4 a_unit = abs(v_unit);
  83. float ma_unit = max(max(a_unit.x, max(a_unit.y, a_unit.z)), a_unit.w);
  84. if (ma_unit > 1.0)
  85. return p_clip + v_clip / ma_unit;
  86. else
  87. return prevSample;
  88. }
  89. float4 frag(v2f i) : SV_Target
  90. {
  91. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  92. float3 vspos = float3(i.ray, 1.0);
  93. float4 raymarchResult = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_UndersampleCloudTex,UnityStereoTransformScreenSpaceTex(i.uv));
  94. float distance = raymarchResult.y;
  95. float intensity = raymarchResult.x;
  96. half outOfBound;
  97. float4 worldPos = mul(_CamToWorld, float4(normalize(vspos) * distance, 1.0));
  98. worldPos /= worldPos.w;
  99. float2 prevUV = PrevUV(worldPos, outOfBound);
  100. {
  101. float4 prevSample = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, UnityStereoTransformScreenSpaceTex(prevUV));
  102. float4 m1 = float4(0.0f,0.0f,0.0f,0.0f);
  103. float4 m2 = float4(0.0f,0.0f,0.0f,0.0f);
  104. float sampleCount = 1.0f;
  105. #if ENVIRO_DEPTH_BLENDING
  106. float originalPointDepth = LinearEyeDepth(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_DownsampledDepth, UnityStereoTransformScreenSpaceTex(i.uv)));
  107. #endif
  108. [unroll]
  109. for (int x = -1; x <= 1; x ++)
  110. {
  111. [unroll]
  112. for (int y = -1; y <= 1; y ++ )
  113. {
  114. float4 val;
  115. if (x == 0 && y == 0)
  116. {
  117. val = raymarchResult;
  118. m1 += val;
  119. m2 += val * val;
  120. }
  121. else
  122. {
  123. float2 uv = i.uv + float2(x * _UndersampleCloudTex_TexelSize.x, y * _UndersampleCloudTex_TexelSize.y);
  124. val = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_UndersampleCloudTex, UnityStereoTransformScreenSpaceTex(uv));
  125. #if ENVIRO_DEPTH_BLENDING
  126. float depth = LinearEyeDepth(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_DownsampledDepth,UnityStereoTransformScreenSpaceTex(uv)));
  127. if (abs(originalPointDepth - depth < 1.5f))
  128. {
  129. m1 += val;
  130. m2 += val * val;
  131. sampleCount += 1.0f;
  132. }
  133. #else
  134. m1 += val;
  135. m2 += val * val;
  136. sampleCount += 1.0f;
  137. #endif
  138. }
  139. }
  140. }
  141. float gamma = _BlendTime;
  142. float4 mu = m1 / sampleCount;
  143. float4 sigma = sqrt(abs(m2 / sampleCount - mu * mu));
  144. float4 minc = mu - gamma * sigma;
  145. float4 maxc = mu + gamma * sigma;
  146. prevSample = ClipAABB(minc, maxc, prevSample);
  147. //Blend.
  148. raymarchResult = lerp(prevSample, raymarchResult, max(0.01f, outOfBound));
  149. }
  150. return raymarchResult;
  151. }
  152. ENDCG
  153. }
  154. }
  155. }