Looks
A look is a finished setting for a scene’s light. Pick one by name on World, and it sets the following together:
- An HDRI sky that every model’s material takes light and reflections from.
- Fog.
- Exposure.
- A colour grade.
- A post-processing stack.
A game that picks no look draws with the daylight rig alone.
import { LookName, World } from "@daniel-zarinski/engine";
export function DuskScene() { return <World map="meadow" look={LookName.Dusk} />;}| Look | Hour | What it looks like |
|---|---|---|
LookName.Noon |
10 | A clear meadow with the sun high. |
LookName.Morning |
2.4 | A low sun through a light haze. |
LookName.Dusk |
19.3 | A warm sun on the horizon, and a strong glow. |
LookName.Overcast |
10 | Soft light from a grey sky, and close fog. |
The sky and the sun
Section titled “The sky and the sun”Each look’s sky is a 1K HDRI from Poly Haven, about 1.5 MB. It lights the scene’s materials but does not replace the drawn sky. The daylight rig keeps the sky and the light in agreement every frame:
- It clips the image’s own sun, because the rig’s directional light is the sun and casts the shadows. Left in, the image’s sun would light every shadow.
- It turns the image so the image’s sun stands on the rig’s sun.
- It dims the image with the hour, as it dims the hemisphere fill.
- It multiplies the hour’s exposure by the look’s.
- It dims the fog with the light on the ground, the sun and the fill together. The fog keeps the look’s colour at the look’s hour and at any brighter hour, and darkens as the light falls after it, so it never glows past a scene the night has darkened.
A look opens the World on its hour, where the rig’s sun stands near the height of the image’s sun. Pass startHour to open elsewhere. The day clock still runs, so the light follows the hour from there.
Overriding a value
Section titled “Overriding a value”Pass { name, ...values } in place of the name to replace any value of the look. A pass’s settings merge into the look’s, and false drops the pass or the fog:
import { LookName, World } from "@daniel-zarinski/engine";
export function BrightNoonScene() { return ( <World map="meadow" look={{ name: LookName.Noon, exposure: 1.2, bloom: { intensity: 1 }, vignette: false, }} /> );}| Value | What it sets |
|---|---|
| hour | The hour the World opens on. |
| environment | file, the .hdr URL; sunU, the column its sun stands in, 0 to 1; intensity, the light it lends every surface at the sun’s peak. |
| sun | The share of the rig’s sun kept: less under cloud. |
| fill | The share of the rig’s hemisphere fill kept beside the sky’s light. |
| exposure | Multiplies the rig’s exposure for the hour. |
| fog | color, near and far in metres, or false. |
| postProcessing | false keeps the look’s light and fog and mounts no stack, so the game can mount its own <PostProcessing>. |
| bloom | Bloom’s props, or false. |
| ambientOcclusion | AmbientOcclusion’s props, or false. |
| vignette | Vignette’s props, or false. |
| grading | hue in radians, and saturation, brightness and contrast from -1 to 1, applied before tone mapping. 0 leaves the frame as it is. |
Post-processing
Section titled “Post-processing”Picking a look opts the game in to post-processing: World mounts the look’s stack, and the devtools show its passes’ sliders. A scene that mounts its own <PostProcessing> keeps it: the look mounts no stack beside it and logs a warning, so the frame is drawn once. Pass postProcessing: false to keep your own stack without the warning.
Roblox sets a scene’s light with fixed settings on its Lighting service, and Unity and Unreal leave the sky, fog and post-processing volume for the creator to tune. Godot gathers them in one Environment resource. A look is closest to Roblox’s: the creator picks a name and never tunes a stack, and an agent starts from a finished look and changes one value at a time.
A scene without a map
Section titled “A scene without a map”A scene that draws its own ground, such as a track, has no map to hand World. Mount Lighting instead. It sets the same sky, sun, look and stack as World does, over a point you name rather than the player hero:
import { Lighting, LookName } from "@daniel-zarinski/engine";import { Vector3 } from "three";
export function TrackLight() { return ( <Lighting look={LookName.Morning} focus={new Vector3(0, 0, -120)} shadowBox={{ halfWidth: 60, depth: 220 }} /> );}With no day clock in the world, the sun stands at the look’s hour. shadowBox sizes the sun’s shadow box in metres around focus; the default holds a hero’s surroundings.
To keep a painted sky, pass background: an equirectangular image, and sunU, the column its sun stands in from 0 to 1 across. The image is drawn in place of the rig’s sky, turned so its sun stands on the rig’s. It is only drawn; the look’s HDRI still lights the models.
import { Lighting, LookName } from "@daniel-zarinski/engine";import dawn from "./sky-dawn.webp?url";
export function DawnLight() { return ( <Lighting look={LookName.Dusk} background={{ file: dawn, sunU: 0.5 }} /> );}Where it runs
Section titled “Where it runs”Client, except the hour. Headless, World mounts no rig and no stack, but the look’s hour still seeds the day clock, so a simulation opens on the same hour a player sees.