阳光和阴影效果要怎么在threejs中应用
前言
这篇文章实现智慧城市中模拟太阳光随时间变化产生对应场景效果。为了场景能够更逼真,我们一般会通过对接天气以及阳光等各种环境因素同步到场景中,使得场景能够更贴近现实。比如一些常见的天气系统,下雨、下雪、阴天、雾霾等,我之后会独立一篇文章中提现。这边文章主要介绍一系列灯光,主要是平行光对于太阳的模仿,以及一些材质的问题~
灯光与材质基础篇
常见的灯光:
- 点光源 (点光源可以理解为一个同时向四面八方散发光线,我们通常用来模拟灯泡,可以产生阴影)
- 平行光 (平行光可以想象成一个从无限远照射来的光束,通常用来模拟太阳光,可以产生阴影)
- 聚光灯 (聚光灯字面意思就是类似舞台灯光一样,照射突出特定圆弧形范围,可以产生阴影)
- 环境光 (一般用于改变整体场景的亮度,也是最常用的光源之一)
这里提一嘴材质:(仅仅列举常用的)
- 网格基础材质(meshbasicmaterial,不支持阴影)
- fbr材质
- 物理标准材质(meshstandardmaterial)
- meshphysicalmaterial
- 以上两者fbr材质相对于高光网格材质效果更好
- meshphongmaterial(高光网格材质,高亮表面、镜面反射)
- meshlambertmaterial(网格lambert材质,暗淡,漫反射)
这里简单做一下介绍,不懂的同学可以具体去了解某个材质
太阳光
添加平行光-----从东至西调整位置-----调整亮度以及颜色-----添加过渡模拟太阳光
接下来介绍本文的重点,如何模拟太阳光照的变化。其实原理非常简单,就是添加平行光,调整场景模型的阴影关系,根据时间实时变化平行光的位置以及光照强度以及颜色即可模拟~
整体调用代码
由于是一个demo,所以注重效果,一切从简实现功能
sun() { //两秒变化一次平行光 let i=0 setinterval(()=> { this.initsun(i) i++ } ,2000) }
简单实现通过定时器以及提前写好对应位置光照的信息。主要是思想,酌情根据自己的需求可以改变~
这里这么写主要是实现效果,真实的应该根据系统时间将太阳光做出调整,包括根据天气原因,换汤不换药,主要还是
手动调整并存储为json通过传入时间以及天气去做出转化~
viewer.prototype.initsun = function (type) { let position = { } let color = '#ffffff' let intensity = 1 switch (type) { case 0: position = { x: 270, y: 150, z: 0 } intensity = 5 break case 1: position = { x: 258, y: 170, z: 0 } intensity = 7 color = '#fcffc9' break case 2: position = { x: 245, y: 180, z: 0 } intensity = 10 color = '#ffe69f' break case 3: position = { x: 0, y: 100, z: 0 } intensity = 15 color = '#ffe69f' break case 4: position = { x: -245, y: 180, z: 0 } intensity = 10 color = '#e3894d' break case 5: position = { x: -258, y: 160, z: 0 } intensity = 10 color = '#ff8400' break default : position = { x: -270, y: 150, z: 0 } intensity = 8 color = '#ff8400' break } if (this.directionallight) { this.directionallight.setsun(position,color,intensity) } else { this.directionallight = new zhdsun() this.directionallight.renderfn(this.renderfunction) this.directionallight.init({ position, color, intensity, scene: this.scene, currentlayers: this.currentlayers } ) } }
太阳光类
这里主要对太阳光类的拆解与分析,封装的比较粗糙,酌情个人可以优化
import tween from '@tweenjs/tween.js' import { zhdobject} from './zhdobject' export class zhdsun extends zhdobject { constructor() { super() this.light = null } } //由于添加了tween动画库,记得在animate中实时更新tween tween.update()
初始化
这里做的是向场景中添加平行光,设置其阴影的范围以及距离等属性,因为我这边涉及层级,所以设置了平行光的层级
平行光可谓是所有灯光中阴影调整最麻烦的,想要平行光能够产生对的阴影效果,模型的产生阴影以及接收阴影要调整好,并且平行光的照射范围也要调整好。我效果图中不知大家有没有发现,在正午时刻的时候太阳光照射地面产生了一个长方形的范围阴影,这里是特地录制一个相对不那么完美的版本。
产生原因:平行光范围太小,但是一旦你调整平行光范围过大,由于地面是通过多个瓦片加载的,就会出现条纹状的阴影
如下图
解决方法:调整平行光阴影的bias属性,有助于减少阴影中的伪影
init({ position, color, intensity , currentlayers, scene} ) { const directionallight = new three.directionallight(color, intensity) // 新建一个平行光源,颜色未白色,强度为1 this.light = directionallight directionallight.position.set(position.x, position.y, position.z) // 将此平行光源调整到一个合适的位置 directionallight.castshadow = true // 将此平行光源产生阴影的属性打开 // 设置平行光的的阴影属性,即一个长方体的长宽高,在设定值的范围内的物体才会产生阴影 const d =100 //阴影范围 directionallight.shadow.camera.left = -d directionallight.shadow.camera.right = d directionallight.shadow.camera.top = d directionallight.shadow.camera.bottom = -d directionallight.shadow.camera.near = 20 directionallight.shadow.camera.far = 8000 directionallight.shadow.mapsize.x = 2048 // 定义阴影贴图的宽度和高度,必须为2的整数此幂 directionallight.shadow.mapsize.y = 2048 // 较高的值会以计算时间为代价提供更好的阴影质量 directionallight.shadow.bias = -0.0005 //解决条纹阴影的出现 this.setlayers(directionallight, currentlayers) scene.add(directionallight) // 将此平行光源加入场景中,我们才可以看到这个光源 return directionallight }
设置平行光信息
设置平行光的信息:包括位置、颜色、强度
setsun(position, color, intensity) { this.settweens(this.light.position, position, 2000) this.light.color = new three.color( color ) this.light.intensity = intensity }
tween
这里简单介绍tween不懂的可以去看我之前的文章,主要是一个动画库,这里做简单的封装
settweens(obj, newobj, duration = 1500) { var ro = new tween.tween(obj) ro.to(newobj, duration) // 变化后的位置以及动画时间 ro.easing(tween.easing.sinusoidal.inout) ro.onupdate(function () { } ) ro.start() }
总结
通过以上内容的阐述,相信大家对“阳光和阴影效果要怎么在threejs中应用”已经有了进一步的了解,更多相关的问题,欢迎关注网络或到官网咨询客服。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 阳光和阴影效果要怎么在threejs中应用
本文地址: https://pptw.com/jishu/654326.html