【Three.js入门】灯光与阴影、平行光阴影属性、聚光灯的属性和应用

简介: 【Three.js入门】灯光与阴影、平行光阴影属性、聚光灯的属性和应用

https://www.bilibili.com/video/BV1hD4y1h7pi?t=1.4

【使用 Three.js 实现的效果】


一、灯光与阴影的关系与设置

灯光阴影:


材质要满足能够对光照有反应

设置渲染器开启阴影计算 renderer.shadowMap.enabled = true

设置光照投射阴影 directionalLight.castShadow = true

设置物体投射阴影 sphere.castShadow = true

设置物体接收阴影 plane.receiveShadow = true

下面的解释与上面的灯光阴影相对应:


.shadowMap 它包含阴影贴图的引用


.castShadow 如果设置为 true 该平行光会产生动态阴影


.castShadow 对象是否被渲染到阴影贴图中


.receiveShadow 材质是否接收阴影


我们先创建一个球体和一个平面,为球体阴影到平面上做准备。之后以上的四步也是缺一不可的(渲染器阴影计算,光照投射阴影,球体投射阴影,平面接收阴影)

// 创建一个球
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20)
// 设置材质
const material = new THREE.MeshStandardMaterial()
// 结合实体和材质
const sphere = new THREE.Mesh(sphereGeometry, material)
// 打开球体的投射阴影
sphere.castShadow = true
// 添加到场景中
scene.add(sphere)
// 创建平面
const planeGeometry = new THREE.PlaneBufferGeometry(10, 10)
const plane = new THREE.Mesh(planeGeometry, material)
plane.position.set(0, -1, 0)
// 正面旋转 90°,调整平面的位置
plane.rotation.x = -Math.PI / 2
// 开启平面接收阴影
plane.receiveShadow = true
scene.add(plane)
// 环境光:均匀的照亮场景中的所有物体
const light = new THREE.AmbientLight(0xffffff, 0.9)
scene.add(light)
// 平行光:方向从一个平行光位置 position 到 target 位置
const directionLight = new THREE.DirectionalLight(0xffffff, 0.95)
// 设置光的位置
directionLight.position.set(10, 10, 10)
// 开启光照投射阴影
directionLight.castShadow = true
scene.add(directionLight)
// 初始化渲染器
const renderer = new THREE.WebGLRenderer()
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true
// 将 webgl 渲染的 canvas 内容添加到 body
document.body.appendChild(renderer.domElement)
......

de2ff999d6a14af0ac644663f43875b7.png

二、平行光阴影属性

1、设置阴影模糊度

.radius 将此值设置为大于 1 的值将模糊阴影的边缘。较高的值会在阴影中产生不必要的条带效果

// 设置阴影贴图模糊度
directionLight.shadow.radius = 20

583c4331a8454bec9f41fa2d49532abb.png

2、阴影贴图

.mapSize 一个 Vector2 定义阴影贴图的宽度和高度。较高的值会以计算时间为代价提供更好地阴影质量。但值必须是 2 的幂,默认值是(512, 512)

// 设置阴影贴图的分辨率
directionLight.shadow.mapSize.set(2048, 2048)

657e370353dc46d39986fce632cdf748.png

3、平行光投射相机的属性

近端,远端,上下左右。当我们改变近端的值时,阴影的大小会相应的发生改变

// 设置平行光投射相机的属性
directionLight.shadow.camera.near = 18.2
directionLight.shadow.camera.far = 500
directionLight.shadow.camera.top = 5
directionLight.shadow.camera.bottom = -5
directionLight.shadow.camera.left = -5
directionLight.shadow.camera.right = 5

33293990f9254782a39f363da4c33037.png

三、聚光灯的属性和应用

聚光灯(SpotLight):光线从一个点沿一个方向射出,随着光线照射的变远,光线圆锥体的尺寸也逐渐增大。

相关属性:

color 十六进制光照颜色,缺省值 0xffffff(白色)

intensity (可选参数)光照强度,缺省值 1

distance 从光源发出光的最大距离,其强度根据光源的距离线性衰减

angle 光线散射角度,最大值为 Math.PI/2

penumbra 聚光锥的半影衰减百分比。在0和1之间的值。默认为 0

decay 沿着光照距离的衰减量

使用聚光灯,改变 target 的位置,通过 GUI 来查看不同距离的显示效果

......
// 聚光灯
const spotLight = new THREE.SpotLight(0xffffff, 0.5)
// 设置光的位置
spotLight.position.set(5, 5, 5)
// 设置阴影贴图模糊度
spotLight.shadow.radius = 20
// 设置阴影贴图的分辨率
spotLight.shadow.mapSize.set(4096, 4096)
// 设置目标
spotLight.target = sphere
// 设置光照投射阴影
spotLight.castShadow = true
scene.add(spotLight)
// 使用 GUI,改变球体在 x 轴的位置,查看投影效果
gui
    .add(spotLight.position, 'x')
    .min(-5)
    .max(5)
    .step(0.1)

de815f3bc69b4b9bb24aaab49fae1b6a.png

733964b1c4d54e618f819a4c4c051484.png

// 设置聚光灯的角度
spotLight.angle = Math.PI / 10

a6b7abe759924519ac441a1022eb8623.png

// 设置从光源发出光的最大距离
spotLight.distance = 0
gui
    .add(spotLight, 'distance')
    .min(0)
    .max(30)
    .step(0.01)

be586da7237d4940b808a95596f140d8.png

// 聚光锥的半影衰减百分比
spotLight.penumbra = 0
gui
    .add(spotLight, 'penumbra')
    .min(0)
    .max(1)
    .step(0.01)

e945ce2505854faea2dffd7fe60bfe89.png

// 设置沿着光照距离的衰减量
spotLight.decay = 0
......
gui
    .add(spotLight, 'decay')
    .min(0)
    .max(5)
    .step(0.01)
......
renderer.physicallyCorrectLights = true

86e74c3ed6764078bcd7fe1df06e0e3e.png

45fc82a82c6542bdb2ff4986377d8db3.png

相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
2月前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
190 77
|
2月前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
128 62
|
9天前
|
JavaScript 前端开发
【JavaScript】——JS基础入门常见操作(大量举例)
JS引入方式,JS基础语法,JS增删查改,JS函数,JS对象
|
2月前
|
存储 缓存 监控
如何使用内存监控工具来优化 Node.js 应用的性能
需要注意的是,不同的内存监控工具可能具有不同的功能和特点,在使用时需要根据具体工具的要求和操作指南进行正确使用和分析。
73 31
|
2月前
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
2月前
|
JavaScript
如何使用内存快照分析工具来分析Node.js应用的内存问题?
需要注意的是,不同的内存快照分析工具可能具有不同的功能和操作方式,在使用时需要根据具体工具的说明和特点进行灵活运用。
51 3
|
2月前
|
Web App开发 JSON JavaScript
Node.js 中的中间件机制与 Express 应用
Node.js 中的中间件机制与 Express 应用
|
2月前
|
JavaScript 前端开发 安全
JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择
本文深入探讨了JavaScript与TypeScript的对比,分析了两者的特性及在实际项目中的应用选择。JavaScript以其灵活性和广泛的生态支持著称,而TypeScript通过引入静态类型系统,提高了代码的可靠性和可维护性,特别适合大型项目。文章还讨论了结合使用两种语言的优势,以及如何根据项目需求和技术背景做出最佳选择。
65 4
|
2月前
|
机器学习/深度学习 人工智能 JavaScript
JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景
本文探讨了JavaScript和TypeScript的未来发展趋势及其在Web开发中的应用前景。JavaScript将注重性能优化、跨平台开发、AI融合及WebAssembly整合;TypeScript则强调与框架整合、强类型检查、前端工程化及WebAssembly的深度结合。两者结合发展,特别是在Vue 3.0中完全采用TypeScript编写,预示着未来的Web开发将更加高效、可靠。
51 4