十一、光源和阴影
聚光源SpotLight
聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆锥体。
- 创建聚光源
- 设置聚光光源发散角度
- 设置光线衰弱
.decay生活中聚光源,比如台灯、手电筒之类,随机距离的改变,光线会衰减,越来越弱,.decay默认值是2.0,如果你不希望衰减可以设置为0.0。 - 设置聚光源的位置position
- 设置光源目标对象 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;平行光阴影计算
.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;.castShadow设置产生阴影的光源对象
javascript
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(100, 60, 50);
scene.add(directionalLight);//平行光
// 设置产生阴影的光源对象,开启光源阴影的计算功能
directionalLight.castShadow = true;.receiveShadow设置接收阴影效果的模型
javascript
// 矩形平面网格模型
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotateX(-Math.PI/2);
// 设置接收阴影的投影面
planeMesh.receiveShadow = true;.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;.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;.position调整光源位置(按需调整)
javascript
directionalLight.position.set(100, 60, 50);