threejs教程-灯光对物体的影响

简介

本系列教程需要具备threejs的基础入门知识,了场景、几何体、相机等基础概念。

学习本教程之前,建议学习【几何体】的基础知识。

根据前置知识,我们能够实现一个如下的3D效果

在这个示例中,我们使用PlaneGeometry创建了平面几何体

js 复制代码
const geometry = new THREE.PlaneGeometry(5, 5);

使用texture设置了其纹理贴图

js 复制代码
// 创建纹理
const texture = new THREE.TextureLoader().load("/bg.jpg");

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

js 复制代码
// 创建平面几何体
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 试试

很明显,这种材质如果没有光照就会是一团黑。

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

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

可见,这种受到光照影响的材质有了光源后才能被我们看见。

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

受光照影响材质

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

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

js 复制代码
//MeshBasicMaterial不受光照影响
const material = new THREE.MeshBasicMaterial(); 

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

创建光影观察模型

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

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

面上有一个立方体

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

上述代码中,我们使用了高光材质,但是没有设置光源,因此,物体表面是黑色的。

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

光源简介

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

环境光AmbientLight

环境光会均匀的照亮场景中的所有物体,它没有方向,不能用来投射阴影。

API:threejs.org/docs/?q=Amb...

构造函数

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

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

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

可以看出,环境光会照亮所有物体,而且物体的每个位置光照颜色是一致的。

我们更改光照强度试试

物体位置移动

现在立方体的位置卡在平面中间,看着很难受,我们把它抬高一点。

点光源PointLight

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

PointLight构造函数:

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

我们试着添加一个点光源

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

反光强度

MeshPhongMaterial材质的物体在点光源下可以设置不同的反光程度

API:threejs.org/docs/index....

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

实现物体阴影效果

在光照下,立方体盒子应该在地面上有个阴影,实现这个效果需要以下几步

打开物体的投射光源功能

js 复制代码
// 物体投射光源
boxMesh.castShadow = true;

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

js 复制代码
// 地面接受光源
floorMesh.receiveShadow = true;

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

js 复制代码
// 投射光源
pointLight.castShadow = true;

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

js 复制代码
// 渲染器的阴影渲染开关
renderer.shadowMap.enabled = true;
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端