网站首页 > 编程文章 正文
我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
本文简介
点赞 + 关注 + 收藏 = 学会了
渲染阴影效果需要消耗一定的资源,所以 Three.js 默认是关闭阴影效果的。
想要在 Three.js 中实现阴影效果,只需记住接下来要讲的几个点即可。
本文要实现的效果
本文适合 Three.js 入门级的工友阅读~
如果你还不了解 Three.js ,可以先看看 《Three.js 起飞》 。
本文使用 Three 的版本是 137 。
基础概念
在学习 Three.js 时,很多知识点其实记住几个重要的步骤就能实现相应的效果。
比如在 《Three.js 起飞》 中提到的,只要有 场景、摄像机、渲染器、物体 就能在页面中展示一些东西出来了。
要实现阴影效果同样需要几个重要的概念。
我们首先研究一下日常生活中是如何产生阴影效果的。
- 需要有光。
- 需要一个物体,比如苹果、狗等。
- 需要一个接受投影的元素,比如地面、桌面等。
在 Three.js 中要产生阴影效果其实和现实世界的原理差不多。
但考虑到性能原因,Three.js 默认关闭了阴影效果,需要手动开启阴影效果:
- 渲染器开启阴影效果。
- 有一个能产生阴影的光源,并开启阴影效果。
- 有一个接受阴影投射的元素(比如地面),并设置 接受阴影的属性 为 true。
- 有一个能产生阴影效果的物体,并开启阴影效果。
动手实现
动手之前先观察一下最终效果
上图有一个立方体、地面、光源。
还有基础元素:场景、摄像机、渲染器。
我把用到的元素整理成一个表格:
元素 | 描述 | 相关代码 |
场景 | 容器,光源、立方体、地面等元素都要添加到场景中。 | let scene = new Scene() |
摄像机 | 场景中的相机,代替人眼去观察的工具。 | let camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000) |
渲染器 | 渲染工具,本文主要讲的是开启阴影渲染功能。 | 需要开启阴影渲染功能 |
地面 | 地面,接收阴影的元素。 | 用 PlaneGeometry 生成一个平面,并设置该平面的 receiveShadow 属性为 true 就能接受别的物体投射过来的阴影。 |
立方体 | 本例的物体元素。 | 用 BoxGeometry 创建一个立方体,并设置该立方体的 castShadow 属性为 true ,就能产生投影效果。 |
光源 | 要使用 可产生阴影效果 的光源,比如本例的 SpotLight 聚光灯。 | 使用 SpotLight 创建光源,并设置该光源的 castShadow 为 true 开启阴影效果。 |
第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步:开启阴影效果
用回上面提到的四句口诀就能开启阴影效果
- 渲染器开启阴影效果。
- 有一个能产生阴影的光源,并开启阴影效果。
- 有一个接受阴影投射的元素(比如地面),并设置 接受阴影的属性 为 true。
- 有一个能产生阴影效果的物体,并开启阴影效果。
// 省略部分代码
// 渲染器开启阴影效果
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』几个简单的入门动画(新手篇)》
点赞 + 关注 + 收藏 = 学会了
猜你喜欢
- 2024-10-24 啥叫完美?基于three.js的数字孪生设计
- 2024-10-24 threejs非同凡响|建模和大数据的完美融合
- 2024-10-24 Three.JS编程中如何切换gltf模型动画?
- 2024-10-24 Three.JS教程4 threejs中的辅助类
- 2024-10-24 THREEJS学习之路-镜头切换动画(threejs camera)
- 2024-10-24 Threejs技术助力IoT可视化大屏的创新展示方式
- 2024-10-24 threejs3d学习笔记3(threejs教程)
- 2024-10-24 three.js还是cesium.js ? 究其根本只是实现工具,思路才关键!
- 2024-10-24 threejs中,如何检测一个模型附近一定范围内的其它模型
- 2024-10-24 Threejs 与blender贴图 结合用法(threejs导入blender模型)
你 发表评论:
欢迎- 06-24一个老爸画了超级有爱的365幅画 | 父亲节献礼
- 06-24产品小白看魏则西事件——用产品思维审视百度推广
- 06-24某教程学习笔记(一):13、脚本木马原理
- 06-24十大常见web漏洞——命令执行漏洞
- 06-24初涉内网,提权那些事(内网渗透提权)
- 06-24黑客命令第16集:47种最常见的**网站方法2/2
- 06-24铭说 | 一句话木马的多种变形方式
- 06-24Java隐藏的10倍效率技巧!90%程序员不知道的魔法方法(附代码)
- 最近发表
- 标签列表
-
- spire.doc (70)
- instanceclient (62)
- solidworks (78)
- system.data.oracleclient (61)
- 按键小精灵源码提取 (66)
- pyqt5designer教程 (65)
- 联想刷bios工具 (66)
- c#源码 (64)
- graphics.h头文件 (62)
- mysqldump下载 (66)
- libmp3lame (60)
- maven3.3.9 (63)
- 二调符号库 (57)
- git.exe下载 (68)
- diskgenius_winpe (72)
- pythoncrc16 (57)
- solidworks宏文件下载 (59)
- qt帮助文档中文版 (73)
- satacontroller (66)
- hgcad (64)
- bootimg.exe (69)
- android-gif-drawable (62)
- axure9元件库免费下载 (57)
- libmysqlclient.so.18 (58)
- springbootdemo (64)
本文暂时没有评论,来添加一个吧(●'◡'●)