Skip to content

Commit

Permalink
beginning of gas giant clouds
Browse files Browse the repository at this point in the history
  • Loading branch information
wellcaffeinated committed Feb 14, 2024
1 parent 8ad660f commit 4325d8a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/components/DebugControls.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
const cloudSettings = atmosSettings.addFolder('Clouds')
cloudSettings.add(state, 'cloudZ', 0.01, 0.9, 0.01)
cloudSettings.add(state, 'cloudThickness', 0, 20, 0.1)
cloudSettings.add(state, 'cloudSize', 0, 10, 0.1)
cloudSettings.add(state, 'cloudSize', 0, 10, 0.01)
cloudSettings.add(state, 'cloudMie', 0, .999, 1e-7)
cloudSettings.add(state, 'cloudThreshold', 0, 1, 0.01)
cloudSettings.add(state, 'cloudAbsorption', 0, 1, 0.01)
Expand Down
6 changes: 5 additions & 1 deletion src/entities/Uranus.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<script>
import { DoubleSide, RingGeometry, TextureLoader, Vector3 } from 'three'
import { Color, DoubleSide, RingGeometry, TextureLoader, Vector3 } from 'three'
import { T, useLoader } from '@threlte/core'
import textureUrl from '../assets/uranus/uranusmap.jpg'
import ringTextureUrl from '../assets/uranus/uranusringcolor.jpg'
import ringOpacityUrl from '../assets/uranus/uranusringtrans.gif'
import { useSuspense } from '@threlte/extras'
import { altitude, atmosphereThickness } from '../store/environment'
export let planetRadius = 1
export let position = [0, 0, 0]
Expand All @@ -28,6 +29,8 @@ const textures = suspend(useLoader(TextureLoader).load({
ring: ringTextureUrl,
ringOpacity: ringOpacityUrl,
}))
$: colorFade = new Color(0x000000).lerp(new Color(0xffffff), Math.min(1, $altitude / $atmosphereThickness))
</script>

{#if $textures}
Expand All @@ -45,6 +48,7 @@ const textures = suspend(useLoader(TextureLoader).load({
map={$textures.map}
shininess={0}
fog={false}
color={'#' + colorFade.getHexString()}
/>
</T.Mesh>
<!-- rings -->
Expand Down
27 changes: 22 additions & 5 deletions src/shaders/sky/fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ vec3 opticalDensity(float x) {
exp(-x / vec2(rayleighScaleHeight, mieScaleHeight)),
opticalDensityTent(x, ozoneLayerHeight, ozoneLayerWidth)
),
0., 1.);
0., 5.);
}

// optical depth from start to end in the atmosphere
Expand Down Expand Up @@ -465,7 +465,8 @@ vec4 scattering(
// We can reduce the number of atmospheric samples required to converge by spacing them exponentially closer to the camera.
// This breaks space view however, so let's compensate for that with an exponent that "fades" to 1 as we leave the atmosphere.
float observerHeight = length(rayOrigin) - planetRadius;
float sampleDistributionExponent = 1. + 8. * clamp(1. - observerHeight / atmosphereThickness, 0., 1.);
float factor = planet_intersected ? 0. : 8.;
float sampleDistributionExponent = 1. + factor * clamp(1. - observerHeight / atmosphereThickness, 0., 1.);
float prevRayT = 0.0;

for (int i = 0; i < steps.x; i++){
Expand Down Expand Up @@ -515,23 +516,39 @@ vec4 scattering(
float cloudAmount = 0.0;
vec3 cloud = vec3(0.0);
float cloudAbsorptionAmount = 0.0;
if (!intersectsOutside(intPlanet) && cloudThickness >= 0.1){
if (!intersectsOutside(intPlanet) && cloudThickness >= 0.01){
float cloudHeight = cloudZ * atmosphereThickness;
vec2 cloudInt = raySphereIntersection(rayOrigin, rayDir, planetRadius + cloudHeight);
if (intersectsInsideOnly(cloudInt)){
float cloudPhase = miePhase(mu, cloudMie);
vec3 cloudPoint = rayOrigin + cloudInt.y * rayDir;
vec2 planetInt = raySphereIntersection(cloudPoint, sSun, planetRadius);
float cloudMinBrightness = mix(1e-5, 0., remap(planetInt.y - abs(planetInt.x), 0., 0.03 * planetRadius, 0., 1.));
vec3 cloudLayer = cloudSize * 900. * (rayDir * (cloudInt.y + 0.2 * atmosphereThickness)) / atmosphereRadius;
vec3 cloudLayer = cloudSize * 900. * cloudPoint / atmosphereRadius;
cloudAmount = cloudThickness * smoothstep(0., 1.0, fbm(cloudLayer + windSpeed * time) - cloudThreshold);
// float cloudAmount = 2. * getPhases(rayDir, sSun, 0.5 + 0.4 * fbm(cloudLayer * 20.)).y;
cloudAbsorptionAmount = clamp(cloudAbsorption * cloudAmount, 0., 1.);
// cloud = 1e-6 * I0 * cloudAmount * cloudPhase * rayleighT;
cloud = I0 * clamp(0.1 * cloudAmount * max(length(mieCoefficients) * (cloudPhase + (1. - cloudAbsorptionAmount) * phases.x), cloudMinBrightness) * rayleighT, 0., 1.);
cloud = I0 * clamp(0.1 * cloudAmount * max(10. * (mieCoefficients) * (cloudPhase + (1. - cloudAbsorptionAmount) * phases.x), cloudMinBrightness) * (rayleighT + mieT), 0., 1.);
}
}

// clouds below for gas giants
if (planetRadius > 5e6 && planet_intersected){
float cloudPhase = miePhase(mu, cloudMie);
vec3 cloudPoint = rayOrigin + path.y * rayDir;
cloudPoint += 20. * cnoise3(cloudPoint / planetRadius);
vec2 planetInt = raySphereIntersection(cloudPoint, sSun, planetRadius - 1.);
float cloudMinBrightness = mix(1e-5, 0., remap(planetInt.y - abs(planetInt.x), 0., 0.03 * planetRadius, 0., 1.));
vec3 cloudLayer = cloudSize * 4000. * cloudPoint / atmosphereRadius;
cloudAmount = cloudThickness * smoothstep(0., 1.0, fbm(cloudLayer + windSpeed * time + 10.) - cloudThreshold);
// fade as we get higher
float k = remap(length(rayOrigin) - planetRadius, 0., atmosphereThickness, 0., 1.);
cloudAmount = mix(cloudAmount, 0., k);
cloudAbsorptionAmount = clamp(cloudAbsorption * cloudAmount, 0., 1.);
cloud = I0 * clamp(0.1 * cloudAmount * max(10. * (mieCoefficients) * (cloudPhase + (1. - cloudAbsorptionAmount) * phases.x), cloudMinBrightness) * (rayleighT + mieT), 0., 1.);
}

// final scattering
vec3 scatter = I0 * rayleighT * phases.x * rayleighCoefficients + I0 * mieT * phases.y * mieCoefficients;
// scatter = clamp(scatter, vec3(0.0), vec3(I0)) / sqrt(fsteps);
Expand Down

0 comments on commit 4325d8a

Please sign in to comment.