
R3f Lighting
- 942 installs
- 105 repo stars
- Updated January 20, 2026
- enzed/r3f-skills
r3f-lighting is a React Three Fiber agent skill that configures physically accurate lights, shadows, and environment maps for developers who need polished 3D scene illumination in @react-three/fiber Canvas components.
About
r3f-lighting is an enzed/r3f-skills agent skill for React Three Fiber lighting setup. It covers light types, shadow configuration, the Environment component for image-based lighting (IBL), and performance-oriented lighting patterns. The quick-start pattern enables shadows on Canvas, adds ambientLight at intensity 0.5, and configures directionalLight with castShadow and shadow-mapSize={[2048, 2048]} on meshes that castShadow and receiveShadow. Developers reach for r3f-lighting when adding lights to a new R3F scene, tuning shadow quality, setting up HDR environment maps, or optimizing lighting performance in Three.js React apps.
- Complete reference for all six core light types with shadow support and performance cost
- Ready-to-copy patterns for ambientLight, directionalLight, pointLight, spotLight and hemisphereLight
- Shadow configuration including mapSize, castShadow and receiveShadow setup
- Environment component and IBL lighting guidance for realistic materials
- Performance-optimized lighting checklist for production 3D experiences
R3f Lighting by the numbers
- 942 all-time installs (skills.sh)
- +38 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #388 of 2,277 Frontend Development skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
npx skills add https://github.com/enzed/r3f-skills --skill r3f-lightingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 942 |
|---|---|
| repo stars | ★ 105 |
| Security audit | 3 / 3 scanners passed |
| Last updated | January 20, 2026 |
| Repository | enzed/r3f-skills ↗ |
How do you add shadows and IBL in React Three Fiber?
Quickly add physically accurate lighting, shadows, and environment maps to any React Three Fiber scene.
Who is it for?
Frontend developers building 3D React apps with @react-three/fiber who need correct light types, shadows, and environment lighting.
Skip if: Developers working in vanilla Three.js without React or who only need 2D CSS lighting effects.
When should I use this skill?
The user adds lights, configures shadows, sets up Environment IBL, or optimizes lighting performance in a React Three Fiber scene.
What you get
Configured R3F scene with typed lights, shadow-casting meshes, environment maps, and performance-tuned illumination.
- Configured light components
- Shadow-enabled meshes
- Environment map setup
By the numbers
- Recommends shadow-mapSize of 2048×2048 for directionalLight shadows
Files
React Three Fiber Lighting
Quick Start
import { Canvas } from '@react-three/fiber'
function Scene() {
return (
<Canvas shadows>
{/* Ambient fill */}
<ambientLight intensity={0.5} />
{/* Main light with shadows */}
<directionalLight
position={[5, 5, 5]}
intensity={1}
castShadow
shadow-mapSize={[2048, 2048]}
/>
{/* Objects */}
<mesh castShadow receiveShadow>
<boxGeometry />
<meshStandardMaterial color="orange" />
</mesh>
{/* Ground */}
<mesh receiveShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.5, 0]}>
<planeGeometry args={[10, 10]} />
<meshStandardMaterial color="#888" />
</mesh>
</Canvas>
)
}Light Types Overview
| Light | Description | Shadow Support | Cost |
|---|---|---|---|
| ambientLight | Uniform everywhere | No | Very Low |
| hemisphereLight | Sky/ground gradient | No | Very Low |
| directionalLight | Parallel rays (sun) | Yes | Low |
| pointLight | Omnidirectional (bulb) | Yes | Medium |
| spotLight | Cone-shaped | Yes | Medium |
| rectAreaLight | Area light (window) | No* | High |
ambientLight
Illuminates all objects equally. No direction, no shadows.
<ambientLight
color="#ffffff" // or color={new THREE.Color('#ffffff')}
intensity={0.5}
/>hemisphereLight
Gradient from sky to ground. Good for outdoor scenes.
<hemisphereLight
color="#87ceeb" // Sky color
groundColor="#8b4513" // Ground color
intensity={0.6}
position={[0, 50, 0]}
/>directionalLight
Parallel light rays. Simulates distant light (sun).
<directionalLight
color="#ffffff"
intensity={1}
position={[5, 10, 5]}
// Shadow configuration
castShadow
shadow-mapSize={[2048, 2048]}
shadow-camera-near={0.5}
shadow-camera-far={50}
shadow-camera-left={-10}
shadow-camera-right={10}
shadow-camera-top={10}
shadow-camera-bottom={-10}
shadow-bias={-0.0001}
shadow-normalBias={0.02}
/>
// With target (light points at target)
function DirectionalWithTarget() {
const lightRef = useRef()
return (
<>
<directionalLight
ref={lightRef}
position={[5, 10, 5]}
target-position={[0, 0, 0]}
/>
</>
)
}pointLight
Emits light in all directions. Like a light bulb.
<pointLight
color="#ffffff"
intensity={1}
position={[0, 5, 0]}
distance={100} // Maximum range (0 = infinite)
decay={2} // Light falloff (physically correct = 2)
// Shadows
castShadow
shadow-mapSize={[1024, 1024]}
shadow-camera-near={0.5}
shadow-camera-far={50}
shadow-bias={-0.005}
/>spotLight
Cone-shaped light. Like a flashlight.
<spotLight
color="#ffffff"
intensity={1}
position={[0, 10, 0]}
angle={Math.PI / 6} // Cone angle (max Math.PI/2)
penumbra={0.5} // Soft edge (0-1)
distance={100} // Range
decay={2} // Falloff
// Target
target-position={[0, 0, 0]}
// Shadows
castShadow
shadow-mapSize={[1024, 1024]}
shadow-camera-near={0.5}
shadow-camera-far={50}
shadow-camera-fov={30}
shadow-bias={-0.0001}
/>
// SpotLight helper
import { useHelper } from '@react-three/drei'
import { SpotLightHelper } from 'three'
function SpotLightWithHelper() {
const lightRef = useRef()
useHelper(lightRef, SpotLightHelper, 'cyan')
return <spotLight ref={lightRef} position={[0, 5, 0]} />
}rectAreaLight
Rectangular area light. Great for soft, realistic lighting.
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper'
function AreaLight() {
const lightRef = useRef()
return (
<>
<rectAreaLight
ref={lightRef}
color="#ffffff"
intensity={5}
width={4}
height={2}
position={[0, 5, 0]}
rotation={[-Math.PI / 2, 0, 0]} // Point downward
/>
</>
)
}
// Note: RectAreaLight only works with MeshStandardMaterial and MeshPhysicalMaterial
// Does not cast shadows nativelyShadow Setup
Enable Shadows on Canvas
<Canvas
shadows // or shadows="soft" | "basic" | "percentage" | "variance"
>Shadow Types
// Basic shadows (fastest, hard edges)
<Canvas shadows="basic">
// PCF shadows (default, filtered)
<Canvas shadows>
// Soft shadows (PCFSoft, softer edges)
<Canvas shadows="soft">
// VSM shadows (variance shadow map)
<Canvas shadows="variance">Configure Shadow-Casting Objects
// Light must cast shadows
<directionalLight castShadow />
// Objects must cast and/or receive shadows
<mesh castShadow receiveShadow>
<boxGeometry />
<meshStandardMaterial />
</mesh>
// Ground typically only receives
<mesh receiveShadow>
<planeGeometry args={[100, 100]} />
<meshStandardMaterial />
</mesh>Shadow Camera Helper
import { useHelper } from '@react-three/drei'
import { CameraHelper } from 'three'
function LightWithShadowHelper() {
const lightRef = useRef()
// Visualize shadow camera frustum
useHelper(lightRef.current?.shadow.camera, CameraHelper)
return (
<directionalLight
ref={lightRef}
castShadow
shadow-camera-left={-10}
shadow-camera-right={10}
shadow-camera-top={10}
shadow-camera-bottom={-10}
/>
)
}Drei Lighting Helpers
Environment
HDR environment lighting with presets or custom files.
import { Environment } from '@react-three/drei'
// Preset environments
<Environment
preset="sunset" // apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse
background // Also use as background
backgroundBlurriness={0} // Background blur
backgroundIntensity={1} // Background brightness
environmentIntensity={1} // Lighting intensity
/>
// Custom HDR file
<Environment files="/hdri/studio.hdr" />
// Cube map (6 images)
<Environment
files={['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']}
path="/textures/cube/"
/>
// Ground projection
<Environment
preset="city"
ground={{
height: 15,
radius: 100,
scale: 100,
}}
/>Lightformer
Create custom light shapes inside Environment.
import { Environment, Lightformer } from '@react-three/drei'
<Environment>
<Lightformer
form="ring" // circle, ring, rect
intensity={2}
color="white"
scale={10}
position={[0, 5, -5]}
target={[0, 0, 0]} // Point at target
/>
<Lightformer
form="rect"
intensity={1}
color="red"
scale={[5, 2]}
position={[-5, 5, 0]}
/>
</Environment>Sky
Procedural sky with sun.
import { Sky } from '@react-three/drei'
<Sky
distance={450000}
sunPosition={[0, 1, 0]} // Or calculate from inclination/azimuth
inclination={0.6} // Sun elevation (0 = horizon, 0.5 = zenith)
azimuth={0.25} // Sun rotation around horizon
turbidity={10} // Haziness
rayleigh={2} // Light scattering
mieCoefficient={0.005}
mieDirectionalG={0.8}
/>Stars
Starfield background.
import { Stars } from '@react-three/drei'
<Stars
radius={100} // Sphere radius
depth={50} // Depth of star distribution
count={5000} // Number of stars
factor={4} // Size factor
saturation={0} // Color saturation
fade // Fade at edges
speed={1} // Twinkle speed
/>Stage
Quick lighting setup for product showcase.
import { Stage } from '@react-three/drei'
<Stage
preset="rembrandt" // rembrandt, portrait, upfront, soft
intensity={1}
shadows="contact" // false, 'contact', 'accumulative', true
environment="city"
adjustCamera={1.2} // Adjust camera to fit content
>
<Model />
</Stage>ContactShadows
Fast fake shadows without shadow mapping.
import { ContactShadows } from '@react-three/drei'
<ContactShadows
position={[0, -0.5, 0]}
opacity={0.5}
scale={10}
blur={1}
far={10}
resolution={256}
color="#000000"
frames={1} // Render once (for static scenes)
/>
// For animated scenes
<ContactShadows frames={Infinity} />AccumulativeShadows
Soft, accumulated shadows.
import { AccumulativeShadows, RandomizedLight } from '@react-three/drei'
<AccumulativeShadows
position={[0, -0.5, 0]}
scale={10}
color="#316d39"
opacity={0.8}
frames={100}
temporal // Smooth accumulation over time
>
<RandomizedLight
amount={8}
radius={4}
ambient={0.5}
intensity={1}
position={[5, 5, -10]}
bias={0.001}
/>
</AccumulativeShadows>SoftShadows
Enable PCF soft shadows globally.
import { SoftShadows } from '@react-three/drei'
<Canvas shadows>
<SoftShadows
size={25}
samples={10}
focus={0}
/>
</Canvas>BakeShadows
Bake shadows for static scenes.
import { BakeShadows } from '@react-three/drei'
<Canvas shadows>
<BakeShadows /> {/* Bakes shadows once on mount */}
</Canvas>Common Lighting Setups
Three-Point Lighting
function ThreePointLighting() {
return (
<>
{/* Key light (main) */}
<directionalLight
position={[5, 5, 5]}
intensity={1}
castShadow
/>
{/* Fill light (softer, opposite side) */}
<directionalLight
position={[-5, 3, 5]}
intensity={0.5}
/>
{/* Back light (rim lighting) */}
<directionalLight
position={[0, 5, -5]}
intensity={0.3}
/>
{/* Ambient fill */}
<ambientLight intensity={0.2} />
</>
)
}Outdoor Daylight
import { Sky, Environment } from '@react-three/drei'
function OutdoorLighting() {
return (
<>
<Sky sunPosition={[100, 100, 100]} />
<Environment preset="dawn" />
<directionalLight
position={[50, 100, 50]}
intensity={1.5}
castShadow
shadow-mapSize={[2048, 2048]}
shadow-camera-far={200}
shadow-camera-left={-50}
shadow-camera-right={50}
shadow-camera-top={50}
shadow-camera-bottom={-50}
/>
<hemisphereLight
color="#87ceeb"
groundColor="#8b4513"
intensity={0.5}
/>
</>
)
}Studio Lighting
import { Environment, Lightformer, ContactShadows } from '@react-three/drei'
function StudioLighting() {
return (
<>
<Environment resolution={256}>
{/* Key light */}
<Lightformer
form="rect"
intensity={4}
position={[5, 5, -5]}
scale={[10, 5]}
target={[0, 0, 0]}
/>
{/* Fill light */}
<Lightformer
form="rect"
intensity={2}
position={[-5, 5, 5]}
scale={[10, 5]}
/>
{/* Rim light */}
<Lightformer
form="ring"
intensity={1}
position={[0, 5, -10]}
scale={5}
/>
</Environment>
<ContactShadows
position={[0, -0.5, 0]}
opacity={0.5}
blur={2}
/>
</>
)
}Animated Lighting
import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'
function AnimatedLight() {
const lightRef = useRef()
useFrame(({ clock }) => {
const t = clock.elapsedTime
// Orbit around scene
lightRef.current.position.x = Math.cos(t) * 5
lightRef.current.position.z = Math.sin(t) * 5
// Pulsing intensity
lightRef.current.intensity = 1 + Math.sin(t * 2) * 0.5
// Color cycling
lightRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
})
return (
<pointLight ref={lightRef} position={[5, 3, 0]} castShadow />
)
}Light Helpers
import { useHelper } from '@react-three/drei'
import {
DirectionalLightHelper,
PointLightHelper,
SpotLightHelper,
HemisphereLightHelper,
} from 'three'
function LightWithHelpers() {
const dirLightRef = useRef()
const pointLightRef = useRef()
const spotLightRef = useRef()
const hemiLightRef = useRef()
useHelper(dirLightRef, DirectionalLightHelper, 5, 'red')
useHelper(pointLightRef, PointLightHelper, 1, 'green')
useHelper(spotLightRef, SpotLightHelper, 'blue')
useHelper(hemiLightRef, HemisphereLightHelper, 5, 'yellow', 'brown')
return (
<>
<directionalLight ref={dirLightRef} position={[5, 5, 5]} />
<pointLight ref={pointLightRef} position={[-5, 5, 0]} />
<spotLight ref={spotLightRef} position={[0, 5, 5]} />
<hemisphereLight ref={hemiLightRef} />
</>
)
}Performance Tips
1. Limit light count: Each light adds shader complexity 2. Use baked lighting: For static scenes 3. Smaller shadow maps: 512-1024 often sufficient 4. Tight shadow frustums: Only cover needed area 5. Disable unused shadows: Not all lights need shadows 6. Use Environment: More efficient than many lights
// Selective shadows
<mesh castShadow={isHero}>
<boxGeometry />
</mesh>
// Only update shadows when needed
<ContactShadows frames={isAnimating ? Infinity : 1} />
// Use layers to exclude objects from lights
<directionalLight layers={1} />
<mesh layers={1}> {/* Affected by light */}
<mesh layers={2}> {/* Not affected */}See Also
r3f-materials- Material light responser3f-textures- Environment mapsr3f-postprocessing- Bloom and light effects
Related skills
How it compares
Use r3f-lighting for scene illumination; pair other r3f-skills for materials, animation, or post-processing.
FAQ
What lights does r3f-lighting configure?
r3f-lighting covers ambientLight for fill, directionalLight as a main shadow-casting source, and Environment-based image-based lighting, with guidance on intensity, position, and shadow-mapSize settings.
How do you enable shadows with r3f-lighting patterns?
r3f-lighting enables shadows on the Canvas element, sets castShadow on directionalLight with shadow-mapSize={[2048, 2048]}, and marks meshes with castShadow and receiveShadow props.
When should developers use r3f-lighting?
r3f-lighting fits new or existing @react-three/fiber scenes when adding lights, tuning shadow quality, loading HDR environment maps, or diagnosing lighting performance issues.
Is R3f Lighting safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.