three.js源码翻译-SpotLightShadow.js
说明
SpotLightShadow类是聚光灯光的阴影,SpotLightShadow的创建可以在SpotLightShadow的源码翻译部分看到,总体来说就是创建了一个透视摄像机传到LightShadow中去,默认参数投影出的效果差不多,但是同样的要更加真实的话,还是要自己设置参数。
源码位置及翻译
源码位置
src/light/SpotLightShadow.js
源码翻译
function SpotLightShadow() {
LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
}
SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
constructor: SpotLightShadow,
isSpotLightShadow: true,
//点光源和方向光源阴影不同有,点光源使用了透视摄像机,并且重写了update方法
update: function ( light ) {
//只是对透视相机做的一般处理,因为阴影的基类使用的是正交投影
var camera = this.camera;
var fov = _Math.RAD2DEG * 2 * light.angle;
var aspect = this.mapSize.width / this.mapSize.height;
var far = light.distance || camera.far;
if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
camera.fov = fov;
camera.aspect = aspect;
camera.far = far;
camera.updateProjectionMatrix();
}
}
} );
示例及案例
创建
let sphere = new THREE.SphereBufferGeometry(1, 16, 16);
let spotLight = new THREE.SpotLight(0xffff00, 2.0, 150);
spotLight.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xff00ff })));
spotLight.position.y = 100;
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 10;
spotLight.shadow.camera.far = 150;
spotLight.shadow.camera.fov = 45;
scene.add(spotLight);
spotLight.target = ground;
scene.add(spotLight.target);
注意的点
- spot光源为啥有单独的文件呢,就是因为他的update方法和基类Shadow不一样,所以重写了一下。
- 需要将光源的.castShadow设置为true,同时需要将接受阴影的mesh的.receiveShadow设置为true,然后还有渲染器中的.shadowMap.enabled也要设置为true。表格如下
操作物体/属性 | 光源(eg:THREE.DirectionalLight) | 接受阴影的物体(THREE.Mesh) | 渲染器(THREE.WebGLRenderer) |
---|---|---|---|
.castShadow | ✅ Yes | ||
.receiveShadow | ✅ Yes | ||
.shadowMap.enabled | ✅ Yes |