Case Study
Realistic Earth (Three.js + GLSL)
A physically-inspired Earth with day/night blending, cloud masking, ocean-only specular, atmospheric twilight, and a volumetric glow — all in custom GLSL, controlled live with GUI and deployed via GitHub Actions.
The Problem
Render a convincing planet in WebGL without PBR libraries: handle day/night textures, specular highlights limited to oceans, cloud coverage, atmospheric scattering feel, and a separate volumetric atmosphere — all performant and portable to GitHub Pages.
Solution
- Day/Night blend using dot(N, sunDir) → smoothstep remap to mix day.jpg and night.jpg in sRGB.
- Specular only on oceans: reflect(−sunDir, N) • V → pow + mask from specularClouds.jpg (R).
- Clouds from the same texture (G): thresholded smoothstep and multiplied by dayMix so they vanish at night.
- Atmosphere color: mix(dayBlue, twilightOrange) by sun orientation; apply Fresnel vs. view for rim weighting.
- Separate volumetric atmosphere mesh (BackSide) scaled 1.04× with alpha = edgeFresnel × day factor.
- Texture sharpness at grazing angles via anisotropy = 8.
- Robust asset paths using import.meta.env.BASE_URL and Vite base '/THREEjs-earth-shaders/' for Pages.
- CI deploy: build on Actions, upload artifact, and deploy with actions/deploy-pages.
Results
- Interactive globe with live sun controls (phi/theta), smooth day→night transition, and warm twilight rim.
- Portable demo hosted on GitHub Pages with a single push (Actions pipeline).
- Tight bundle for a shader project; loads textures from /static/ with sRGB correctness.
Next
- Animate clouds via subtle UV flow; add perlin displacement for parallax.
- Add starfield / Milky Way env and optional lens flare (assets already in /static/lenses).
- Real-time Earth rotation speed tied to actual sidereal rate; time-of-day lighting control.
- Post-processing pass for bloom and tone-mapped highlights.