EnviroVolumetricCloudsRaymarch.shader 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. Shader "Hidden/EnviroCloudsRaymarch"
  2. {
  3. Properties
  4. {
  5. //_MainTex ("Texture", any) = "white" {}
  6. }
  7. SubShader
  8. {
  9. // No culling or depth
  10. Cull Off ZWrite Off ZTest Always
  11. Pass
  12. {
  13. CGPROGRAM
  14. #pragma vertex vert
  15. #pragma fragment frag
  16. #pragma multi_compile _ ENVIRO_DEPTH_BLENDING
  17. #pragma multi_compile _ ENVIRO_DUAL_LAYER
  18. #pragma multi_compile _ ENVIRO_CLOUD_SHADOWS
  19. #pragma multi_compile _ ENVIROURP
  20. #include "UnityCG.cginc"
  21. #include "../Includes/VolumetricCloudsInclude.cginc"
  22. int _Frame;
  23. struct v2f
  24. {
  25. float4 position : SV_POSITION;
  26. float2 uv : TEXCOORD0;
  27. float4 screenPos : TEXCOORD1;
  28. float eyeIndex : TEXCOORD2;
  29. UNITY_VERTEX_OUTPUT_STEREO
  30. };
  31. struct appdata
  32. {
  33. float4 vertex : POSITION;
  34. float2 texcoord : TEXCOORD0;
  35. UNITY_VERTEX_INPUT_INSTANCE_ID
  36. };
  37. v2f vert (appdata_img v)
  38. {
  39. v2f o;
  40. UNITY_SETUP_INSTANCE_ID(v);
  41. UNITY_INITIALIZE_OUTPUT(v2f, o);
  42. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  43. o.eyeIndex = unity_StereoEyeIndex;
  44. #if defined(ENVIROURP)
  45. o.position = float4(v.vertex.xyz,1.0);
  46. #if UNITY_UV_STARTS_AT_TOP
  47. o.position.y *= -1;
  48. #endif
  49. #else
  50. o.position = UnityObjectToClipPos(v.vertex);
  51. #endif
  52. o.uv = v.texcoord;
  53. o.screenPos = ComputeScreenPos(o.position);
  54. return o;
  55. }
  56. float getRandomRayOffset(float2 uv) // uses blue noise texture to get random ray offset
  57. {
  58. float noise = tex2D(_BlueNoise, uv).x;
  59. noise = mad(noise, 2.0, 1.0);
  60. return noise;
  61. }
  62. fixed4 frag (v2f i) : SV_Target
  63. {
  64. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  65. float4 cameraRay = float4(i.uv * 2.0 - 1.0, 1.0, 1.0);
  66. float3 EyePosition = _CameraPosition;
  67. float3 ray = 0;
  68. //return lerp(float4(1, 0, 0, 1), float4(0, 1, 0, 1), unity_StereoEyeIndex);
  69. if (unity_StereoEyeIndex == 0)
  70. {
  71. cameraRay = mul(_InverseProjection, cameraRay);
  72. cameraRay = cameraRay / cameraRay.w;
  73. ray = normalize(mul((float3x3)_InverseRotation, cameraRay.xyz));
  74. }
  75. else
  76. {
  77. cameraRay = mul(_InverseProjectionRight, cameraRay);
  78. cameraRay = cameraRay / cameraRay.w;
  79. ray = normalize(mul((float3x3)_InverseRotationRight, cameraRay.xyz));
  80. }
  81. float rayLength = length(ray);
  82. float sceneDepth = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_DownsampledDepth, UnityStereoTransformScreenSpaceTex(i.uv));
  83. float raymarchEnd = GetRaymarchEndFromSceneDepth(Linear01Depth(sceneDepth), 100000); //* rayLenght
  84. float raymarchEndShadows = GetRaymarchEndFromSceneDepth(Linear01Depth(sceneDepth), 1000);
  85. float offset = tex2D(_BlueNoise, squareUV(i.uv + _Randomness.xy)).x * _CloudDensityScale.z;
  86. //offset = clamp(offset - 2,-2,2);
  87. float3 pCent = float3(EyePosition.x, -_CloudsParameter.w, EyePosition.z);
  88. float bIntensity, bDistance, bAlpha, shadow = 0.0f;
  89. float3 wpos;
  90. #if ENVIRO_DUAL_LAYER
  91. //Clouds Layer 1
  92. RaymarchParameters parametersLayer1;
  93. InitRaymarchParametersLayer1(parametersLayer1);
  94. float2 hitDistanceLayer1 = ResolveRay(EyePosition,ray,pCent, raymarchEnd, parametersLayer1);
  95. float3 layer1Final = Raymarch(EyePosition,ray,hitDistanceLayer1.xy,pCent,parametersLayer1,offset,0);
  96. #if ENVIRO_CLOUD_SHADOWS
  97. //Clouds Shadows Layer1
  98. wpos = CalculateWorldPosition(i.uv,sceneDepth);
  99. float2 shadowHitDistanceLayer1 = ResolveRay(EyePosition,ray,pCent, raymarchEnd, parametersLayer1).xy;
  100. float shadowsLayer1 = RaymarchShadows(EyePosition,wpos,ray, shadowHitDistanceLayer1,pCent,parametersLayer1,offset,sceneDepth,0);
  101. #endif
  102. //Clouds Layer 2
  103. RaymarchParameters parametersLayer2;
  104. InitRaymarchParametersLayer2(parametersLayer2);
  105. float2 hitDistanceLayer2 = ResolveRay(EyePosition,ray,pCent,raymarchEnd, parametersLayer2);
  106. float3 layer2Final = Raymarch(EyePosition,ray,hitDistanceLayer2,pCent,parametersLayer2,offset,1);
  107. #if ENVIRO_CLOUD_SHADOWS
  108. //Clouds Shadows Layer2
  109. float2 shadowHitDistanceLayer2 = ResolveRay(EyePosition,ray,pCent, raymarchEnd, parametersLayer2).xy;
  110. float shadowsLayer2 = RaymarchShadows(EyePosition,wpos,ray, shadowHitDistanceLayer2,pCent,parametersLayer2,offset,sceneDepth,1);
  111. #endif
  112. if (EyePosition.y < _CloudsParameter2.x)
  113. {
  114. if(layer1Final.b >= 1.0)
  115. return float4(layer1Final.r,layer1Final.g,shadow,layer1Final.b);
  116. if(layer2Final.z <= 0)
  117. {
  118. bIntensity = layer1Final.r;
  119. bDistance = layer1Final.g;
  120. bAlpha = layer1Final.b;
  121. }
  122. else
  123. {
  124. bIntensity = layer2Final.x * (1-layer1Final.z) + layer1Final.x;
  125. bDistance = layer2Final.y * (1-layer1Final.z) + layer1Final.y * layer1Final.z;
  126. bAlpha = layer2Final.z * (1-layer1Final.z) + layer1Final.z;
  127. }
  128. }
  129. else
  130. {
  131. if(layer2Final.b >= 1.0)
  132. return float4(layer2Final.r,layer2Final.g,1.0,layer2Final.b);
  133. bIntensity = layer1Final.x * (1-layer2Final.z) + layer2Final.x;
  134. bDistance = layer1Final.y * (1-layer2Final.z) + layer2Final.y * layer2Final.z;
  135. bAlpha = layer1Final.z * (1-layer2Final.z) + layer2Final.z;
  136. }
  137. #if ENVIRO_CLOUD_SHADOWS
  138. //Combine cloud shadows.
  139. shadow = shadowsLayer1 + shadowsLayer2;
  140. #endif
  141. #else
  142. RaymarchParameters parametersLayer1;
  143. InitRaymarchParametersLayer1(parametersLayer1);
  144. float2 hitDistanceLayer1 = ResolveRay(EyePosition,ray,pCent, raymarchEnd, parametersLayer1);
  145. float3 layer1Final = Raymarch(EyePosition,ray,hitDistanceLayer1,pCent,parametersLayer1,offset,0);
  146. #if ENVIRO_CLOUD_SHADOWS
  147. //Clouds Shadows
  148. float2 shadowHitDistanceLayer1 = ResolveRay(EyePosition,ray,pCent, raymarchEnd, parametersLayer1).xy;
  149. wpos = CalculateWorldPosition(i.uv,sceneDepth);
  150. shadow = RaymarchShadows(EyePosition,wpos,ray, shadowHitDistanceLayer1,pCent,parametersLayer1,offset,sceneDepth,0);
  151. #endif
  152. bIntensity = layer1Final.r;
  153. bDistance = layer1Final.g;
  154. bAlpha = layer1Final.b;
  155. #endif
  156. return float4(max(bIntensity,0.0f),max(bDistance,0.0f),clamp(shadow,0.0,0.25),max(bAlpha,0.0f));
  157. }
  158. ENDCG
  159. }
  160. }
  161. }