Skip to content

十一、光源和阴影

更新: 12/19/2025字数: 0 字阅读: 0 分钟

聚光源SpotLight

聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆锥体。

  1. 创建聚光源
  2. 设置聚光光源发散角度
  3. 设置光线衰弱.decay 生活中聚光源,比如台灯、手电筒之类,随机距离的改变,光线会衰减,越来越弱,.decay默认值是2.0,如果你不希望衰减可以设置为0.0
  4. 设置聚光源的位置position
  5. 设置光源目标对象 target,默认为原点
javascript
// 聚光源
// 0xffffff:光源颜色
// 1.0:光照强度intensity
const spotLight = new THREE.SpotLight(0xffffff,1.0);
scene.add(spotLight);//光源添加到场景中
// 设置聚光光源发散角度
spotLight.angle = Math.PI / 6;//光锥角度的二分之一
spotLight.decay = 0.0;//设置光源不随距离衰减
// 设置聚光光源位置
spotLight.position.set(0, 50, 0);

// spotLight.target是一个模型对象Object3D,默认在坐标原点
spotLight.target.position.set(50,0,0);
//spotLight.target添加到场景中.target.position才会起作用
scene.add(spotLight.target);

聚光源辅助对象SpotLightHelper

javascript
// 聚光源辅助对象,可视化聚光源
const spotLightHelper = new THREE.SpotLightHelper(spotLight, 0xffffff)
scene.add(spotLightHelper);

平行光阴影对象DirectionalLightShadow

阴影相机属性.shadow.camera

  • 平行光DirectionalLight.shadow属性是平行光阴影对象DirectionalLightShadow
  • 平行光阴影对象DirectionalLightShadow有一个相机属性.camera
  • .shadow.camera属性值(正投影相机OrthographicCamera)

CameraHelper可视化.shadow.camera

为了方便观察阴影渲染的范围,可以把平行光对应的阴影相机.shadow.camera可视化显示

javascript
// 可视化平行光阴影对应的正投影相机对象
const cameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(cameraHelper);

设置相机.shadow.camera长方体范围

同正投影相机,可以通过.left.right.top.bottom.near.far属性调整平行光阴影相机的参数(即设置可视化阴影相机的长方体空间)

javascript
// 设置三维场景计算阴影的范围
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 200;
directionalLight.shadow.camera.bottom = -100;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 600;

阴影贴图尺寸属性.mapSize

用于提升边缘渲染效果

mapSize属性默认512x512

如果你的阴影边缘不够清晰,有模糊感、锯齿感,可以适当提升.mapSize属性值。

javascript
// directionalLight.shadow.mapSize.set(128,128);
// 如果阴影边缘锯齿感的时候,可以适当提升像素(尺寸一般2的n次方)
// directionalLight.shadow.mapSize.set(1024,1024);
directionalLight.shadow.mapSize.set(2048,2048);

阴影半径属性.radius

用于弱化模糊阴影边缘

适当提升.shadow.radius,你可以感到阴影边缘与非阴影区域是渐变过渡,或者说阴影边缘逐渐弱化或模糊化,没有很明显的边界感。

javascript
directionalLight.shadow.radius = 3;

阴影条纹问题解决.shadowMap.type

模型表面产生条纹影响渲染效果,可以改变.shadowMap.type默认值优化

javascript
// 模型表面产生条纹影响渲染效果,可以改变.shadowMap.type默认值优化
renderer.shadowMap.type = THREE.VSMShadowMap;

平行光阴影计算

  1. .castShadow设置产生阴影的模型对象
javascript
// 长方体网格模型
const geometry = new THREE.BoxGeometry(50, 100, 50);
const material = new THREE.MeshLambertMaterial({
    color: 0x00ffff,
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.y = 50;

// 设置产生投影的网格模型
mesh.castShadow = true;
  1. .castShadow设置产生阴影的光源对象
javascript
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(100, 60, 50);
scene.add(directionalLight);//平行光

// 设置产生阴影的光源对象,开启光源阴影的计算功能
directionalLight.castShadow = true;
  1. .receiveShadow设置接收阴影效果的模型
javascript
// 矩形平面网格模型
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotateX(-Math.PI/2);

// 设置接收阴影的投影面
planeMesh.receiveShadow = true;
  1. .shadowMap.enabled允许WebGL渲染器渲染阴影
javascript
// WebGL渲染器设置
const renderer = new THREE.WebGLRenderer({
    antialias: true, //开启优化锯齿
});
renderer.setPixelRatio(window.devicePixelRatio); //防止输出模糊
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

// 设置渲染器,允许光源阴影渲染
renderer.shadowMap.enabled = true;
  1. .shadow.camera设置光源阴影渲染范围
javascript
// 设置三维场景计算阴影的范围
directionalLight.shadow.camera.left = -50;
directionalLight.shadow.camera.right = 50;
directionalLight.shadow.camera.top = 200;
directionalLight.shadow.camera.bottom = -100;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 400;
  1. .position调整光源位置(按需调整)
javascript
directionalLight.position.set(100, 60, 50);