# 3d Underwater God Rays

Add volumetric underwater god rays to a Three.js scene, marching one drifting swell...

- Repository: https://github.com/MengTo/Skills (7170 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: yes, review before use

## Install

Claude Code: `npx skills add MengTo/Skills --skill 3d-underwater-god-rays -g -a claude-code -y`
Codex: `npx skills add MengTo/Skills --skill 3d-underwater-god-rays -g -a codex -y`
Cursor: `npx skills add MengTo/Skills --skill 3d-underwater-god-rays -g -a cursor -y`
Gemini CLI: `npx skills add MengTo/Skills --skill 3d-underwater-god-rays -g -a gemini-cli -y`

## Description

Add volumetric underwater god rays to a Three.js scene, marching one drifting swell field along every view ray at half resolution so the light shafts converge on the sun, parallax with the camera and carry rippling caustic streaks, with a shimmering surface underside, a sun that wobbles through the ripples, and the same light dappling fish as they swim through the beams. Use for underwater scenes, oceans seen from below, aquariums, reefs, kelp forests, diving and shipwreck scenes, schools of fish, sunbeams or light shafts through water, caustics, "rays of light shining through the ocean", or watery ripples on a background. Includes a reusable module and the Blue Hour sardine-school demo.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# 3D Underwater God Rays

Use this when the camera is under the water and the light comes down through it. Reach for a sibling instead in these cases:

- **Sun shafts in air, cut by trees and rooflines:** use `3d-sky-rays`. Its screen-space radial blur of an occlusion mask is the right tool there. It cannot parallax or carry ripples, so under water keep it only as a low companion for fish shadows (Blue Hour runs it at 0.25).
- **The ocean surface seen from above, with a horizon:** use `3d-ultra-realistic-water`.
- **Authored shaft planes through one window in a lit interior:** use `3d-wood-lighting-scorecard`.

Source: extracted from **Blue Hour**, the living-ocean wallpaper of a Three.js iPhone Duo study. A school of 2,200 Blender sardines turns behind a glass device. The light had to read as sun through water across the whole 38 s camera dolly and on the device's own screen.

Verified stack: Three.js r170, WebGL2, GLSL `ShaderMaterial`s, one HalfFloat render target, and a hand-written ACES pass. No post-processing library.

## The mechanism

**Sample one drifting swell field across the sun direction, and integrate it along every view ray.** Each point in the water is lit by the swell value at its position measured perpendicular to the sun. The shafts are therefore parallel columns in the world. They converge on the sun the way rails converge on a vanishing point, and they slide past the fish when the camera moves. Paint the same shafts in screen space and they stay locked to the lens.

## Reuse the working effect

Copy [assets/underwater-light.mjs](assets/underwater-light.mjs). You pass in your own `THREE`, and the module does not import a second copy. [The demo](demo/index.html) runs this same module inside Blue Hour's renderer. `demo/build.mjs` rebuilds it from the Blue Hour sources.

```js
import { createUnderwaterLight, LIGHT_GLSL, WATER_GLSL } from './underwater-light.mjs';

The rest: https://github.com/MengTo/Skills/blob/HEAD/agent-skills/3d/3d-underwater-god-rays/SKILL.md
