component
LightRig
Sun + hemisphere/ground fill with shadow configuration.
⌖ Explore the library in 3D → · View as Markdown
Lighting system — lights a whole scene rather than an object.
Add it
npx @runek/cli add lightrig
Pulls @runek/core@^0.15.0, three@^0.184.0.
Use it
import { LightRig } from './runek/LightRig'
<LightRig position={[0, 0, 0]} />
Or as a node in a world file (worlds as data):
{ "type": "LightRig", "props": { "position": [0, 0, 0] } }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
seed |
number |
Accepted for the component contract; this component has no seeded variation yet. | |
sunPosition |
[x, y, z] |
||
sunColor |
color |
||
sunIntensity |
number |
||
ambient |
number |
||
skyColor |
color |
"#bcd4ff" |
|
groundColor |
color |
"#4a4030" |
|
shadows |
boolean |
true |
|
shadowRange |
number |
30 |
Half-extent of the shadow camera frustum, in units. |
Registry manifest
registry manifest /r/components/lightrig.json Self-contained JSON: inlined source plus resolved dependencies, exactly whatrunek add lightrig fetches.
Browse the whole catalog in the gallery →.
Source (LightRig.tsx)
import { useSun, type Vec3 } from '@runek/core'
import { Color } from 'three'
export interface LightRigProps {
/** Accepted for the component contract; this component has no seeded variation yet. */
seed?: number
sunPosition?: Vec3
sunColor?: string
sunIntensity?: number
ambient?: number
skyColor?: string
groundColor?: string
shadows?: boolean
/** Half-extent of the shadow camera frustum, in units. */
shadowRange?: number
}
// Sun tint across the day: warm at the horizon, near-white at noon, cool moonlight at night.
const NOON = new Color('#fff4e0')
const HORIZON = new Color('#ff9a55')
const MOON = new Color('#9fb2e6')
function sunTint(day: boolean, elevation: number): string {
if (!day) return `#${MOON.getHexString()}`
return `#${HORIZON.clone().lerp(NOON, elevation).getHexString()}`
}
/**
* A drop-in sun + sky/ground fill rig. Pair with `<World lights={false}>`. With no
* explicit sun props it tracks the world's time-of-day: the sun's position, tint,
* and intensity follow `<World time>` / `timezone` (golden hour, blue hour, dim
* moonlight). Any prop you set wins over the time-derived value.
*/
export function LightRig({
sunPosition,
sunColor,
sunIntensity,
ambient,
skyColor = '#bcd4ff',
groundColor = '#4a4030',
shadows = true,
shadowRange = 30,
}: LightRigProps) {
const sun = useSun()
const e = sun.elevation
const position = sunPosition ?? sun.position
const color = sunColor ?? sunTint(sun.day, e)
const intensity = sunIntensity ?? (sun.day ? 0.3 + 1.4 * e : 0.08)
const amb = ambient ?? (sun.day ? 0.18 + 0.22 * e : 0.1)
const hemiIntensity = sun.day ? 0.25 + 0.45 * e : 0.15
return (
<>
<hemisphereLight color={skyColor} groundColor={groundColor} intensity={hemiIntensity} />
<ambientLight intensity={amb} />
<directionalLight
position={position}
color={color}
intensity={intensity}
castShadow={shadows}
shadow-mapSize={[2048, 2048]}
shadow-camera-near={1}
shadow-camera-far={120}
shadow-camera-left={-shadowRange}
shadow-camera-right={shadowRange}
shadow-camera-top={shadowRange}
shadow-camera-bottom={-shadowRange}
/>
</>
)
}