123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769 |
- UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
- #pragma exclude_renderers gles
- uniform Texture3D _Noise;
- SamplerState sampler_Noise;
- uniform Texture3D _DetailNoise;
- SamplerState sampler_DetailNoise;
- uniform Texture2D _WeatherMap;
- SamplerState sampler_WeatherMap;
- uniform Texture2D _CurlNoise;
- SamplerState sampler_CurlNoise;
- uniform sampler2D _BlueNoise;
- float4 _BlueNoise_TexelSize;
- UNITY_DECLARE_SCREENSPACE_TEXTURE(_DownsampledDepth);
- UNITY_DECLARE_SCREENSPACE_TEXTURE(_CameraDepthTexture);
- uniform float4x4 _InverseProjection;
- uniform float4x4 _InverseRotation;
- uniform float4x4 _InverseProjectionRight;
- uniform float4x4 _InverseRotationRight;
- float4x4 _LeftWorldFromView;
- float4x4 _RightWorldFromView;
- float4x4 _LeftViewFromScreen;
- float4x4 _RightViewFromScreen;
-
- uniform float4 _CloudsParameter;
- uniform float4 _CloudsParameter2;
-
- uniform float4 _Steps;
- uniform float4 _CloudsLighting;
- uniform float4 _CloudsLighting2;
- uniform float4 _CloudsLightingExtended;
- uniform float4 _CloudsLightingExtended2;
- uniform float4 _CloudsMultiScattering;
- uniform float4 _CloudsMultiScattering2;
- uniform float4 _CloudsErosionIntensity; //x = Base, y = Detail
- uniform float4 _CloudsNoiseSettings; //x = Base, y = Detail
-
- uniform float4 _CloudDensityScale;
- uniform float4 _CloudsCoverageSettings; //x = _GlobalCoverage, y = Bottom Coverage Mod, z = Top coverage mod, w = Clouds Up Morph Intensity
- uniform float _GlobalCoverage;
- uniform float4 _CloudsAnimation;
- uniform float4 _CloudsWindDirection;
-
- uniform float3 _LightDir;
- uniform float _stepsInDepth;
- uniform float _LODDistance;
- uniform float3 _CameraPosition;
- uniform float4 _Resolution;
- uniform float4 _Randomness;
- ////
- const float env_inf = 1e10;
- struct RaymarchParameters
- {
- //Lighting
- float scatteringCoef;
- float hgPhase;
- float silverLiningIntensity;
- float silverLiningSpread;
- float powderTerm;
- float attenuation;
- float lightStep;
- float lightAbsorb;
- float multiScatteringA;
- float multiScatteringB;
- float multiScatteringC;
- //Height
- float4 cloudsParameter;
- //Density
- float density;
- //Erosion
- float baseErosion;
- float detailErosion;
- int minSteps, maxSteps;
-
- float baseNoiseUV;
- float detailNoiseUV;
- float baseErosionIntensity;
- float detailErosionIntensity;
- float anvilBias;
- };
- /*
- struct Lightning
- {
- float3 pos;
- float range;
- float intensity;
- };
- StructuredBuffer<Lightning> _Lightnings;
- float _LightningCount;
- float anisotropy(float costheta)
- {
- float g = 0.5f;
- float gsq = g*g;
- float denom = 1 + gsq - 2.0 * g * costheta;
- denom = denom * denom * denom;
- denom = sqrt(max(0, denom));
- return (1 - gsq) / denom;
- }
- float Attenuation(float distNorm)
- {
- return 1.0 / (1.0 + 25.0 * distNorm);
- }
- float Lightnings(float3 pos)
- {
- float intensity = 0.0f;
-
- for (int i = 0; i < _LightningCount; i++)
- {
- float3 posToLight = _Lightnings[i].pos - pos;
- //float3 posToLight = _Lightnings[i].pos - pos;
- float distNorm = dot(posToLight, posToLight) * _Lightnings[i].range;
- float att = Attenuation(distNorm);
- //#if ANISOTROPY
- float3 cameraToPos = normalize(pos - _WorldSpaceCameraPos.xyz);
- float costheta = dot(cameraToPos, normalize(posToLight));
- att *= anisotropy(costheta);
- //#endif
-
- intensity += _Lightnings[i].intensity * att;
- }
- return intensity;
- }
- */
- void InitRaymarchParametersLayer1(inout RaymarchParameters parameters)
- {
- parameters.scatteringCoef = _CloudsLighting.x;
- parameters.hgPhase = _CloudsLighting.y;
- parameters.silverLiningIntensity = _CloudsLighting.z;
- parameters.silverLiningSpread = _CloudsLighting.w;
- parameters.multiScatteringA = _CloudsMultiScattering.x;
- parameters.multiScatteringB = _CloudsMultiScattering.y;
- parameters.multiScatteringC = _CloudsMultiScattering.z;
- parameters.powderTerm = _CloudsLightingExtended.x;
- parameters.attenuation = _CloudsLightingExtended.y;
- parameters.lightStep = _CloudsLightingExtended.z;
- parameters.lightAbsorb = _CloudsLightingExtended.w;
- parameters.cloudsParameter = _CloudsParameter;
- parameters.density = _CloudDensityScale.x;
-
- parameters.baseErosion = _CloudsErosionIntensity.x;
- parameters.detailErosion = _CloudsErosionIntensity.y;
- parameters.minSteps = _Steps.x;
- parameters.maxSteps = _Steps.y;
- parameters.baseNoiseUV = _CloudsNoiseSettings.x;
- parameters.detailNoiseUV = _CloudsNoiseSettings.y;
- parameters.baseErosionIntensity = _CloudsErosionIntensity.x;
- parameters.detailErosionIntensity = _CloudsErosionIntensity.y;
- parameters.anvilBias = _CloudsCoverageSettings.z;
- }
-
- void InitRaymarchParametersLayer2(inout RaymarchParameters parameters)
- {
- parameters.scatteringCoef = _CloudsLighting2.x;
- parameters.hgPhase = _CloudsLighting2.y;
- parameters.silverLiningIntensity = _CloudsLighting2.z;
- parameters.silverLiningSpread = _CloudsLighting2.w;
- parameters.multiScatteringA = _CloudsMultiScattering2.x;
- parameters.multiScatteringB = _CloudsMultiScattering2.y;
- parameters.multiScatteringC = _CloudsMultiScattering2.z;
- parameters.powderTerm = _CloudsLightingExtended2.x;
- parameters.attenuation = _CloudsLightingExtended2.y;
- parameters.lightStep = _CloudsLightingExtended2.z;
- parameters.lightAbsorb = _CloudsLightingExtended2.w;
- parameters.cloudsParameter = _CloudsParameter2;
- parameters.density = _CloudDensityScale.y;
- parameters.baseErosion = _CloudsErosionIntensity.x;
- parameters.detailErosion = _CloudsErosionIntensity.y;
- parameters.minSteps = _Steps.z;
- parameters.maxSteps = _Steps.w;
-
- parameters.baseNoiseUV = _CloudsNoiseSettings.z;
- parameters.detailNoiseUV = _CloudsNoiseSettings.w;
- parameters.baseErosionIntensity = _CloudsErosionIntensity.z;
- parameters.detailErosionIntensity = _CloudsErosionIntensity.w;
- parameters.anvilBias = _CloudsCoverageSettings.w;
- }
- uint intersectRaySphere(float3 rayOrigin,float3 rayDir, float3 sphereCenter, float sphereRadius, out float2 t)
- {
- float3 l = rayOrigin - sphereCenter;
- float a = 1.0f; // dot(rayDir, rayDir) where rayDir is normalized
- float b = 2.0f * dot(rayDir, l);
- float c = dot(l, l) - sphereRadius * sphereRadius;
- float discriminate = b * b - 4.0f * a * c;
- if (discriminate < 0.0f)
- {
- t.x = t.y = 0.0f;
- return 0u;
- }
- else if (abs(discriminate) - 0.00005f <= 0.0f)
- {
- t.x = t.y = -0.5f * b / a;
- return 1u;
- }
- else
- {
- float q = b > 0.0f ? -0.5f * (b + sqrt(discriminate)) : -0.5f * (b - sqrt(discriminate));
- float h1 = q / a;
- float h2 = c / q;
- t.x = min(h1, h2);
- t.y = max(h1, h2);
- if (t.x < 0.0f)
- {
- t.x = t.y;
- if (t.x < 0.0f)
- {
- return 0u;
- }
- return 1u;
- }
- return 2u;
- }
- }
- float2 ResolveInside(float3 cameraPos, float3 cameraDir, float maxDistance, RaymarchParameters parameter)
- {
- const float3 up = float3(0, 1, 0);
- maxDistance = min(parameter.cloudsParameter.w, maxDistance);
- float bottom = (parameter.cloudsParameter.x - cameraPos.y);
- float top = ((parameter.cloudsParameter.x + parameter.cloudsParameter.y) - cameraPos.y);
- float horizon = dot(cameraDir, up);
- float bottomDist = max(0, bottom / horizon);
- float topDist = max(0, top / horizon);
- float startDist = min(bottomDist, topDist);
- float endDist = max(bottomDist, topDist);
- startDist = min(maxDistance, startDist);
- endDist = min(maxDistance, endDist);
- return float2(startDist, endDist);
- }
- float HenryGreenstein(float cosTheta, float g) {
- float k = 3.0 / (8.0 * 3.1415926f) * (1.0 - g * g) / (2.0 + g * g);
- return k * (1.0 + cosTheta * cosTheta) / pow(abs(1.0 + g * g - 2.0 * g * cosTheta), 1.5);
- }
- float Remap(float org_val, float org_min, float org_max, float new_min, float new_max)
- {
- return new_min + saturate(((org_val - org_min) / (org_max - org_min))*(new_max - new_min));
- }
- float4 GetHeightGradient(float cloudType)
- {
- const float4 CloudGradient1 = float4(0.0, 0.07, 0.08, 0.15);
- const float4 CloudGradient2 = float4(0.0, 0.2, 0.42, 0.6);
- const float4 CloudGradient3 = float4(0.0, 0.08, 0.75, 0.98);
-
- float a = 1.0 - saturate(cloudType * 2.0);
- float b = 1.0 - abs(cloudType - 0.5) * 2.0;
- float c = saturate(cloudType - 0.5) * 2.0;
- return CloudGradient1 * a + CloudGradient2 * b + CloudGradient3 * c;
- }
- float GradientStep(float a, float4 gradient)
- {
- return smoothstep(gradient.x, gradient.y, a) - smoothstep(gradient.z, gradient.w, a);
- }
- float4 GetWeather(float3 pos)
- {
- float2 uv = pos.xz * 0.0000025;
- return _WeatherMap.SampleLevel(sampler_WeatherMap,uv, 0);
- }
- float GetSamplingHeight(float3 pos, float3 center, float4 parameters)
- {
- return (length(pos - center) - (parameters.w + parameters.x)) * parameters.z;
- }
-
- float3 ScreenSpaceDither(float2 vScreenPos, float lum)
- {
- float d = dot(float2(131.0, 312.0), vScreenPos.xy); //+ _Time TODO
- float3 vDither = float3(d, d, d);
- vDither.rgb = frac(vDither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5);
- return (vDither.rgb / 15.0) * 1.0 * lum;
- }
- float GetRaymarchEndFromSceneDepth(float sceneDepth, float maxRange)
- {
- float raymarchEnd = 0.0f;
- //#if ENVIRO_DEPTH_BLENDING
- if (sceneDepth == 1.0f)
- {
- raymarchEnd = maxRange;
- }
- else
- {
- raymarchEnd = sceneDepth * _ProjectionParams.z;
- }
- //#else
- // raymarchEnd = maxRange;
- //#endif
- return raymarchEnd;
- }
- float HeightAlter(float percent_height, float weather, float anvil)
- {
- float cloud_anvil_amount = 0.5;
- float global_coverage = 0.5;
- // Round bottom a bit
- float ret_val = saturate(Remap(percent_height, 0.0, 0.07, 0.0, 1.0));
- // Round top a lot
- float stop_height = saturate(weather + 0.12);
- ret_val *= saturate(Remap(percent_height, stop_height * 0.2, stop_height, 1.0, 0.0));
- // Apply anvil ( cumulonimbus /" giant storm" clouds)
- ret_val = pow(ret_val, saturate(Remap(percent_height, 0.65, 0.95, 1.0, (1 - cloud_anvil_amount * global_coverage))));
- return ret_val;
- }
- float DensityAlter(float coverage, float percent_height, float anvil)
- {
- // Have density be generally increasing over height
- float ret_val = percent_height;
-
- // Reduce density at base
- ret_val *= saturate(Remap(percent_height, 0.0, 0.2, 0.0, 1.0));
- ret_val *= 2;
-
- // Reduce density for the anvil (cumulonimbus clouds)
- ret_val *= lerp(ret_val, saturate(Remap(pow(percent_height, 0.5), 0.4, 0.95, 1.0, 0.2)), 1-anvil);
-
- // Reduce density at top to make better transition
- ret_val *= saturate(Remap(percent_height, 0.9, 1.0, 1.0, 0.0));
- return ret_val;
- }
- // Sample Cloud Density
- float CalculateCloudDensity(float3 pos, float3 PlanetCenter, RaymarchParameters parameters, float2 weather, float mip, float lod, bool details)
- {
- const float baseFreq = 1e-5;
-
- // Get Height fraction
- float height = GetSamplingHeight(pos, PlanetCenter, parameters.cloudsParameter);
- // wind settings
- float cloud_top_offset = 2000.0;
- float3 wind_direction = float3(_CloudsWindDirection.x, 0.0, _CloudsWindDirection.y);
- // skew in wind direction
- pos += height * wind_direction * cloud_top_offset;
- float mip1 = mip + lod;// + dist * _LODDistance;
- float4 coord = float4(pos * baseFreq * parameters.baseNoiseUV, mip1);
- // Animate Wind
- // coord.xyz += float3(_ CloudsWindDirection.z, 0.0f, _CloudsWindDirection.w);
-
- float4 baseNoise = 0;
- baseNoise = _Noise.SampleLevel(sampler_Noise, coord.xyz,coord.w);
- float low_freq_fBm = (baseNoise.g * 0.625) + (baseNoise.b * 0.25) + (baseNoise.a * 0.125);
- float base_cloud = Remap(baseNoise.r, -(1.0 - low_freq_fBm) * parameters.baseErosionIntensity, 1.0, 0.0, 1.0);
- float heightGradient = GradientStep(height, GetHeightGradient(saturate(weather.g * 2.0)));
-
- base_cloud *= heightGradient;
- float cloud_coverage = saturate(1-weather.r);
-
- float densAlter = DensityAlter(cloud_coverage,(1-height * 0.75), parameters.anvilBias);
- cloud_coverage = pow(cloud_coverage, densAlter);
- // cloud_coverage = pow(cloud_coverage, Remap(height, 0.7, 0.8, 1.0, lerp(1.0, 0.5, parameters.anvilBias)));
-
- float cloudDensity = Remap(base_cloud, cloud_coverage, 1.0, 0.0, 1.0);
- cloudDensity = max(cloudDensity * (1-cloud_coverage),0.0);
- //DETAIL
- [branch]
- if (details)
- {
- float mip2 = mip + lod;// + dist * _LODDistance;
- coord = float4(pos * baseFreq * parameters.detailNoiseUV, mip2);
- coord.xyz += float3(_CloudsAnimation.x, _CloudsAnimation.z, _CloudsAnimation.y);
-
- float3 curl_noise1 = _CurlNoise.SampleLevel(sampler_CurlNoise, float2(coord.x * 5,coord.y * 5), 0).rgb;
- coord.xyz += pow(saturate(curl_noise1.rgb),0.1) * parameters.attenuation;// * saturate(height * 10);
-
- float3 detailNoise = _DetailNoise.SampleLevel(sampler_DetailNoise, coord.xyz, coord.w).rgb;
- float high_freq_fBm = (detailNoise.r * 0.625) + (detailNoise.g * 0.25) + (detailNoise.b * 0.125);
- float high_freq_noise_modifier = lerp(high_freq_fBm, 1.0f - high_freq_fBm, saturate(height * 10));
- //float high_freq_noise_modifier = 1.0f - high_freq_fBm;
- cloudDensity = Remap(cloudDensity, high_freq_noise_modifier * parameters.detailErosionIntensity, 1.0, 0.0, 1.0);
- }
-
- return cloudDensity;
- }
- static const float shadowSampleDistance[5] =
- {
- 0.5, 4, 6, 12.0, 48.0
- };
- static const float LightingInfluence[5] =
- {
- 4.0f, 2.0f, 2.0f, 4.0f, 2.0f
- };
- // Lighting Sample Function
- float GetDensityAlongRay(float3 pos, float3 PlanetCenter, RaymarchParameters parameters, float3 LightDirection, float2 weather, float lod)
- {
- float opticalDepth = 0.0;
- int mip_offset = 0.5;
-
- [unroll]
- for (int i = 0; i < 5; i++)
- {
- float stepLength = shadowSampleDistance[i] * (512 * _CloudsLightingExtended.z);
- float3 samplePos = pos + LightDirection * stepLength;
- float sampleResult = CalculateCloudDensity(samplePos, PlanetCenter, parameters, weather, mip_offset, lod, true);
- opticalDepth += LightingInfluence[i] * sampleResult * (stepLength / (i + 1)) ;
- mip_offset += 0.5;
- }
- return opticalDepth * parameters.lightAbsorb;
- }
- float SampleEnergy(float3 pos, float cosTheta, float3 cent, RaymarchParameters parameters, float3 LightDirection, float height, float ds_loded, float step_size, float2 weather, float lod)
- {
- float opticsDistance = GetDensityAlongRay(pos, cent, parameters, LightDirection, weather, lod);
- float result = 0.0f;
- [unroll]
- for (int octaveIndex = 0; octaveIndex < 2; octaveIndex++)
- {
- //Multi scattering approximation based on Frostbite paper.
- float transmittance = exp(-parameters.density * pow(parameters.multiScatteringB, octaveIndex) * opticsDistance);
- float ecMult = pow(parameters.multiScatteringC, octaveIndex);
- float phase = lerp(HenryGreenstein(cosTheta, .5 * ecMult), HenryGreenstein(cosTheta,(0.99 - parameters.silverLiningSpread) * ecMult), 0.5f);
- result += phase * transmittance * parameters.scatteringCoef * 25.0f * pow(parameters.multiScatteringA, octaveIndex);
- }
-
- float powder = 1.0 - exp(-ds_loded * (1-parameters.powderTerm));
- powder = max(lerp(powder * 5, 1, cosTheta * 0.5 + 0.5), 0);
- return result * powder;
- }
- float2 squareUV(float2 uv)
- {
- float width = _Resolution.x;
- float height = _Resolution.y;
- float scale = 500;
- float x = uv.x * width;
- float y = uv.y * height;
- return float2 (x/scale, y/scale);
- }
- /*
- float sampleStart, sampleEnd;
- if (!resolve_ray_start_end(EyePosition, ray, sampleStart, sampleEnd) )
- {
- intensity = 0.0;
- depth = 1e6;
- return 0;
- }
- float3 sampleStartPos = EyePosition + ray * sampleStart;
- if (sampleEnd <= sampleStart || sampleStartPos.y < -200)
- {
- //Below horizon.
- intensity = 0.0;
- depth = 1e6;
- return 0.0;
- }
-
- sampleEnd = min(raymarchEnd, sampleEnd);
- sampleStart = max(0.0, sampleStart);
- float2 hitDistance = float2(sampleStart,sampleEnd);
- */
- float2 ResolveRay(float3 pos, float3 ray, float3 center, float raymarchEnd, RaymarchParameters parameter)
- {
- float2 hDistance;
- float2 ih = 0.0f;
- uint innerShellHits = intersectRaySphere(
- pos,
- ray,
- center,
- parameter.cloudsParameter.w + parameter.cloudsParameter.x,
- ih);
- // find nearest outer shell point
- float2 oh = 0.0f;
- uint outerShellHits = intersectRaySphere(
- pos,
- ray,
- center,
- parameter.cloudsParameter.w + parameter.cloudsParameter.y,
- oh);
- // world space ray intersections
- float3 innerShellHit = pos + (ray * ih.x);
- float3 outerShellHit = pos + (ray * oh.x);
- float2 hitDistance;
- // eye radius from planet center
- float ch = length(pos - center) - parameter.cloudsParameter.w;
- if (ch < parameter.cloudsParameter.x)
- {
- if (ray.y < 0.0)
- return float4(0,0,0,0);
-
- hDistance = float2(ih.x, oh.x);
- }
- else if (ch > parameter.cloudsParameter.y)
- {
- float3 firstShellHit = outerShellHit;
- float3 secondShellHit = outerShellHits == 2u && innerShellHits == 0u ? pos + (ray * oh.y) : innerShellHit;
- float hit2 = outerShellHits == 2u && innerShellHits == 0u ? oh.y : ih.x;
- hDistance = float2(oh.x, hit2);
- }
- else // between shells
- {
- float3 shellHit = innerShellHits > 0u ? innerShellHit : outerShellHit;
- float hit = innerShellHits > 0u ? ih.x : oh.x;
- float height = Remap(pos.y, parameter.cloudsParameter.x, parameter.cloudsParameter.y * 0.75, 0, 1);
- hDistance = ResolveInside(pos.xyz, ray, lerp(25000, 50000, height), parameter);
- }
- hDistance.x = max(0.0, hDistance.x);
- hDistance.y = min(raymarchEnd, hDistance.y);
- hDistance.y = max(0.0, hDistance.y);
- return hDistance;
- }
- float3 Raymarch (float3 cameraPos, float3 ray, float2 hitDistance, float3 center, RaymarchParameters parameters, float offset, int layer)
- {
- float cloud_test = 0.0;
- int zero_density_sample_count = 0;
- float sampled_density_previous = -1.0;
-
- float alpha = 1.0;
- float intensity = 0.0;
- float depth = 0.0;
- float depthWeightSum = 0.000001f;
- float trans = 1.0f;
-
- int steps = (int)lerp(parameters.minSteps, parameters.maxSteps, ray.y);
- // int steps = parameters.maxSteps;
- float rayStepLength = (hitDistance.y - hitDistance.x) / steps;
- float3 rayStep = ray * rayStepLength;
- float3 pos = (cameraPos + (hitDistance.x) * ray);
- pos += (offset * rayStepLength) * ray;
- float3 sampleEndPos = cameraPos + ray * hitDistance.y;
- float eyeToEnd = distance(cameraPos, sampleEndPos);
- float cosTheta = dot(ray, normalize(_LightDir));
-
- [loop]
- for (int i = 0; i < steps; i++)
- {
-
- pos += rayStep;
- //Calculate projection height
- float height = GetSamplingHeight(pos, center, parameters.cloudsParameter);
- //Get out of expensive raymarching
- if (alpha <= 0.01 || height > 1.0 || height < 0.0 || _CloudsCoverageSettings.x <= -0.9)
- break;
-
- // Get Weather Data
- float2 weather;
- if(layer == 0)
- weather = GetWeather(pos).xy;
- else
- weather = GetWeather(pos).zw;
- float dist = Remap(length(pos - cameraPos),0.0,length(sampleEndPos - cameraPos) * _LODDistance * 10.0,0.0,1.0);
- float lod = lerp(0.0,5.0,dist);
- if (cloud_test > 0.0)
- {
- float sampled_density = CalculateCloudDensity(pos, center, parameters, weather, 0, lod, true);
- //float sampled_density_lod = CalculateCloudDensity(pos, center, parameters, weather, 0.5, lod, true) * 0.25;
- if (sampled_density == 0.0 && sampled_density_previous == 0.0)
- {
- zero_density_sample_count++;
- }
- if (zero_density_sample_count < 11 && sampled_density != 0.0)
- {
- float extinction = parameters.density * sampled_density;
- float clampedExtinction = max(extinction, 1e-7);
-
- float transmittance = exp(-extinction * rayStepLength);
- //ds += clampedExtinction * rayStepLength;
- float luminance = SampleEnergy(pos, cosTheta, center, parameters, _LightDir, height, sampled_density * rayStepLength, rayStepLength, weather, lod);
- float integScatt = (luminance - luminance * transmittance);
- float depthWeight = trans;
- depth += depthWeight * length(pos - cameraPos);
- depthWeightSum += depthWeight;
-
- intensity += trans * integScatt;
-
- trans *= transmittance;
- alpha *= max(transmittance, 0.0);
- if (alpha <= 0.01)
- alpha = 0.0;
- }
- // if not, then set cloud_test to zero so that we go back to the cheap sample case
- else
- {
- cloud_test = 0.0;
- zero_density_sample_count = 0;
- }
- sampled_density_previous = sampled_density;
- }
- else
- {
- // sample density the cheap way, only using the low frequency noise
- cloud_test = CalculateCloudDensity(pos, center,parameters, weather, 0, lod, false);
- if (cloud_test == 0.0)
- {
- pos += rayStep;
- }
- else //take a step back and capture area we skipped.
- {
- pos -= rayStep;
- }
- }
-
- }
- float distance = depth / depthWeightSum;
- if (distance == 0.0f)
- {
- distance = length(sampleEndPos - cameraPos);
- }
- alpha = saturate(1.0f - alpha);
-
- return float3(intensity,distance,alpha);
-
- }
- float3 CalculateWorldPosition (float2 uv, float depth)
- {
- float4x4 proj, eyeToWorld;
- if (unity_StereoEyeIndex == 0)
- {
- proj = _LeftViewFromScreen;
- eyeToWorld = _LeftWorldFromView;
- }
- else
- {
- proj = _RightViewFromScreen;
- eyeToWorld = _RightWorldFromView;
- }
- //bit of matrix math to take the screen space coord (u,v,depth) and transform to world space
- float2 uvClip = uv * 2.0 - 1.0;
- float clipDepth = depth; // Fix for OpenGl Core thanks to Lars Bertram
- clipDepth = (UNITY_NEAR_CLIP_VALUE < 0) ? clipDepth * 2 - 1 : clipDepth;
- float4 clipPos = float4(uvClip, clipDepth, 1.0);
- float4 viewPos = mul(proj, clipPos); // inverse projection by clip position
- viewPos /= viewPos.w; // perspective division
- return float3(mul(eyeToWorld, viewPos).xyz);
- }
- float RaymarchShadows (float3 cameraPos, float3 worldPos,float3 ray,float2 hitDistance, float3 center, RaymarchParameters parameters, float offset,float depth, int layer)
- {
- if(depth == 0.0f)
- return 0.0;
- int steps = 16;
- float worldDotLight = saturate(dot(float3(0, 1, 0), _LightDir));
- float bottomDist = max(0, parameters.cloudsParameter.x ) / worldDotLight;
- float topDist = max(0, parameters.cloudsParameter.y ) / worldDotLight;
-
- float rayStepLength = (topDist - bottomDist) / steps;
- float3 rayStep = _LightDir * rayStepLength;
- float3 pos = worldPos + bottomDist * _LightDir;
- float2 weather;
- float intensity = 1.0;
- if(layer == 0)
- {
- weather = GetWeather(pos).xy;
- intensity = 0.05;
- }
- else
- {
- weather = GetWeather(pos).zw;
- intensity = 0.025;
- }
- float shadowIntensity = 0.0;
-
- float _Softness = 2.0f;
- [unroll]
- for (int i = 0; i < steps; i++)
- {
- float3 samplePos = rayStepLength * i * _LightDir + pos;
- float sampleResult = CalculateCloudDensity(samplePos, center, parameters, weather, 0, 0, true) * intensity;
- float result = sampleResult * (rayStepLength / (i + 1));
- shadowIntensity += result;
- // if (shadowIntensity > 0.99)
- // break;
- }
- return (shadowIntensity);
- }
|