首页前端开发其他前端知识阳光和阴影效果要怎么在threejs中应用

阳光和阴影效果要怎么在threejs中应用

时间2024-03-27 16:02:03发布访客分类其他前端知识浏览618
导读:这篇文章分享给大家的内容是关于阳光和阴影效果要怎么在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中实时更新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
java char数组输出乱码问题,如何解决 实时操作系统FreeRTOS的内核配置有什么,什么含义

游客 回复需填写必要信息