乐趣区

关于前端:Threejs-这样写就有阴影效果啦

本文简介

点赞 + 关注 + 珍藏 = 学会了

渲染暗影成果须要耗费肯定的资源,所以 Three.js 默认是敞开暗影成果的。

想要在 Three.js 中实现暗影成果,只需记住接下来要讲的几个点即可。

本文要实现的成果

本文适宜 Three.js 入门级的工友浏览~

如果你还不理解 Three.js,能够先看看《Three.js 腾飞》。

本文应用 Three 的版本是 137

根底概念

在学习 Three.js 时,很多知识点其实记住几个重要的步骤就能实现相应的成果。

比方在《Three.js 腾飞》中提到的,只有有 场景、摄像机、渲染器、物体 就能在页面中展现一些货色进去了。

要实现暗影成果同样须要几个重要的概念。

咱们首先钻研一下日常生活中是如何产生暗影成果的。

  1. 须要有光。
  2. 须要一个物体,比方苹果、狗等。
  3. 须要一个承受投影的元素,比方高空、桌面等。

Three.js 中要产生暗影成果其实和事实世界的原理差不多。

但思考到性能起因,Three.js 默认敞开了暗影成果,须要手动开启暗影成果:

  1. 渲染器开启暗影成果。
  2. 有一个能产生暗影的光源,并开启暗影成果。
  3. 有一个承受暗影投射的元素(比方高空),并设置 承受暗影的属性true
  4. 有一个能产生暗影成果的物体,并开启暗影成果。

入手实现

入手之前先察看一下最终成果

上图有一个立方体、高空、光源。

还有根底元素:场景、摄像机、渲染器。

我把用到的元素整顿成一个表格:

元素 形容 相干代码
场景 容器,光源、立方体、高空等元素都要增加到场景中。 let scene = new Scene()
摄像机 场景中的相机,代替人眼去察看的工具。 let camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
渲染器 渲染工具,本文次要讲的是开启暗影渲染性能。 须要开启暗影渲染性能
renderer.shadowMap.enabled = true
高空 高空,接管暗影的元素。 PlaneGeometry 生成一个立体,并设置该立体的 receiveShadow 属性为 true 就能承受别的物体投射过去的暗影。
立方体 本例的物体元素。 BoxGeometry 创立一个立方体,并设置该立方体的 castShadow 属性为 true,就能产生投影成果。
光源 要应用 可产生暗影成果 的光源,比方本例的 SpotLight 聚光灯。
AmbientLight 环境光PointLight 点光源 是不能产生暗影成果的。
应用 SpotLight 创立光源,并设置该光源的 castShadowtrue 开启暗影成果。

第 1 步:搭建根底场景

Three 中搭建根底场景须要 3 因素:场景 Scene、摄像机 PerspectiveCamera、渲染器 WebGLRenderer

<script type="module">
  import {
    Scene, // 场景
    PerspectiveCamera, // 摄像机
    WebGLRenderer, // 渲染器
    Color, // 色彩(不是本例重点)PlaneGeometry, // 平面几何(创立高空时会用到)BoxGeometry, // 立方几何体(创立立方体时会用到)MeshLambertMaterial, // 非光泽外表的材质(可承受光照产生暗影成果)Mesh, // 网格,合成物体元素时会用到
    SpotLight // 聚光灯
  } from '../js/Three/src/Three.js'

  // 场景
  let scene = new Scene()

  // 摄像机
  let camera = new PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  )

  // 设置摄像机地位
  camera.position.set(-30, 60, 60)
  // 锁定摄像机镜头方向
  camera.lookAt(scene.position)

  // 渲染器
  let renderer = new WebGLRenderer()
  renderer.setClearColor(new Color(0xEEEEEE)) // 设置渲染器色彩
  renderer.setSize(window.innerWidth, window.innerHeight) // 渲染器尺寸

  // 将渲染器增加到页面
  document.body.appendChild(renderer.domElement)

  // 渲染
  renderer.render(scene, camera)

</script>

我把场景的背景色设置成灰色 renderer.setClearColor(new Color(0xEEEEEE))

此时页面上是一片空白,还没元素能够展现。

第 2 步:创立光源

因为本例 没有应用 根底材质(MeshBasicMaterial),渲染进去的物体没有光源是不会显示的,所以我先把光源增加到场景中,之后增加高空和立方体时就比拟不便察看了。

要实现暗影成果,我抉择了 SpotLight 聚光灯。

// 省略局部代码

// 光源
let spotLight = new SpotLight(0xFFFFFF)
spotLight.position.set(-40, 50, 30)

scene.add(spotLight) // 将聚光灯增加到场景中

尽管创立了光源,但此时场景中并没有其余物体,所以场景还是一片空白。

第 3 步:创立高空

在本例中高空是用来承受物体投影的载体。

创立高空我应用了 PlaneGeometry 立体,该办法只需传入宽和高即可。

而后应用 MeshLambertMaterial 材质,设置高空色彩为红色。

// 省略局部代码

// 高空
let planeGeometry = new PlaneGeometry(60, 20) // 骨架
let planeMaterial = new MeshLambertMaterial({color: 0xffffff}) // 可产生暗影的材质
let plane = new Mesh(planeGeometry, planeMaterial) // 网格

scene.add(plane) // 将高空增加到场景中

此时看到的高空出现上图的样子(一点都不想高空)。

因为灯光的关系,高空看上去并不是纯白色,离灯光越近的中央就越白,越远就越灰。

我心愿高空能够程度搁置,所以我将高空沿 x 轴旋转 -90°

// 省略局部代码
plane.rotation.x = -90 * Math.PI / 180 // 高空 x 轴 旋转 -90 度

第 4 步:创立立方体

我应用 BoxGeometry 创立立方体,设置一个红色的纹理。

// 省略局部代码

// 立方体
let cubeGeometry = new BoxGeometry(6, 6, 6)
let cubeMaterial = new MeshLambertMaterial({color: 0xff0000}) // 可产生暗影的材质
let cube = new Mesh(cubeGeometry, cubeMaterial)

scene.add(cube)

批改一下立方体的地位

cube.position.set(-6, 6, 3)

第 5 步:开启暗影成果

用回下面提到的四句口诀就能开启暗影成果

  1. 渲染器开启暗影成果。
  2. 有一个能产生暗影的光源,并开启暗影成果。
  3. 有一个承受暗影投射的元素(比方高空),并设置 承受暗影的属性true
  4. 有一个能产生暗影成果的物体,并开启暗影成果。

// 省略局部代码

// 渲染器开启暗影成果
renderer.shadowMap.enabled = true

// 光源开启暗影成果
spotLight.castShadow = true

// 高空承受暗影
plane.receiveShadow = true

// 立方体开启暗影成果
cube.castShadow = true

实现!

如果想设置暗影的精密度,还能够通过聚光灯的三个属性进行管制:

  • spotLight.shadow.mapSize
  • spotLight.shadow.camera.far
  • spotLight.shadow.camera.nera

本文次要解说暗影的根底应用办法,先入个门,前面的案例文章会和联合其余成果实现更好玩的货色~

代码仓库

⭐Three 根底暗影用法

举荐浏览

👍《『Three.js』腾飞!》

👍《『Three.js』辅助坐标轴》

👍《『Three.js』场景 Scene》

👍《『Three.js』几个简略的入门动画(老手篇)》

点赞 + 关注 + 珍藏 = 学会了
代码仓库

退出移动版