VolumetricCloudsInclude.cginc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1.  UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
  2. #pragma exclude_renderers gles
  3. uniform Texture3D _Noise;
  4. SamplerState sampler_Noise;
  5. uniform Texture3D _DetailNoise;
  6. SamplerState sampler_DetailNoise;
  7. uniform Texture2D _WeatherMap;
  8. SamplerState sampler_WeatherMap;
  9. uniform Texture2D _CurlNoise;
  10. SamplerState sampler_CurlNoise;
  11. uniform sampler2D _BlueNoise;
  12. float4 _BlueNoise_TexelSize;
  13. UNITY_DECLARE_SCREENSPACE_TEXTURE(_DownsampledDepth);
  14. UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthTexture);
  15. uniform float4x4 _InverseProjection;
  16. uniform float4x4 _InverseRotation;
  17. uniform float4x4 _InverseProjectionRight;
  18. uniform float4x4 _InverseRotationRight;
  19. float4x4 _LeftWorldFromView;
  20. float4x4 _RightWorldFromView;
  21. float4x4 _LeftViewFromScreen;
  22. float4x4 _RightViewFromScreen;
  23. uniform float4 _CloudsParameter;
  24. uniform float4 _CloudsParameter2;
  25. uniform float4 _Steps;
  26. uniform float4 _CloudsLighting;
  27. uniform float4 _CloudsLighting2;
  28. uniform float4 _CloudsLightingExtended;
  29. uniform float4 _CloudsLightingExtended2;
  30. uniform float4 _CloudsMultiScattering;
  31. uniform float4 _CloudsMultiScattering2;
  32. uniform float4 _CloudsErosionIntensity; //x = Base, y = Detail
  33. uniform float4 _CloudsNoiseSettings; //x = Base, y = Detail
  34. uniform float4 _CloudDensityScale;
  35. uniform float4 _CloudsCoverageSettings; //x = _GlobalCoverage, y = Bottom Coverage Mod, z = Top coverage mod, w = Clouds Up Morph Intensity
  36. uniform float _GlobalCoverage;
  37. uniform float4 _CloudsAnimation;
  38. uniform float4 _CloudsWindDirection;
  39. uniform float3 _LightDir;
  40. uniform float _stepsInDepth;
  41. uniform float _LODDistance;
  42. uniform float3 _CameraPosition;
  43. uniform float4 _Resolution;
  44. uniform float4 _Randomness;
  45. ////
  46. const float env_inf = 1e10;
  47. struct RaymarchParameters
  48. {
  49. //Lighting
  50. float scatteringCoef;
  51. float hgPhase;
  52. float silverLiningIntensity;
  53. float silverLiningSpread;
  54. float powderTerm;
  55. float attenuation;
  56. float lightStep;
  57. float lightAbsorb;
  58. float multiScatteringA;
  59. float multiScatteringB;
  60. float multiScatteringC;
  61. //Height
  62. float4 cloudsParameter;
  63. //Density
  64. float density;
  65. //Erosion
  66. float baseErosion;
  67. float detailErosion;
  68. int minSteps, maxSteps;
  69. float baseNoiseUV;
  70. float detailNoiseUV;
  71. float baseErosionIntensity;
  72. float detailErosionIntensity;
  73. float anvilBias;
  74. };
  75. /*
  76. struct Lightning
  77. {
  78. float3 pos;
  79. float range;
  80. float intensity;
  81. };
  82. StructuredBuffer<Lightning> _Lightnings;
  83. float _LightningCount;
  84. float anisotropy(float costheta)
  85. {
  86. float g = 0.5f;
  87. float gsq = g*g;
  88. float denom = 1 + gsq - 2.0 * g * costheta;
  89. denom = denom * denom * denom;
  90. denom = sqrt(max(0, denom));
  91. return (1 - gsq) / denom;
  92. }
  93. float Attenuation(float distNorm)
  94. {
  95. return 1.0 / (1.0 + 25.0 * distNorm);
  96. }
  97. float Lightnings(float3 pos)
  98. {
  99. float intensity = 0.0f;
  100. for (int i = 0; i < _LightningCount; i++)
  101. {
  102. float3 posToLight = _Lightnings[i].pos - pos;
  103. //float3 posToLight = _Lightnings[i].pos - pos;
  104. float distNorm = dot(posToLight, posToLight) * _Lightnings[i].range;
  105. float att = Attenuation(distNorm);
  106. //#if ANISOTROPY
  107. float3 cameraToPos = normalize(pos - _WorldSpaceCameraPos.xyz);
  108. float costheta = dot(cameraToPos, normalize(posToLight));
  109. att *= anisotropy(costheta);
  110. //#endif
  111. intensity += _Lightnings[i].intensity * att;
  112. }
  113. return intensity;
  114. }
  115. */
  116. void InitRaymarchParametersLayer1(inout RaymarchParameters parameters)
  117. {
  118. parameters.scatteringCoef = _CloudsLighting.x;
  119. parameters.hgPhase = _CloudsLighting.y;
  120. parameters.silverLiningIntensity = _CloudsLighting.z;
  121. parameters.silverLiningSpread = _CloudsLighting.w;
  122. parameters.multiScatteringA = _CloudsMultiScattering.x;
  123. parameters.multiScatteringB = _CloudsMultiScattering.y;
  124. parameters.multiScatteringC = _CloudsMultiScattering.z;
  125. parameters.powderTerm = _CloudsLightingExtended.x;
  126. parameters.attenuation = _CloudsLightingExtended.y;
  127. parameters.lightStep = _CloudsLightingExtended.z;
  128. parameters.lightAbsorb = _CloudsLightingExtended.w;
  129. parameters.cloudsParameter = _CloudsParameter;
  130. parameters.density = _CloudDensityScale.x;
  131. parameters.baseErosion = _CloudsErosionIntensity.x;
  132. parameters.detailErosion = _CloudsErosionIntensity.y;
  133. parameters.minSteps = _Steps.x;
  134. parameters.maxSteps = _Steps.y;
  135. parameters.baseNoiseUV = _CloudsNoiseSettings.x;
  136. parameters.detailNoiseUV = _CloudsNoiseSettings.y;
  137. parameters.baseErosionIntensity = _CloudsErosionIntensity.x;
  138. parameters.detailErosionIntensity = _CloudsErosionIntensity.y;
  139. parameters.anvilBias = _CloudsCoverageSettings.z;
  140. }
  141. void InitRaymarchParametersLayer2(inout RaymarchParameters parameters)
  142. {
  143. parameters.scatteringCoef = _CloudsLighting2.x;
  144. parameters.hgPhase = _CloudsLighting2.y;
  145. parameters.silverLiningIntensity = _CloudsLighting2.z;
  146. parameters.silverLiningSpread = _CloudsLighting2.w;
  147. parameters.multiScatteringA = _CloudsMultiScattering2.x;
  148. parameters.multiScatteringB = _CloudsMultiScattering2.y;
  149. parameters.multiScatteringC = _CloudsMultiScattering2.z;
  150. parameters.powderTerm = _CloudsLightingExtended2.x;
  151. parameters.attenuation = _CloudsLightingExtended2.y;
  152. parameters.lightStep = _CloudsLightingExtended2.z;
  153. parameters.lightAbsorb = _CloudsLightingExtended2.w;
  154. parameters.cloudsParameter = _CloudsParameter2;
  155. parameters.density = _CloudDensityScale.y;
  156. parameters.baseErosion = _CloudsErosionIntensity.x;
  157. parameters.detailErosion = _CloudsErosionIntensity.y;
  158. parameters.minSteps = _Steps.z;
  159. parameters.maxSteps = _Steps.w;
  160. parameters.baseNoiseUV = _CloudsNoiseSettings.z;
  161. parameters.detailNoiseUV = _CloudsNoiseSettings.w;
  162. parameters.baseErosionIntensity = _CloudsErosionIntensity.z;
  163. parameters.detailErosionIntensity = _CloudsErosionIntensity.w;
  164. parameters.anvilBias = _CloudsCoverageSettings.w;
  165. }
  166. uint intersectRaySphere(float3 rayOrigin,float3 rayDir, float3 sphereCenter, float sphereRadius, out float2 t)
  167. {
  168. float3 l = rayOrigin - sphereCenter;
  169. float a = 1.0f; // dot(rayDir, rayDir) where rayDir is normalized
  170. float b = 2.0f * dot(rayDir, l);
  171. float c = dot(l, l) - sphereRadius * sphereRadius;
  172. float discriminate = b * b - 4.0f * a * c;
  173. if (discriminate < 0.0f)
  174. {
  175. t.x = t.y = 0.0f;
  176. return 0u;
  177. }
  178. else if (abs(discriminate) - 0.00005f <= 0.0f)
  179. {
  180. t.x = t.y = -0.5f * b / a;
  181. return 1u;
  182. }
  183. else
  184. {
  185. float q = b > 0.0f ? -0.5f * (b + sqrt(discriminate)) : -0.5f * (b - sqrt(discriminate));
  186. float h1 = q / a;
  187. float h2 = c / q;
  188. t.x = min(h1, h2);
  189. t.y = max(h1, h2);
  190. if (t.x < 0.0f)
  191. {
  192. t.x = t.y;
  193. if (t.x < 0.0f)
  194. {
  195. return 0u;
  196. }
  197. return 1u;
  198. }
  199. return 2u;
  200. }
  201. }
  202. float2 ResolveInside(float3 cameraPos, float3 cameraDir, float maxDistance, RaymarchParameters parameter)
  203. {
  204. const float3 up = float3(0, 1, 0);
  205. maxDistance = min(parameter.cloudsParameter.w, maxDistance);
  206. float bottom = (parameter.cloudsParameter.x - cameraPos.y);
  207. float top = ((parameter.cloudsParameter.x + parameter.cloudsParameter.y) - cameraPos.y);
  208. float horizon = dot(cameraDir, up);
  209. float bottomDist = max(0, bottom / horizon);
  210. float topDist = max(0, top / horizon);
  211. float startDist = min(bottomDist, topDist);
  212. float endDist = max(bottomDist, topDist);
  213. startDist = min(maxDistance, startDist);
  214. endDist = min(maxDistance, endDist);
  215. return float2(startDist, endDist);
  216. }
  217. float HenryGreenstein(float cosTheta, float g) {
  218. float k = 3.0 / (8.0 * 3.1415926f) * (1.0 - g * g) / (2.0 + g * g);
  219. return k * (1.0 + cosTheta * cosTheta) / pow(abs(1.0 + g * g - 2.0 * g * cosTheta), 1.5);
  220. }
  221. float Remap(float org_val, float org_min, float org_max, float new_min, float new_max)
  222. {
  223. return new_min + saturate(((org_val - org_min) / (org_max - org_min))*(new_max - new_min));
  224. }
  225. float4 GetHeightGradient(float cloudType)
  226. {
  227. const float4 CloudGradient1 = float4(0.0, 0.07, 0.08, 0.15);
  228. const float4 CloudGradient2 = float4(0.0, 0.2, 0.42, 0.6);
  229. const float4 CloudGradient3 = float4(0.0, 0.08, 0.75, 0.98);
  230. float a = 1.0 - saturate(cloudType * 2.0);
  231. float b = 1.0 - abs(cloudType - 0.5) * 2.0;
  232. float c = saturate(cloudType - 0.5) * 2.0;
  233. return CloudGradient1 * a + CloudGradient2 * b + CloudGradient3 * c;
  234. }
  235. float GradientStep(float a, float4 gradient)
  236. {
  237. return smoothstep(gradient.x, gradient.y, a) - smoothstep(gradient.z, gradient.w, a);
  238. }
  239. float4 GetWeather(float3 pos)
  240. {
  241. float2 uv = pos.xz * 0.0000025;
  242. return _WeatherMap.SampleLevel(sampler_WeatherMap,uv, 0);
  243. }
  244. float GetSamplingHeight(float3 pos, float3 center, float4 parameters)
  245. {
  246. return (length(pos - center) - (parameters.w + parameters.x)) * parameters.z;
  247. }
  248. float3 ScreenSpaceDither(float2 vScreenPos, float lum)
  249. {
  250. float d = dot(float2(131.0, 312.0), vScreenPos.xy); //+ _Time TODO
  251. float3 vDither = float3(d, d, d);
  252. vDither.rgb = frac(vDither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5);
  253. return (vDither.rgb / 15.0) * 1.0 * lum;
  254. }
  255. float GetRaymarchEndFromSceneDepth(float sceneDepth, float maxRange)
  256. {
  257. float raymarchEnd = 0.0f;
  258. //#if ENVIRO_DEPTH_BLENDING
  259. if (sceneDepth == 1.0f)
  260. {
  261. raymarchEnd = maxRange;
  262. }
  263. else
  264. {
  265. raymarchEnd = sceneDepth * _ProjectionParams.z;
  266. }
  267. //#else
  268. // raymarchEnd = maxRange;
  269. //#endif
  270. return raymarchEnd;
  271. }
  272. float HeightAlter(float percent_height, float weather, float anvil)
  273. {
  274. float cloud_anvil_amount = 0.5;
  275. float global_coverage = 0.5;
  276. // Round bottom a bit
  277. float ret_val = saturate(Remap(percent_height, 0.0, 0.07, 0.0, 1.0));
  278. // Round top a lot
  279. float stop_height = saturate(weather + 0.12);
  280. ret_val *= saturate(Remap(percent_height, stop_height * 0.2, stop_height, 1.0, 0.0));
  281. // Apply anvil ( cumulonimbus /" giant storm" clouds)
  282. ret_val = pow(ret_val, saturate(Remap(percent_height, 0.65, 0.95, 1.0, (1 - cloud_anvil_amount * global_coverage))));
  283. return ret_val;
  284. }
  285. float DensityAlter(float coverage, float percent_height, float anvil)
  286. {
  287. // Have density be generally increasing over height
  288. float ret_val = percent_height;
  289. // Reduce density at base
  290. ret_val *= saturate(Remap(percent_height, 0.0, 0.2, 0.0, 1.0));
  291. ret_val *= 2;
  292. // Reduce density for the anvil (cumulonimbus clouds)
  293. ret_val *= lerp(ret_val, saturate(Remap(pow(percent_height, 0.5), 0.4, 0.95, 1.0, 0.2)), 1-anvil);
  294. // Reduce density at top to make better transition
  295. ret_val *= saturate(Remap(percent_height, 0.9, 1.0, 1.0, 0.0));
  296. return ret_val;
  297. }
  298. // Sample Cloud Density
  299. float CalculateCloudDensity(float3 pos, float3 PlanetCenter, RaymarchParameters parameters, float2 weather, float mip, float lod, bool details)
  300. {
  301. const float baseFreq = 1e-5;
  302. // Get Height fraction
  303. float height = GetSamplingHeight(pos, PlanetCenter, parameters.cloudsParameter);
  304. // wind settings
  305. float cloud_top_offset = 2000.0;
  306. float3 wind_direction = float3(_CloudsWindDirection.x, 0.0, _CloudsWindDirection.y);
  307. // skew in wind direction
  308. pos += height * wind_direction * cloud_top_offset;
  309. float mip1 = mip + lod;// + dist * _LODDistance;
  310. float4 coord = float4(pos * baseFreq * parameters.baseNoiseUV, mip1);
  311. // Animate Wind
  312. // coord.xyz += float3(_ CloudsWindDirection.z, 0.0f, _CloudsWindDirection.w);
  313. float4 baseNoise = 0;
  314. baseNoise = _Noise.SampleLevel(sampler_Noise, coord.xyz,coord.w);
  315. float low_freq_fBm = (baseNoise.g * 0.625) + (baseNoise.b * 0.25) + (baseNoise.a * 0.125);
  316. float base_cloud = Remap(baseNoise.r, -(1.0 - low_freq_fBm) * parameters.baseErosionIntensity, 1.0, 0.0, 1.0);
  317. float heightGradient = GradientStep(height, GetHeightGradient(saturate(weather.g * 2.0)));
  318. base_cloud *= heightGradient;
  319. float cloud_coverage = saturate(1-weather.r);
  320. float densAlter = DensityAlter(cloud_coverage,(1-height * 0.75), parameters.anvilBias);
  321. cloud_coverage = pow(cloud_coverage, densAlter);
  322. // cloud_coverage = pow(cloud_coverage, Remap(height, 0.7, 0.8, 1.0, lerp(1.0, 0.5, parameters.anvilBias)));
  323. float cloudDensity = Remap(base_cloud, cloud_coverage, 1.0, 0.0, 1.0);
  324. cloudDensity = max(cloudDensity * (1-cloud_coverage),0.0);
  325. //DETAIL
  326. [branch]
  327. if (details)
  328. {
  329. float mip2 = mip + lod;// + dist * _LODDistance;
  330. coord = float4(pos * baseFreq * parameters.detailNoiseUV, mip2);
  331. coord.xyz += float3(_CloudsAnimation.x, _CloudsAnimation.z, _CloudsAnimation.y);
  332. float3 curl_noise1 = _CurlNoise.SampleLevel(sampler_CurlNoise, float2(coord.x * 5,coord.y * 5), 0).rgb;
  333. coord.xyz += pow(saturate(curl_noise1.rgb),0.1) * parameters.attenuation;// * saturate(height * 10);
  334. float3 detailNoise = _DetailNoise.SampleLevel(sampler_DetailNoise, coord.xyz, coord.w).rgb;
  335. float high_freq_fBm = (detailNoise.r * 0.625) + (detailNoise.g * 0.25) + (detailNoise.b * 0.125);
  336. float high_freq_noise_modifier = lerp(high_freq_fBm, 1.0f - high_freq_fBm, saturate(height * 10));
  337. //float high_freq_noise_modifier = 1.0f - high_freq_fBm;
  338. cloudDensity = Remap(cloudDensity, high_freq_noise_modifier * parameters.detailErosionIntensity, 1.0, 0.0, 1.0);
  339. }
  340. return cloudDensity;
  341. }
  342. static const float shadowSampleDistance[5] =
  343. {
  344. 0.5, 4, 6, 12.0, 48.0
  345. };
  346. static const float LightingInfluence[5] =
  347. {
  348. 4.0f, 2.0f, 2.0f, 4.0f, 2.0f
  349. };
  350. // Lighting Sample Function
  351. float GetDensityAlongRay(float3 pos, float3 PlanetCenter, RaymarchParameters parameters, float3 LightDirection, float2 weather, float lod)
  352. {
  353. float opticalDepth = 0.0;
  354. int mip_offset = 0.5;
  355. [unroll]
  356. for (int i = 0; i < 5; i++)
  357. {
  358. float stepLength = shadowSampleDistance[i] * (512 * _CloudsLightingExtended.z);
  359. float3 samplePos = pos + LightDirection * stepLength;
  360. float sampleResult = CalculateCloudDensity(samplePos, PlanetCenter, parameters, weather, mip_offset, lod, true);
  361. opticalDepth += LightingInfluence[i] * sampleResult * (stepLength / (i + 1)) ;
  362. mip_offset += 0.5;
  363. }
  364. return opticalDepth * parameters.lightAbsorb;
  365. }
  366. float SampleEnergy(float3 pos, float cosTheta, float3 cent, RaymarchParameters parameters, float3 LightDirection, float height, float ds_loded, float step_size, float2 weather, float lod)
  367. {
  368. float opticsDistance = GetDensityAlongRay(pos, cent, parameters, LightDirection, weather, lod);
  369. float result = 0.0f;
  370. [unroll]
  371. for (int octaveIndex = 0; octaveIndex < 2; octaveIndex++)
  372. {
  373. //Multi scattering approximation based on Frostbite paper.
  374. float transmittance = exp(-parameters.density * pow(parameters.multiScatteringB, octaveIndex) * opticsDistance);
  375. float ecMult = pow(parameters.multiScatteringC, octaveIndex);
  376. float phase = lerp(HenryGreenstein(cosTheta, .5 * ecMult), HenryGreenstein(cosTheta,(0.99 - parameters.silverLiningSpread) * ecMult), 0.5f);
  377. result += phase * transmittance * parameters.scatteringCoef * 25.0f * pow(parameters.multiScatteringA, octaveIndex);
  378. }
  379. float powder = 1.0 - exp(-ds_loded * (1-parameters.powderTerm));
  380. powder = max(lerp(powder * 5, 1, cosTheta * 0.5 + 0.5), 0);
  381. return result * powder;
  382. }
  383. float2 squareUV(float2 uv)
  384. {
  385. float width = _Resolution.x;
  386. float height = _Resolution.y;
  387. float scale = 500;
  388. float x = uv.x * width;
  389. float y = uv.y * height;
  390. return float2 (x/scale, y/scale);
  391. }
  392. /*
  393. float sampleStart, sampleEnd;
  394. if (!resolve_ray_start_end(EyePosition, ray, sampleStart, sampleEnd) )
  395. {
  396. intensity = 0.0;
  397. depth = 1e6;
  398. return 0;
  399. }
  400. float3 sampleStartPos = EyePosition + ray * sampleStart;
  401. if (sampleEnd <= sampleStart || sampleStartPos.y < -200)
  402. {
  403. //Below horizon.
  404. intensity = 0.0;
  405. depth = 1e6;
  406. return 0.0;
  407. }
  408. sampleEnd = min(raymarchEnd, sampleEnd);
  409. sampleStart = max(0.0, sampleStart);
  410. float2 hitDistance = float2(sampleStart,sampleEnd);
  411. */
  412. float2 ResolveRay(float3 pos, float3 ray, float3 center, float raymarchEnd, RaymarchParameters parameter)
  413. {
  414. float2 hDistance;
  415. float2 ih = 0.0f;
  416. uint innerShellHits = intersectRaySphere(
  417. pos,
  418. ray,
  419. center,
  420. parameter.cloudsParameter.w + parameter.cloudsParameter.x,
  421. ih);
  422. // find nearest outer shell point
  423. float2 oh = 0.0f;
  424. uint outerShellHits = intersectRaySphere(
  425. pos,
  426. ray,
  427. center,
  428. parameter.cloudsParameter.w + parameter.cloudsParameter.y,
  429. oh);
  430. // world space ray intersections
  431. float3 innerShellHit = pos + (ray * ih.x);
  432. float3 outerShellHit = pos + (ray * oh.x);
  433. float2 hitDistance;
  434. // eye radius from planet center
  435. float ch = length(pos - center) - parameter.cloudsParameter.w;
  436. if (ch < parameter.cloudsParameter.x)
  437. {
  438. if (ray.y < 0.0)
  439. return float4(0,0,0,0);
  440. hDistance = float2(ih.x, oh.x);
  441. }
  442. else if (ch > parameter.cloudsParameter.y)
  443. {
  444. float3 firstShellHit = outerShellHit;
  445. float3 secondShellHit = outerShellHits == 2u && innerShellHits == 0u ? pos + (ray * oh.y) : innerShellHit;
  446. float hit2 = outerShellHits == 2u && innerShellHits == 0u ? oh.y : ih.x;
  447. hDistance = float2(oh.x, hit2);
  448. }
  449. else // between shells
  450. {
  451. float3 shellHit = innerShellHits > 0u ? innerShellHit : outerShellHit;
  452. float hit = innerShellHits > 0u ? ih.x : oh.x;
  453. float height = Remap(pos.y, parameter.cloudsParameter.x, parameter.cloudsParameter.y * 0.75, 0, 1);
  454. hDistance = ResolveInside(pos.xyz, ray, lerp(25000, 50000, height), parameter);
  455. }
  456. hDistance.x = max(0.0, hDistance.x);
  457. hDistance.y = min(raymarchEnd, hDistance.y);
  458. hDistance.y = max(0.0, hDistance.y);
  459. return hDistance;
  460. }
  461. float3 Raymarch (float3 cameraPos, float3 ray, float2 hitDistance, float3 center, RaymarchParameters parameters, float offset, int layer)
  462. {
  463. float cloud_test = 0.0;
  464. int zero_density_sample_count = 0;
  465. float sampled_density_previous = -1.0;
  466. float alpha = 1.0;
  467. float intensity = 0.0;
  468. float depth = 0.0;
  469. float depthWeightSum = 0.000001f;
  470. float trans = 1.0f;
  471. int steps = (int)lerp(parameters.minSteps, parameters.maxSteps, ray.y);
  472. // int steps = parameters.maxSteps;
  473. float rayStepLength = (hitDistance.y - hitDistance.x) / steps;
  474. float3 rayStep = ray * rayStepLength;
  475. float3 pos = (cameraPos + (hitDistance.x) * ray);
  476. pos += (offset * rayStepLength) * ray;
  477. float3 sampleEndPos = cameraPos + ray * hitDistance.y;
  478. float eyeToEnd = distance(cameraPos, sampleEndPos);
  479. float cosTheta = dot(ray, normalize(_LightDir));
  480. [loop]
  481. for (int i = 0; i < steps; i++)
  482. {
  483. pos += rayStep;
  484. //Calculate projection height
  485. float height = GetSamplingHeight(pos, center, parameters.cloudsParameter);
  486. //Get out of expensive raymarching
  487. if (alpha <= 0.01 || height > 1.0 || height < 0.0 || _CloudsCoverageSettings.x <= -0.9)
  488. break;
  489. // Get Weather Data
  490. float2 weather;
  491. if(layer == 0)
  492. weather = GetWeather(pos).xy;
  493. else
  494. weather = GetWeather(pos).zw;
  495. float dist = Remap(length(pos - cameraPos),0.0,length(sampleEndPos - cameraPos) * _LODDistance * 10.0,0.0,1.0);
  496. float lod = lerp(0.0,5.0,dist);
  497. if (cloud_test > 0.0)
  498. {
  499. float sampled_density = CalculateCloudDensity(pos, center, parameters, weather, 0, lod, true);
  500. //float sampled_density_lod = CalculateCloudDensity(pos, center, parameters, weather, 0.5, lod, true) * 0.25;
  501. if (sampled_density == 0.0 && sampled_density_previous == 0.0)
  502. {
  503. zero_density_sample_count++;
  504. }
  505. if (zero_density_sample_count < 11 && sampled_density != 0.0)
  506. {
  507. float extinction = parameters.density * sampled_density;
  508. float clampedExtinction = max(extinction, 1e-7);
  509. float transmittance = exp(-extinction * rayStepLength);
  510. //ds += clampedExtinction * rayStepLength;
  511. float luminance = SampleEnergy(pos, cosTheta, center, parameters, _LightDir, height, sampled_density * rayStepLength, rayStepLength, weather, lod);
  512. float integScatt = (luminance - luminance * transmittance);
  513. float depthWeight = trans;
  514. depth += depthWeight * length(pos - cameraPos);
  515. depthWeightSum += depthWeight;
  516. intensity += trans * integScatt;
  517. trans *= transmittance;
  518. alpha *= max(transmittance, 0.0);
  519. if (alpha <= 0.01)
  520. alpha = 0.0;
  521. }
  522. // if not, then set cloud_test to zero so that we go back to the cheap sample case
  523. else
  524. {
  525. cloud_test = 0.0;
  526. zero_density_sample_count = 0;
  527. }
  528. sampled_density_previous = sampled_density;
  529. }
  530. else
  531. {
  532. // sample density the cheap way, only using the low frequency noise
  533. cloud_test = CalculateCloudDensity(pos, center,parameters, weather, 0, lod, false);
  534. if (cloud_test == 0.0)
  535. {
  536. pos += rayStep;
  537. }
  538. else //take a step back and capture area we skipped.
  539. {
  540. pos -= rayStep;
  541. }
  542. }
  543. }
  544. float distance = depth / depthWeightSum;
  545. if (distance == 0.0f)
  546. {
  547. distance = length(sampleEndPos - cameraPos);
  548. }
  549. alpha = saturate(1.0f - alpha);
  550. return float3(intensity,distance,alpha);
  551. }
  552. float3 CalculateWorldPosition (float2 uv, float depth)
  553. {
  554. float4x4 proj, eyeToWorld;
  555. if (unity_StereoEyeIndex == 0)
  556. {
  557. proj = _LeftViewFromScreen;
  558. eyeToWorld = _LeftWorldFromView;
  559. }
  560. else
  561. {
  562. proj = _RightViewFromScreen;
  563. eyeToWorld = _RightWorldFromView;
  564. }
  565. //bit of matrix math to take the screen space coord (u,v,depth) and transform to world space
  566. float2 uvClip = uv * 2.0 - 1.0;
  567. float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
  568. clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
  569. float4 clipPos = float4(uvClip, clipDepth, 1.0);
  570. float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
  571. viewPos /= viewPos.w; // perspective division
  572. return float3(mul(eyeToWorld, viewPos).xyz);
  573. }
  574. float RaymarchShadows (float3 cameraPos, float3 worldPos,float3 ray,float2 hitDistance, float3 center, RaymarchParameters parameters, float offset,float depth, int layer)
  575. {
  576. if(depth == 0.0f)
  577. return 0.0;
  578. int steps = 16;
  579. float worldDotLight = saturate(dot(float3(0, 1, 0), _LightDir));
  580. float bottomDist = max(0, parameters.cloudsParameter.x ) / worldDotLight;
  581. float topDist = max(0, parameters.cloudsParameter.y ) / worldDotLight;
  582. float rayStepLength = (topDist - bottomDist) / steps;
  583. float3 rayStep = _LightDir * rayStepLength;
  584. float3 pos = worldPos + bottomDist * _LightDir;
  585. float2 weather;
  586. float intensity = 1.0;
  587. if(layer == 0)
  588. {
  589. weather = GetWeather(pos).xy;
  590. intensity = 0.05;
  591. }
  592. else
  593. {
  594. weather = GetWeather(pos).zw;
  595. intensity = 0.025;
  596. }
  597. float shadowIntensity = 0.0;
  598. float _Softness = 2.0f;
  599. [unroll]
  600. for (int i = 0; i < steps; i++)
  601. {
  602. float3 samplePos = rayStepLength * i * _LightDir + pos;
  603. float sampleResult = CalculateCloudDensity(samplePos, center, parameters, weather, 0, 0, true) * intensity;
  604. float result = sampleResult * (rayStepLength / (i + 1));
  605. shadowIntensity += result;
  606. // if (shadowIntensity > 0.99)
  607. // break;
  608. }
  609. return (shadowIntensity);
  610. }