r3f-lighting

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

React Three Fiber Lighting

React Three Fiber 光照系统

Quick Start

快速开始

tsx
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>
  )
}
tsx
import { Canvas } from '@react-three/fiber'

function Scene() {
  return (
    <Canvas shadows>
      {/* 环境填充光 */}
      <ambientLight intensity={0.5} />

      {/* 带阴影的主光源 */}
      <directionalLight
        position={[5, 5, 5]}
        intensity={1}
        castShadow
        shadow-mapSize={[2048, 2048]}
      />

      {/* 物体 */}
      <mesh castShadow receiveShadow>
        <boxGeometry />
        <meshStandardMaterial color="orange" />
      </mesh>

      {/* 地面 */}
      <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

光照类型概述

LightDescriptionShadow SupportCost
ambientLightUniform everywhereNoVery Low
hemisphereLightSky/ground gradientNoVery Low
directionalLightParallel rays (sun)YesLow
pointLightOmnidirectional (bulb)YesMedium
spotLightCone-shapedYesMedium
rectAreaLightArea light (window)No*High
光源描述阴影支持性能开销
ambientLight全局均匀光照不支持极低
hemisphereLight天空/地面渐变光照不支持极低
directionalLight平行光线(模拟太阳光)支持
pointLight全向光源(模拟灯泡)支持中等
spotLight锥形光源(模拟手电筒)支持中等
rectAreaLight面光源(模拟窗户)不支持*

ambientLight

ambientLight

Illuminates all objects equally. No direction, no shadows.
tsx
<ambientLight
  color="#ffffff"  // or color={new THREE.Color('#ffffff')}
  intensity={0.5}
/>
为所有物体提供均匀光照,无方向,不产生阴影。
tsx
<ambientLight
  color="#ffffff"  // 或 color={new THREE.Color('#ffffff')}
  intensity={0.5}
/>

hemisphereLight

hemisphereLight

Gradient from sky to ground. Good for outdoor scenes.
tsx
<hemisphereLight
  color="#87ceeb"        // Sky color
  groundColor="#8b4513"  // Ground color
  intensity={0.6}
  position={[0, 50, 0]}
/>
模拟天空到地面的渐变光照,适用于户外场景。
tsx
<hemisphereLight
  color="#87ceeb"        // 天空颜色
  groundColor="#8b4513"  // 地面颜色
  intensity={0.6}
  position={[0, 50, 0]}
/>

directionalLight

directionalLight

Parallel light rays. Simulates distant light (sun).
tsx
<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]}
      />
    </>
  )
}
平行光线,模拟远距离光源(如太阳光)。
tsx
<directionalLight
  color="#ffffff"
  intensity={1}
  position={[5, 10, 5]}

  // 阴影配置
  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}
/>

// 带目标点(光源指向目标)
function DirectionalWithTarget() {
  const lightRef = useRef()

  return (
    <>
      <directionalLight
        ref={lightRef}
        position={[5, 10, 5]}
        target-position={[0, 0, 0]}
      />
    </>
  )
}

pointLight

pointLight

Emits light in all directions. Like a light bulb.
tsx
<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}
/>
向所有方向发射光线,模拟灯泡效果。
tsx
<pointLight
  color="#ffffff"
  intensity={1}
  position={[0, 5, 0]}
  distance={100}  // 最大光照范围(0表示无限远)
  decay={2}       // 光照衰减(物理正确值为2)

  // 阴影配置
  castShadow
  shadow-mapSize={[1024, 1024]}
  shadow-camera-near={0.5}
  shadow-camera-far={50}
  shadow-bias={-0.005}
/>

spotLight

spotLight

Cone-shaped light. Like a flashlight.
tsx
<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]} />
}
锥形光线,模拟手电筒效果。
tsx
<spotLight
  color="#ffffff"
  intensity={1}
  position={[0, 10, 0]}
  angle={Math.PI / 6}     // 锥形角度(最大值为Math.PI/2)
  penumbra={0.5}          // 边缘柔化度(0-1)
  distance={100}          // 光照范围
  decay={2}               // 光照衰减

  // 目标点
  target-position={[0, 0, 0]}

  // 阴影配置
  castShadow
  shadow-mapSize={[1024, 1024]}
  shadow-camera-near={0.5}
  shadow-camera-far={50}
  shadow-camera-fov={30}
  shadow-bias={-0.0001}
/>

// SpotLight 辅助工具
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

rectAreaLight

Rectangular area light. Great for soft, realistic lighting.
tsx
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 natively
矩形面光源,可实现柔和、真实的光照效果。
tsx
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]}  // 向下照射
      />
    </>
  )
}

// 注意:RectAreaLight 仅适用于 MeshStandardMaterial 和 MeshPhysicalMaterial
// 原生不支持阴影

Shadow Setup

阴影设置

Enable Shadows on Canvas

在Canvas中启用阴影

tsx
<Canvas
  shadows  // or shadows="soft" | "basic" | "percentage" | "variance"
>
tsx
<Canvas
  shadows  // 或 shadows="soft" | "basic" | "percentage" | "variance"
>

Shadow Types

阴影类型

tsx
// 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">
tsx
// 基础阴影(速度最快,边缘生硬)
<Canvas shadows="basic">

// PCF阴影(默认,带过滤效果)
<Canvas shadows>

// 软阴影(PCFSoft,边缘更柔和)
<Canvas shadows="soft">

// VSM阴影(方差阴影贴图)
<Canvas shadows="variance">

Configure Shadow-Casting Objects

配置阴影投射物体

tsx
// 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>
tsx
// 光源必须开启阴影投射
<directionalLight castShadow />

// 物体必须开启投射和/或接收阴影
<mesh castShadow receiveShadow>
  <boxGeometry />
  <meshStandardMaterial />
</mesh>

// 地面通常仅开启接收阴影
<mesh receiveShadow>
  <planeGeometry args={[100, 100]} />
  <meshStandardMaterial />
</mesh>

Shadow Camera Helper

阴影相机辅助工具

tsx
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}
    />
  )
}
tsx
import { useHelper } from '@react-three/drei'
import { CameraHelper } from 'three'

function LightWithShadowHelper() {
  const lightRef = useRef()

  // 可视化阴影相机视锥体
  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

Drei 光照辅助工具

Environment

Environment

HDR environment lighting with presets or custom files.
tsx
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,
  }}
/>
支持预设或自定义文件的HDR环境光照。
tsx
import { Environment } from '@react-three/drei'

// 预设环境
<Environment
  preset="sunset"  // 可选值:apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse
  background       // 同时作为背景显示
  backgroundBlurriness={0}  // 背景模糊度
  backgroundIntensity={1}   // 背景亮度
  environmentIntensity={1}  // 光照强度
/>

// 自定义HDR文件
<Environment files="/hdri/studio.hdr" />

// 立方体贴图(6张图片)
<Environment
  files={['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']}
  path="/textures/cube/"
/>

// 地面投影
<Environment
  preset="city"
  ground={{
    height: 15,
    radius: 100,
    scale: 100,
  }}
/>

Lightformer

Lightformer

Create custom light shapes inside Environment.
tsx
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>
在Environment中创建自定义形状的光源。
tsx
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]}   // 指向目标点
  />

  <Lightformer
    form="rect"
    intensity={1}
    color="red"
    scale={[5, 2]}
    position={[-5, 5, 0]}
  />
</Environment>

Sky

Sky

Procedural sky with sun.
tsx
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}
/>
带太阳的程序化天空。
tsx
import { Sky } from '@react-three/drei'

<Sky
  distance={450000}
  sunPosition={[0, 1, 0]}   // 或通过倾斜角/方位角计算
  inclination={0.6}         // 太阳高度角(0表示地平线,0.5表示天顶)
  azimuth={0.25}            // 太阳在地平线的旋转角度
  turbidity={10}            // 浑浊度
  rayleigh={2}              // 光散射度
  mieCoefficient={0.005}
  mieDirectionalG={0.8}
/>

Stars

Stars

Starfield background.
tsx
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
/>
星空背景。
tsx
import { Stars } from '@react-three/drei'

<Stars
  radius={100}      // 球体半径
  depth={50}        // 星星分布深度
  count={5000}      // 星星数量
  factor={4}        // 尺寸系数
  saturation={0}    // 色彩饱和度
  fade              // 边缘淡出
  speed={1}         // 闪烁速度
/>

Stage

Stage

Quick lighting setup for product showcase.
tsx
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>
用于产品展示的快速光照设置。
tsx
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}  // 调整相机适配内容
>
  <Model />
</Stage>

ContactShadows

ContactShadows

Fast fake shadows without shadow mapping.
tsx
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} />
无需阴影贴图的快速伪阴影。
tsx
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}        // 仅渲染一次(适用于静态场景)
/>

// 适用于动画场景
<ContactShadows frames={Infinity} />

AccumulativeShadows

AccumulativeShadows

Soft, accumulated shadows.
tsx
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>
柔和的累积阴影。
tsx
import { AccumulativeShadows, RandomizedLight } from '@react-three/drei'

<AccumulativeShadows
  position={[0, -0.5, 0]}
  scale={10}
  color="#316d39"
  opacity={0.8}
  frames={100}
  temporal          // 随时间平滑累积
>
  <RandomizedLight
    amount={8}
    radius={4}
    ambient={0.5}
    intensity={1}
    position={[5, 5, -10]}
    bias={0.001}
  />
</AccumulativeShadows>

SoftShadows

SoftShadows

Enable PCF soft shadows globally.
tsx
import { SoftShadows } from '@react-three/drei'

<Canvas shadows>
  <SoftShadows
    size={25}
    samples={10}
    focus={0}
  />
</Canvas>
全局启用PCF软阴影。
tsx
import { SoftShadows } from '@react-three/drei'

<Canvas shadows>
  <SoftShadows
    size={25}
    samples={10}
    focus={0}
  />
</Canvas>

BakeShadows

BakeShadows

Bake shadows for static scenes.
tsx
import { BakeShadows } from '@react-three/drei'

<Canvas shadows>
  <BakeShadows />  {/* Bakes shadows once on mount */}
</Canvas>
为静态场景烘焙阴影。
tsx
import { BakeShadows } from '@react-three/drei'

<Canvas shadows>
  <BakeShadows />  {/* 在组件挂载时一次性烘焙阴影 */}
</Canvas>

Common Lighting Setups

常见光照设置

Three-Point Lighting

三点布光

tsx
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} />
    </>
  )
}
tsx
function ThreePointLighting() {
  return (
    <>
      {/* 主光源 */}
      <directionalLight
        position={[5, 5, 5]}
        intensity={1}
        castShadow
      />

      {/* 补光(更柔和,位于主光源对面) */}
      <directionalLight
        position={[-5, 3, 5]}
        intensity={0.5}
      />

      {/* 背光(轮廓光) */}
      <directionalLight
        position={[0, 5, -5]}
        intensity={0.3}
      />

      {/* 环境填充光 */}
      <ambientLight intensity={0.2} />
    </>
  )
}

Outdoor Daylight

户外日光

tsx
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}
      />
    </>
  )
}
tsx
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

工作室光照

tsx
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}
      />
    </>
  )
}
tsx
import { Environment, Lightformer, ContactShadows } from '@react-three/drei'

function StudioLighting() {
  return (
    <>
      <Environment resolution={256}>
        {/* 主光源 */}
        <Lightformer
          form="rect"
          intensity={4}
          position={[5, 5, -5]}
          scale={[10, 5]}
          target={[0, 0, 0]}
        />

        {/* 补光 */}
        <Lightformer
          form="rect"
          intensity={2}
          position={[-5, 5, 5]}
          scale={[10, 5]}
        />

        {/* 轮廓光 */}
        <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

动画光照

tsx
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 />
  )
}
tsx
import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'

function AnimatedLight() {
  const lightRef = useRef()

  useFrame(({ clock }) => {
    const t = clock.elapsedTime

    // 环绕场景运动
    lightRef.current.position.x = Math.cos(t) * 5
    lightRef.current.position.z = Math.sin(t) * 5

    // 强度脉动
    lightRef.current.intensity = 1 + Math.sin(t * 2) * 0.5

    // 颜色循环
    lightRef.current.color.setHSL((t * 0.1) % 1, 1, 0.5)
  })

  return (
    <pointLight ref={lightRef} position={[5, 3, 0]} castShadow />
  )
}

Light Helpers

光源辅助工具

tsx
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} />
    </>
  )
}
tsx
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
tsx
// 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 */}
  1. 限制光源数量:每个光源都会增加着色器复杂度
  2. 使用烘焙光照:适用于静态场景
  3. 使用更小的阴影贴图:512-1024通常已足够
  4. 收紧阴影视锥体:仅覆盖需要的区域
  5. 禁用未使用的阴影:并非所有光源都需要阴影
  6. 使用Environment:比多个光源更高效
tsx
// 选择性开启阴影
<mesh castShadow={isHero}>
  <boxGeometry />
</mesh>

// 仅在需要时更新阴影
<ContactShadows frames={isAnimating ? Infinity : 1} />

// 使用图层让物体排除在光源影响外
<directionalLight layers={1} />
<mesh layers={1}>  {/* 受光源影响 */}
<mesh layers={2}>  {/* 不受光源影响 */}

See Also

相关参考

  • r3f-materials
    - Material light response
  • r3f-textures
    - Environment maps
  • r3f-postprocessing
    - Bloom and light effects
  • r3f-materials
    - 材质的光照响应
  • r3f-textures
    - 环境贴图
  • r3f-postprocessing
    - 光晕与光照特效