Skip to content

Reflections

Reflective materials can sample a SkyEnvironment, an equirectangular RGBA16F texture containing the current sky and clouds.

This guide covers setup, performance, capture position, and limitations.

Setup

For Water Pro specifically, use the integrated path:

typescript
water.setSky(sky.createSkyProvider({ envMap: true }));

For anything else, bake an env map manually and sample it via the equirectUVFromDir TSL helper:

typescript
import { equirectUVFromDir } from "threejs-sky-pro";
import { texture } from "three/tsl";

const env = sky.createEnvironmentMap({ width: 512 });

// Inside the reflective material's TSL colorNode:
const skyReflection = texture(env.texture, equirectUVFromDir(reflectDir));

function animate() {
  sky.update(dt);
  env.update();
  postProcessing.render();
}

What Gets Baked

  • The atmospheric sky dome (sun disc, scattering, moon disc + ambient lift at night).
  • Volumetric clouds and high haze when includeClouds: true (the default). Cirrus is included after a mask is supplied with env.setCirrusTexture(texture).
  • The night-sky panorama (stars / Milky Way) at night, when a nightSky is configured. Turn it off with env.bakeNightSky = false.

God rays are not baked into the env map.

Performance Settings

SettingDefaultDescription
width384Texture width. Larger values improve detail and increase cost with pixel count.
heightwidth / 2Equirect height in pixels.
cloudMarchSteps16Cloud raymarch steps for the bake (independent of the screen pipeline).
cloudMipBase0Base mip level for cloud noise. Higher values are softer and less expensive.
includeCloudstrueSet false for sky-only reflections (drops the cloud raymarch entirely).
skipFrames4Skip this many update() calls between volumetric-cloud raymarches. Thin cirrus/haze stays live.
initialBaketrueSet false to defer construction-time work until update() or bakeAll().

Use skipFrames, texture resolution, and cloudMarchSteps to control the volumetric-cloud cost. Animated cirrus/haze is a separate inexpensive pass and remains current at every update() where it moves.

Capture Position

The environment map is captured from origin, which defaults to the world origin. Set it at construction or with env.setOrigin(v).

For a horizontal mirror like a water plane, pin Y to the water surface and let X / Z follow the camera:

typescript
env.setOrigin(new THREE.Vector3(camera.position.x, WATER_Y, camera.position.z));

For a flat reflector, capture from the surface because reflection rays originate there. Following the camera's Y position can move the capture point into the cloud layer and produce incorrect reflections.

For general PBR materials, place origin near the primary reflective objects. A single environment map cannot provide accurate parallax for widely separated reflectors.

Configuration Examples

Low-cost, mostly static scene

typescript
sky.createEnvironmentMap({
  width: 256,
  cloudMarchSteps: 16,
  skipFrames: 8,
});

Day/night cycle, sun moving constantly

typescript
sky.createEnvironmentMap({
  width: 512,
  cloudMarchSteps: 24,
  skipFrames: 0,
});

High-quality water

typescript
sky.createEnvironmentMap({
  width: 1024,
  cloudMarchSteps: 32,
  skipFrames: 0,
});

Force an Immediate Refresh

After a preset change or large sun movement, update the environment map immediately instead of waiting for the next scheduled bake:

typescript
env.bakeAll();

Limitations

  • No built-in roughness filtering. Raw texture() sampling does not provide a roughness mip chain. Use a prefiltering step for glossy PBR reflections.
  • Lower resolution than screen. 512×256 is much coarser than a 1080p framebuffer — reflections look softer than the on-screen sky.
  • Single capture point. One env map can't satisfy multiple reflective surfaces in different parts of a scene with different parallax expectations.
  • No god rays in reflections. God rays are a screen-space effect and are not included.
  • Polar pixels compress. Standard equirect collapses the top and bottom rows to a single direction. The sun disc is baked into the texture, so at low resolutions its shape softens along with the rest of the sky.

See Also

Commercial License - All Rights Reserved.