光阴影LightShadow
该类作为其他阴影类的基类来使用。这不能直接调用的-它由其他阴影用作基类。但是和灯光阴影相关的大部分属性也能在这里找到!其他的也只是继承的属性和方法。这里我们就试一下常用的设置阴影的几个属性
.radius : Float
影响的是阴影的模糊效果!
gui.add(light.shadow, "radius").name("radius").step(1).min(-100).max(100)
.mapSize : Vector2
一个
Vector2
(二位向量) 定义阴影贴图的宽度和高度(其实就是分辨率啦,分辨率越高阴影的质量就越高!)。较高的值会以计算时间为代价提供更好的阴影质量。默认是512*512
light.shadow.mapSize.set(x, y) // 设置灯光阴影分辨率,越高越真实!
值必须是2的幂,不能超过给定设备的
WebGLRenderer.capabilities.maxTextureSize
console.log('====================================');
console.log(renderer.capabilities.maxTextureSize); // 16384
console.log('====================================');
灯光阴影相机属性及其原理
灯光阴影相机是用来控制灯光阴影计算和渲染的范围的,如果超出了指定的范围,那么就不去计算和渲染阴影,如果部分超出,那么阴影的计算只是部分在范围内的阴影去计算了
我们下面提供了一个在线例子,是一个平行光,你可以控制其中的参数来控制灯光阴影计算的范围
在这个案例中,能用来确认灯光阴影范围的参数有 near,far,top,bottom,left,right
.
light.shadow.camera.near = 0.1
light.shadow.camera.far = 500
light.shadow.camera.top = 500
light.shadow.camera.bottom = 500
light.shadow.camera.left = 500
light.shadow.camera.right = 500
gui.add(light.shadow.camera,"near").min(8).max(1000).onChange(()=>{
light.shadow.camera.updateProjectionMatrix()
})
可以看到在超出某个范围后,阴影就没有了!
完整代码:
import * as THREE from "three"
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls"
import dat from "dat.gui"
const gui = new dat.GUI()
// 场景
const scene = new THREE.Scene()
// 相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000)
camera.position.set(100, 100, 50)
// 渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
//灯光
const light = new THREE.SpotLight(0xfffff0, 1)
light.position.set(100, 50, 200)
light.shadow.radius = 2
light.shadow.mapSize.set(1920, 1920) // 设置灯光阴影分辨率,越高越真实!
light.shadow.camera.near = 0.1
light.shadow.camera.far = 500
light.shadow.camera.top = 500
light.shadow.camera.bottom = 500
light.shadow.camera.left = 500
light.shadow.camera.right = 500
500
// 球体
const sphereGeometry = new THREE.SphereBufferGeometry(30, 100, 100)
// 标准网格材质
const sphereMaterial = new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 0.5,
})
gui.add(light.shadow, "radius").name("radius").step(1).min(-100).max(100)
gui.add(light.shadow.camera,"near").min(8).max(1000).onChange(()=>{
light.shadow.camera.updateProjectionMatrix()
})
//基础材质
// const sphereMaterial = new THREE.MeshBasicMaterial()
const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial)
// 平面
const planeGeometry = new THREE.PlaneBufferGeometry(200.200, 200, 200)
const planeMaterial = new THREE.MeshStandardMaterial({
side: THREE.DoubleSide,
roughness: 0,
metalness: 0.5,
})
const planeMesh = new THREE.Mesh(planeGeometry, planeMaterial)
console.log('====================================');
console.log(renderer.capabilities.maxTextureSize);
console.log('====================================');
renderer.shadowMap.enabled = true
planeMesh.receiveShadow = true
light.castShadow = true
sphereMesh.castShadow = true
// 沿着 x 轴 旋转 90度
planeMesh.rotation.x = Math.PI / 2
// 沿着 y 轴 平移自身半径
sphereMesh.position.y = 30
scene.add(camera)
scene.add(light)
scene.add(sphereMesh)
scene.add(planeMesh)
const spotLightHelper = new THREE.SpotLightHelper(light);
console.log(spotLightHelper);
scene.add(spotLightHelper);
const controls = new OrbitControls(camera, renderer.domElement)
const handleRender = () => {
controls.update
renderer.render(scene, camera)
requestAnimationFrame(handleRender)
}
requestAnimationFrame(handleRender)
评论区