14.Three.js 中的 SpotLight(聚光灯)详解与 Vue3 实战示例

在 Three.js 中,SpotLight(聚光灯)是一种能沿着一个方向发射锥形光束的光源,广泛应用于舞台灯光、聚焦灯、手电筒等模拟场景中。本文将详细介绍 SpotLight 的各个属性和使用方法,并提供一个基于 Vue3 + Composition API 的完整示例帮助理解。


一、SpotLight 基本介绍

1. 创建方式

const spotLight = new THREE.SpotLight(0xffffff, 1); 
scene.add(spotLight);

构造函数参数:

new THREE.SpotLight(
    color?: ColorRepresentation, 
    intensity?: number, 
    distance?: number, 
    angle?: number, 
    penumbra?: number, 
    decay?: number
)

2. 常用属性解释

属性名作用描述
color光的颜色
intensity光照强度
distance光照最远距离(0表示无限远)
angle聚光灯锥形角度,单位弧度(0 ~ Math.PI/2)
penumbra半影范围(0~1)边缘柔和度
decay衰减系数(默认为 1)
target聚光灯照射目标(默认是 (0,0,0),可设置为任意 Object3D)
castShadow是否投射阴影
shadow光源阴影设置对象(分辨率、模糊度等)


二、SpotLight 相关方法与注意事项

1. 设置光源位置和目标

spotLight.position.set(10, 10, 10); 
spotLight.target.position.set(0, 0, 0); 
scene.add(spotLight.target); // 一定要添加 target

2. 控制阴影效果

spotLight.castShadow = true; 
spotLight.shadow.mapSize.width = 1024; 
spotLight.shadow.mapSize.height = 1024; 
spotLight.shadow.camera.near = 0.5; 
spotLight.shadow.camera.far = 500; 
spotLight.shadow.camera.fov = 30;

3. Helper 可视化工具

const spotLightHelper = new THREE.SpotLightHelper(spotLight); 
scene.add(spotLightHelper); 
// 若动态更新光源参数,需手动调用 update spotLightHelper.update();

三、完整的 SpotLight 示例(非 Vue)

const scene = new THREE.Scene(); 
const light = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.2, 2); light.position.set(10, 20, 10); 
light.castShadow = true; 
scene.add(light); 
light.target.position.set(0, 0, 0); 
scene.add(light.target); 
const helper = new THREE.SpotLightHelper(light); 
scene.add(helper);

四、基于 Vue 3 + Composition API 的 SpotLight 案例

✅ 技术栈

  • Vue 3 + Vite

  • Three.js 0.167.2

  • Composition API + onMounted 生命周期控制

✅ 效果预览

  • 聚光灯照射一个立方体,带阴影

  • 支持窗口自适应

  • 可视化 Helper 显示光照范围

📦 示例组件代码

<!-- SpotLightScene.vue -->
<template>
  <div ref="container" class="w-full h-full"></div>
</template>

<script setup lang="ts">
import * as THREE from 'three'
import { onMounted, ref } from 'vue'

const container = ref<HTMLDivElement | null>(null)

onMounted(() => {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(10, 10, 10)
  camera.lookAt(0, 0, 0)

  const renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.shadowMap.enabled = true
  container.value?.appendChild(renderer.domElement)

  // 地板
  const plane = new THREE.Mesh(
    new THREE.PlaneGeometry(200, 200),
    new THREE.MeshStandardMaterial({ color: 0x999999 })
  )
  plane.rotation.x = -Math.PI / 2
  plane.receiveShadow = true
  scene.add(plane)

  // 立方体
  const cube = new THREE.Mesh(
    new THREE.BoxGeometry(2, 2, 2),
    new THREE.MeshStandardMaterial({ color: 0x00aaff })
  )
  cube.position.y = 1
  cube.castShadow = true
  scene.add(cube)

  // SpotLight
  const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.2, 2)
  spotLight.position.set(10, 15, 10)
  spotLight.castShadow = true
  spotLight.shadow.mapSize.set(1024, 1024)
  spotLight.shadow.camera.near = 1
  spotLight.shadow.camera.far = 100
  scene.add(spotLight)

  // SpotLight Target
  spotLight.target.position.set(0, 0, 0)
  scene.add(spotLight.target)

  // Helper
  const spotHelper = new THREE.SpotLightHelper(spotLight)
  scene.add(spotHelper)

  // 环境光
  scene.add(new THREE.AmbientLight(0x404040))

  // 渲染循环
  const animate = () => {
    requestAnimationFrame(animate)
    renderer.render(scene, camera)
    spotHelper.update()
  }
  animate()

  // 自适应
  window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  })
})
</script>

<style scoped>
html, body, #app {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}
</style>

五、SpotLight 常见问题与调试技巧

  1. 光线没有照射到目标?

    • 检查 target 是否设置并添加到场景中

    • 检查 angle 是否过小

  2. 阴影效果不明显?

    • 调整 shadow.mapSize 提高分辨率

    • 调整 shadow.camera.nearfar 范围

    • 设置 castShadowreceiveShadow 正确

  3. 目标改变位置后光线不更新?

    • 使用 SpotLightHelper.update() 来强制刷新辅助器


六、结语

Three.js 中的 SpotLight 是一个强大而灵活的光源类型,掌握其属性配置与使用技巧对提升 3D 场景表现力至关重要。希望本文的详细讲解和 Vue 示例能帮你更深入地理解它的使用方式。


如果你觉得文章对你有帮助,欢迎点赞、收藏、评论支持!我也会持续分享更多 Three.js 与 Vue 的实战干货 🎉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉檀迦俐

你的鼓励奖是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值