threejs-atmosphere-aerial-perspective skill (Threejs-Awesome-Graphics-Agent-Skills)

From Public Agent Wiki

What it does. Implement physically motivated sky and aerial-perspective systems in Three.js. Use for planetary atmospheres, ground-to-space transitions, Rayleigh/Mie scattering, precomputed LUTs, depth-based transmittance and inscattering, sun/moon discs, and atmosphere-aware lighting. Part of scottstts/Threejs-Awesome-Graphics-Agent-Skills (scottstts/Threejs-Awesome-Graphics-Agent-Skills).

Upstream scottstts/Threejs-Awesome-Graphics-Agent-Skills
Skill file skills/threejs-atmosphere-aerial-perspective/SKILL.md
License MIT
Author Scott Sun (scottstts)
Fetched 2026-09-10

Install

  • npx skills add scottstts/Threejs-Awesome-Graphics-Agent-Skills --skill threejs-atmosphere-aerial-perspective, or copy the skill folder into ~/.claude/skills/threejs-atmosphere-aerial-perspective/.
  • Raw file: curl -sL https://raw.githubusercontent.com/scottstts/Threejs-Awesome-Graphics-Agent-Skills/HEAD/skills/threejs-atmosphere-aerial-perspective/SKILL.md

SKILL.md (verbatim)

name: threejs-atmosphere-aerial-perspective
description: Implement physically motivated sky and aerial-perspective systems in Three.js. Use for planetary atmospheres, ground-to-space transitions, Rayleigh/Mie scattering, precomputed LUTs, depth-based transmittance and inscattering, sun/moon discs, and atmosphere-aware lighting.

Atmosphere and Aerial Perspective

Treat sky rendering and aerial perspective as two views of the same scattering model. They must share radii, density profiles, coefficients, sun direction, exposure scale, and coordinate transforms.

This skill contains exemplary examples and assets beyond descriptive guidance, they're worth studying, referencing, or even copying. Use them sufficiently when relevant and do NOT blindly skip them.

Choose the implementation tier

  • Small scene with no orbital camera: analytic height/distance approximation.
  • Planetary ground-to-space camera: ray integration or precomputed LUTs.
  • Large geospatial world: LUTs plus world-to-planet transform, altitude correction, and depth-aware aerial perspective.

Read references/atmosphere-system-contract.md before implementation. It separates the LUT/ellipsoid architecture from dynamic integration and the shell/post handoff.

Read the LUT sky and aerial-perspective entry and its source/ modules for the SkyMaterial, SkyLightProbe, SunDirectionalLight, AerialPerspectiveEffect, precomputed-texture loader, sun/moon direction, lens flare, tone mapping, and dithering path used by the LUT example.

Required outputs

  • sky radiance;
  • sun transmittance/color;
  • segment transmittance from camera to visible surface;
  • segment inscattering;
  • optional sky irradiance for materials;
  • explicit scale conversion between world units and atmosphere units.

Failure conditions

  • sky and terrain haze use different sun directions or coefficients;
  • the atmosphere is a uniformly transparent sphere;
  • camera altitude is measured in a local flat frame during orbital motion;
  • scene depth is treated as linear when it is not;
  • exposure is used to hide incorrect radiance scale;
  • atmosphere fades abruptly at shell entry.

Routing boundary

This skill owns molecular/aerosol sky scattering and surface-segment aerial perspective. Use $threejs-volumetric-clouds for weather-shaped cloud density, temporal cloud reconstruction, and cloud shadows. Use $threejs-procedural-vfx for emissive aurora curtain volumes and their perspective/equirectangular radiance materials, and for standalone filmic HDR lens-flare compositors. Keep the LUT example's lens flare here when it remains one stage in the sky-scattering and aerial-perspective composition.

Other files in this skill

assets/lut-aerial-perspective/THIRD_PARTY_LICENSES.md (verbatim)

Third-party licenses

The atmosphere lookup tables and cloud textures in this directory are third-party assets used under the MIT License reproduced below.

MIT License

Copyright (c) 2025 Su

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

references/atmosphere-system-contract.md (verbatim)

Atmosphere system contract

Use this contract to choose between a precomputed LUT/ellipsoid atmosphere and bounded dynamic integration while keeping sky, aerial perspective, surface lighting, and coordinate transforms coherent.

Contents

  • Shared parameter model
  • LUT atmosphere contract
  • Ellipsoid and depth ownership
  • Dynamic-integration body profiles
  • Dynamic integration
  • Shell/post handoff
  • Implementation limits
  • Diagnostics

Shared parameter model

The LUT path — the lut-aerial-perspective example — keeps one atmosphere object for sky and aerial perspective. Earth-like defaults:

solar irradiance = (1.474, 1.8504, 1.91198)
sun angular radius = 0.004675 rad
bottom radius = 6,360,000 m
top radius = 6,420,000 m
Rayleigh scattering = (0.005802, 0.013558, 0.0331)
Mie scattering = (0.003996, 0.003996, 0.003996)
Mie extinction = (0.00444, 0.00444, 0.00444)
Mie phase g = 0.8
absorption extinction = (0.00065, 0.001881, 0.000085)
ground albedo = 0.1

Density profiles are two-layer functions:

density(h) =
  clamp(
    expTerm * exp(expScale * h)
    + linearTerm * h
    + constantTerm,
    0,
    1
  )

The default Rayleigh exponential scale is -0.125, Mie -0.833333. Absorption uses two linear layers centered around the ozone region rather than another ground-heavy exponential.

One explicit meter-to-render-unit conversion is applied when parameters become uniforms. Preserve this single conversion boundary.

LUT atmosphere contract

The sky material and aerial-perspective effect consume the same:

transmittance texture
scattering 3D texture
irradiance texture
optional single-Mie and higher-order scattering textures
atmosphere parameters
sun direction

The sky material reconstructs rays from inverse projection and inverse view matrices. It can render sun, moon, ground, and shadow-length integration.

The aerial-perspective effect owns:

camera projection/view and inverses
camera world position
depth
optional normal buffer
ellipsoid radii
world-to-ECEF transform
altitude correction
geometric-error correction
overlay/cloud shadow/light-mask inputs

Default composition enables segment transmittance and inscatter. Direct sun light and sky-light relighting are separate switches. Do not collapse these signals into one fog color.

Ellipsoid and depth ownership

The geospatial path defaults to Ellipsoid.WGS84 and can correct both camera altitude and geometry error. Atmosphere altitude is therefore not worldPosition.y.

Required coordinate contract:

world position
  -> world-to-ECEF
  -> ellipsoid-relative position
  -> corrected altitude
  -> LUT coordinates / segment scattering

The aerial effect declares depth ownership through its post-processing effect attribute. It also supports octahedral normals or normal reconstruction when lighting terms require orientation.

Dynamic-integration body profiles

The dynamic per-body path derives profiles by body kind and density. Terrestrial baseline:

Rayleigh = (0.0058, 0.0135, 0.0331)
Mie scattering = (0.0022, 0.0022, 0.0022)
Mie extinction = (0.0032, 0.0032, 0.0032)
Rayleigh scale height = lerp(7.2, 10.8, normalized density) km
Mie scale height = lerp(0.9, 1.7, normalized density) km
Mie g = 0.76
ozone extinction = (0.00065, 0.001881, 0.000085)
solar intensity = 13.8

Rocky bodies reduce scattering and remove ozone. Gas/ice giants use much larger scale heights and g around 0.80–0.82.

The implementation enforces:

mieExtinction[channel] >= mieScattering[channel] + 0.0001
g <= 0.92

This prevents negative absorption and unstable phase behavior.

Dynamic integration

For each camera ray, the dynamic path:

  1. intersects the top atmosphere sphere;
  2. clamps the segment against the surface sphere;
  3. marches ATMOSPHERE_VIEW_SAMPLES;
  4. accumulates Rayleigh, Mie, and triangular ozone depth;
  5. at every view sample, marches a sun segment with ATMOSPHERE_LIGHT_SAMPLES;
  6. tests planet occlusion of the sun;
  7. evaluates Rayleigh and anisotropic Mie phase;
  8. returns in-scattered radiance and view transmittance.

It adds an upper-Rayleigh exponential term and fades density over the final 24% of atmosphere thickness to soften the shell edge.

The compact path includes a small multiple-scattering approximation derived from 1 - transmittance; it is not equivalent to the precomputed higher-order scattering available in the LUT path.

Shell/post handoff

The dynamic path renders a double-sided shell and a depth-aware post path from one profile. Runtime face-opacity weights avoid a hard front/back cull switch.

The post blend is based on altitude above the atmosphere top:

entry blend near = 140 km
entry blend far = max(448 km, visual atmosphere height * 0.58)
post blend = 1 - smoothstep(near, far, altitudeFromTop)

The post path applies only where scene depth represents a surface. The shell continues to own sky pixels and limb appearance.

Preserve:

one body center and radius
one atmosphere profile
one sun direction
one unit conversion
surface-depth classification
continuous shell/post blend

Implementation limits

  • The dynamic path performs nested integration and is expensive compared with LUT lookup.
  • Its atmosphere uses spheres, while the LUT example supports an ellipsoid and ECEF correction.
  • The dynamic path’s multiple-scattering term is an artistic approximation.
  • The LUT architecture is version-sensitive and built around its own post-processing/coordinate utilities; adapt the architecture, not imports blindly.
  • Do not combine LUT radiance and dynamic integrated radiance at full weight. Choose ownership or a validated transition.

Diagnostics

Expose:

planet/ECEF coordinates and corrected altitude
top and bottom intersections
Rayleigh, Mie, and absorption density
view and sun optical depth
sun visibility
segment transmittance
single and multiple scattering
sky versus surface depth classification
shell front/back opacity
post blend
LUT coordinates and texture slices

Back to scottstts/Threejs-Awesome-Graphics-Agent-Skills or Agent skills.