文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

threejs太阳光与阴影效果怎么实现

2023-06-29 20:21

关注

这篇文章主要介绍“threejs太阳光与阴影效果怎么实现”,在日常操作中,相信很多人在threejs太阳光与阴影效果怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”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中实时更新TWEENTWEEN.update()

初始化

这里做的是向场景中添加平行光,设置其阴影的范围以及距离等属性,因为我这边涉及层级,所以设置了平行光的层级

平行光可谓是所有灯光中阴影调整最麻烦的,想要平行光能够产生对的阴影效果,模型的产生阴影以及接收阴影要调整好,并且平行光的照射范围也要调整好。我效果图中不知大家有没有发现,在正午时刻的时候太阳光照射地面产生了一个长方形的范围阴影,这里是特地录制一个相对不那么完美的版本。

产生原因:平行光范围太小,但是一旦你调整平行光范围过大,由于地面是通过多个瓦片加载的,就会出现条纹状的阴影

如下图

解决方法:调整平行光阴影的bias属性,有助于减少阴影中的伪影

threejs太阳光与阴影效果怎么实现

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太阳光与阴影效果怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯