目 录CONTENT

文章目录

光阴影属性与灯光阴影相机属性及其原理

Hello!你好!我是村望~!
2022-08-14 / 0 评论 / 0 点赞 / 355 阅读 / 908 字
温馨提示:
我不想探寻任何东西的意义,我只享受当下思考的快乐~

光阴影LightShadow

three.js

该类作为其他阴影类的基类来使用。这不能直接调用的-它由其他阴影用作基类。但是和灯光阴影相关的大部分属性也能在这里找到!其他的也只是继承的属性和方法。这里我们就试一下常用的设置阴影的几个属性

.radius : Float

影响的是阴影的模糊效果!

gui.add(light.shadow, "radius").name("radius").step(1).min(-100).max(100)

1-1660449410570

.mapSize : Vector2

一个 Vector2 (二位向量) 定义阴影贴图的宽度和高度(其实就是分辨率啦,分辨率越高阴影的质量就越高!)。较高的值会以计算时间为代价提供更好的阴影质量。默认是512*512

light.shadow.mapSize.set(x, y) // 设置灯光阴影分辨率,越高越真实!

image-1660449917913

值必须是2的幂,不能超过给定设备的 WebGLRenderer.capabilities.maxTextureSize

console.log('====================================');
console.log(renderer.capabilities.maxTextureSize); // 16384
console.log('====================================');

灯光阴影相机属性及其原理

灯光阴影相机是用来控制灯光阴影计算和渲染的范围的,如果超出了指定的范围,那么就不去计算和渲染阴影,如果部分超出,那么阴影的计算只是部分在范围内的阴影去计算了

我们下面提供了一个在线例子,是一个平行光,你可以控制其中的参数来控制灯光阴影计算的范围

在这个案例中,能用来确认灯光阴影范围的参数有 near,far,top,bottom,left,right .

如果上面在线例子显示不出来的话,可以靠着这个gif图片简单理解一下!可以看到平行光的阴影相机范围参数变化过程!

1-1660450082722

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()
})

1-1660450144626

可以看到在超出某个范围后,阴影就没有了!

完整代码:

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)
0

评论区