【threejs教程】让你的场景更加真实:灯光对物体的影响

简介: 【8月更文挑战第6天】threejs教程:让你的场景更加真实,灯光对物体的影响

简介

本系列教程需要具备threejs的基础入门知识,了场景、几何体、相机等基础概念。
学习本教程之前,建议学习【几何体】的基础知识。

根据前置知识,我们能够实现一个如下的3D效果
GIF 2023-11-20 11-03-28.gif
在这个示例中,我们使用PlaneGeometry创建了平面几何体

const geometry = new THREE.PlaneGeometry(5, 5);

使用texture设置了其纹理贴图

// 创建纹理
const texture = new THREE.TextureLoader().load("/bg.jpg");

并且通过uv坐标设置了其纹理贴图的渲染范围

// 创建平面几何体
const geometry = new THREE.PlaneGeometry(5, 5);

// 创建纹理
const texture = new THREE.TextureLoader().load("/bg.jpg");
// 定义uv的取值范围,左上、右上、左下、右下
const uv = new Float32Array([0, 1, 0.5, 1, 0, 0, 0.5, 0]);
geometry.attributes.uv = new THREE.BufferAttribute(uv, 2);

const material = new THREE.MeshBasicMaterial({
   
    map: texture, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

光照对物体的影响

实际生活中物体表面的明暗效果是会受到光照的影响,比如晚上不开灯,你就看不到物体,灯光比较暗,物体也比较暗。在threejs中,咱们用网格模型Mesh模拟生活中物体,所以threejs中模拟光照Light对物体表面的影响,就是模拟光照Light对网格模型Mesh表面的影响。

上述代码示例中,我们使用了MeshBasicMaterial设置了物体的材质,这种材质是不受光照影响的,所以有没有光都无所谓。

我们将MeshBasicMaterial材质换成一种漫反射材质MeshLambertMaterial试试GIF 2023-11-20 11-21-20.gif
很明显,这种材质如果没有光照就会是一团黑。

我们给他加一个环境光试试

// 添加光源
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);

GIF 2023-11-20 11-28-41.gif
可见,这种受到光照影响的材质有了光源后才能被我们看见。

现在,我们对光源已经有了初步的了解,现在我们学习一下光照影响的材质光源等更详细的知识

受光照影响材质

threejs提供的网格材质,有的受光照影响,有的不受光照影响。

基础网格材质MeshBasicMaterial(opens new window)不会受到光照影响。

//MeshBasicMaterial不受光照影响
const material = new THREE.MeshBasicMaterial();

漫反射网格材质MeshLambertMaterial(opens new window)会受到光照影响。受光照影响的材质,在相同光源下,表现的特性也是不一样的。

创建光影观察模型

为了更好的演示灯光对物体的影响,我们创建一个面

// 2.1创建地面模型
const floorMesh = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  // 使用高光材质
  new THREE.MeshPhongMaterial({
   
    side: THREE.DoubleSide, color: 0x1b5e20 })
);
scene.add(floorMesh);

面上有一个立方体

// 2.2创建一个立方体
const boxMesh = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  // 使用高光材质
  new THREE.MeshPhongMaterial({
   
    color: 0x0099ff })
);
scene.add(boxMesh);

上述代码中,我们使用了高光材质,但是没有设置光源,因此,物体表面是黑色的。
GIF 2023-11-20 15-11-03.gif

不同光源下的物体渲染效果

光源简介

Three.js提供了多种模拟生活中光源的API,文档搜索关键词light就可以看到。

image.png

环境光AmbientLight

环境光会均匀的照亮场景中的所有物体,它没有方向,不能用来投射阴影。
API:https://threejs.org/docs/?q=AmbientLight#api/zh/lights/AmbientLight
构造函数

AmbientLight( color : Color, intensity : Float )
  • color -(可选)一个表示颜色的 Color 的实例、字符串或数字,默认为一个白色(0xffffff)的 Color 对象。
  • intensity -(可选)光照的强度。默认值为 1。

我们试着添加一个环境光源

// 添加光源
const light = new THREE.AmbientLight(0xffffff, 1);
scene.add(light);

GIF 2023-11-20 15-13-30.gif
可以看出,环境光会照亮所有物体,而且物体的每个位置光照颜色是一致的。
我们更改光照强度试试
GIF 2023-11-20 15-15-37.gif

物体位置移动

现在立方体的位置卡在平面中间,看着很难受,我们把它抬高一点。
GIF 2023-11-20 15-32-56.gif

点光源PointLight

点光源PointLight(opens new window)可以类比为一个发光点,就像生活中一个灯泡以灯泡为中心向四周发射光线。
PointLight构造函数:

PointLight( color : Color, intensity : Float, distance : Number, decay : Float )
  • color -(可选)一个表示颜色的 Color 的实例、字符串或数字,默认为一个白色(0xffffff)的 Color 对象。
  • intensity -(可选)光照强度。默认值为 1。
  • distance - 光源照射的最大距离。默认值为 0(无限远)。
  • decay - 沿着光照距离的衰退量。默认值为 2。

我们试着添加一个点光源

// 添加点光源
const pointLight = new THREE.PointLight(0xffffff, 100, 100);
// 设置光源位置
pointLight.position.set(5, 3, 5);
scene.add(pointLight);

GIF 2023-11-20 15-55-15.gif

反光强度

MeshPhongMaterial材质的物体在点光源下可以设置不同的反光程度
API:https://threejs.org/docs/index.html?q=MeshPhongMaterial#api/zh/materials/MeshPhongMaterial
image.png

// 2.2创建一个立方体
const boxMesh = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  // 使用高光材质
  new THREE.MeshPhongMaterial({
   
    
    color: 0x0099ff, 
  + shininess: 800 
  })
);

GIF 2023-11-20 16-13-26.gif

实现物体阴影效果

在光照下,立方体盒子应该在地面上有个阴影,实现这个效果需要以下几步
打开物体的投射光源功能

// 物体投射光源
boxMesh.castShadow = true;

打开地面的接受光源光源功能

// 地面接受光源
floorMesh.receiveShadow = true;

打开点光源的投射光源功能

// 投射光源
pointLight.castShadow = true;

启用渲染器的阴影渲染开关

// 渲染器的阴影渲染开关
renderer.shadowMap.enabled = true;

GIF 2023-11-20 16-30-40.gif

相关文章
|
2月前
Threejs用下个点方法实现模型沿着轨道行驶
这篇文章讲解了如何在Three.js中通过计算下一个路径点来控制模型沿轨迹行驶的方向,使用`lookAt`方法使模型面向行驶方向,实现了更加自然的移动效果。
63 1
|
4月前
|
API
【threejs教程】让你的场景及物体拥有质感:聊聊threejs中的基础网络材质!
【8月更文挑战第5天】threejs中的基础网络材质教程
75 3
|
4月前
|
开发者 图形学 Java
揭秘Unity物理引擎核心技术:从刚体动力学到关节连接,全方位教你如何在虚拟世界中重现真实物理现象——含实战代码示例与详细解析
【8月更文挑战第31天】Unity物理引擎对于游戏开发至关重要,它能够模拟真实的物理效果,如刚体运动、碰撞检测及关节连接等。通过Rigidbody和Collider组件,开发者可以轻松实现物体间的互动与碰撞。本文通过具体代码示例介绍了如何使用Unity物理引擎实现物体运动、施加力、使用关节连接以及模拟弹簧效果等功能,帮助开发者提升游戏的真实感与沉浸感。
134 1
|
4月前
|
图形学 开发者
【Unity光照艺术手册】掌握这些技巧,让你的游戏场景瞬间提升档次:从基础光源到全局光照,打造24小时不间断的视觉盛宴——如何运用代码与烘焙创造逼真光影效果全解析
【8月更文挑战第31天】在Unity中,合理的光照与阴影设置对于打造逼真环境至关重要。本文介绍Unity支持的多种光源类型,如定向光、点光源、聚光灯等,并通过具体示例展示如何使用着色器和脚本控制光照强度,模拟不同时间段的光照变化。此外,还介绍了动态和静态阴影、全局光照及光照探针等高级功能,帮助开发者创造丰富多样的光影效果,提升游戏沉浸感。
108 0
|
4月前
|
图形学
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
小功能⭐️Unity 如何判断物体是否在摄像机视野内或外
Three.js模拟沿着路径进行运动,模拟飞机飞行,并保持运动方向
Three.js模拟沿着路径进行运动,模拟飞机飞行,并保持运动方向
1211 0
|
编解码 缓存 计算机视觉
神还原物体复杂、高频细节,4K-NeRF高保真视图合成来了
神还原物体复杂、高频细节,4K-NeRF高保真视图合成来了
150 0
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏05图像仿射变换(平移和缩放操作)
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏05图像仿射变换(平移和缩放操作)
167 0
|
算法 数据可视化
【视觉高级篇】25 # 如何用法线贴图模拟真实物体表面
【视觉高级篇】25 # 如何用法线贴图模拟真实物体表面
182 0
【视觉高级篇】25 # 如何用法线贴图模拟真实物体表面
|
数据可视化
【视觉高级篇】20 # 如何用WebGL绘制3D物体?
【视觉高级篇】20 # 如何用WebGL绘制3D物体?
190 0
【视觉高级篇】20 # 如何用WebGL绘制3D物体?