【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

相关文章
|
JavaScript
Threejs实现标签,自定义样式显示标签
Threejs实现标签,自定义样式显示标签
1796 0
Threejs实现标签,自定义样式显示标签
Threejs实现下雨,下雪,阴天,晴天,火焰
Threejs实现下雨,下雪,阴天,晴天,火焰
2389 0
Threejs实现下雨,下雪,阴天,晴天,火焰
Threejs实现模拟河流,水面水流,水管水流,海面
Threejs实现模拟河流,水面水流,水管水流,海面
3207 0
Threejs实现模拟河流,水面水流,水管水流,海面
Threejs实现天空盒,全景场景,地面草地
Threejs实现天空盒,全景场景,地面草地
1730 0
Threejs实现天空盒,全景场景,地面草地
Threejs实现模拟管道液体流动
Threejs实现模拟管道液体流动
3102 0
Threejs实现模拟管道液体流动
Threejs实现相机视角切换,平滑过渡,点击模型切换到查看模型视角
Threejs实现相机视角切换,平滑过渡,点击模型切换到查看模型视角
2607 0
Threejs实现相机视角切换,平滑过渡,点击模型切换到查看模型视角
Threejs使用精灵Sprite作为标签,鼠标悬浮精灵上时鼠变小手
Threejs使用精灵Sprite作为标签,鼠标悬浮精灵上时鼠变小手
1875 0
Threejs使用精灵Sprite作为标签,鼠标悬浮精灵上时鼠变小手
|
开发框架
threejs做特效:实现物体的发光效果-EffectComposer详解!
【8月更文挑战第7天】实现物体的发光效果-EffectComposer详解!
1921 6
threejs做特效:实现物体的发光效果-EffectComposer详解!
|
11月前
Threejs制作窗户透亮效果
这篇文章讲解了如何在Three.js中制作窗户的透亮效果,包括设置透明材质和光照以实现逼真的窗户渲染效果的技术细节。
264 1
|
11月前
ThreeJs制作管道中水流效果
这篇文章详细介绍了如何在Three.js中创建具有动态水流效果的管道模型,通过纹理贴图的移动来模拟水流的视觉效果。
780 2
ThreeJs制作管道中水流效果