Three.js 材质篇(中):从兰伯特到PBR,一篇文章看懂五种光照材质

上篇我们认识了四种"免灯光"材质。今天给场景加上光,让五种吃光照的材质同台竞技:

  1. Lambert (水粉画,漫反射)
  2. Phong (油画,带高光)
  3. Toon (动漫风,卡通光)
  4. Standard (单反照,PBR真实感)
  5. Physical (加镀膜,清漆层)

读完这篇,你不仅能看懂材质演变史,更能在实际项目中做出"以假乱真"的物体。

至关重要的"配合":环境光与点光源

在讲解这些材质前,必须加一个小节,因为它们是"吃光照"的,没有光就是黑色。

⚠️ 重要:这五种材质都需要光照才能显示颜色。没有光,它们就是一团黑色。

ini 复制代码
// 添加环境光,让物体不至于太暗

const ambientLight = new THREE.AmbientLight(0x404060);

scene.add(ambientLight);

// 添加一个点光源,让它转起来,方便观察材质

const pointLight = new THREE.PointLight(0xffffff, 1);

pointLight.position.set(2, 3, 4);

scene.add(pointLight);

// 让光源动起来,展示光影变化

const tick = () => {

    const time = Date.now() * 0.002;
    
    pointLight.position.x = Math.sin(time) * 3;
    
    pointLight.position.z = Math.cos(time) * 2;
    // ... 渲染
}

1.MeshLambertMaterial (兰伯特) ------ 初代目,漫反射

`// MeshLambertMaterial

const material = new THREE.MeshLambertMaterial()`

想象一面粗糙的水泥墙 ,或者一件没上釉的陶器。光照上去,光线朝各个方向均匀散开,你不会看到某个点特别亮。这就是纯粹的漫反射,就像磨砂光面。

可以看到它的质感非常的细腻,光感很柔和,材质看起来很高级。

2. MeshPhongMaterial ------ 油画,带高光

在磨砂质感的基础上出现了反光点,像高光一样,像上了釉的陶瓷瓶,有高光质感,接下来创建:

`// MeshPhongMaterial const material = new THREE.MeshPhongMaterial()

material.shininess = 10 // 光泽度,越高高光点越小越亮

material.specular = new THREE.Color(0x1188FF) //颜色`

可以看到shininess数值越大反光点汇聚成一个点很亮,数值越小,高光散开,很柔和像珍珠光。

3. MeshToonMaterial ------ 动漫风,卡通光

// MeshToonMaterial const material = new THREE.MeshToonMaterial()

就像动漫或二次元手办。真实的光影是渐变的(暗→灰→亮),而卡通材质把光影压缩成几个明显的色块------暗部一块、中间调一块、亮部一块,边界清晰,感觉可以用来制作甜甜圈效果。

4. MeshStandardMaterial ------ 单反照,PBR真实感(核心重点)

现代Three.js的绝对主力 。基于物理的渲染(PBR),使用 roughness(粗糙度)和 metalness(金属度)两个直观参数,能模拟几乎所有真实材质。

`const material = new THREE.MeshStandardMaterial()

material.metalness = 0.7//金属度

material.roughness = 0.2//粗糙度 ` 为了展示我们需要给项目加入一个环境贴图:

import { RGBELoader } from 'three/examples/jsm/Addons.js'//引入RGBELoader

RGBELoader 用来加载 HDR(高动态范围)环境贴图,这张图既是背景,又是光源------就像把你的3D物体放进一个真实拍摄的"光影胶囊"里。

ini 复制代码
/**
  * 环境贴图
  */
 
const rgbeLoader = new RGBELoader()

rgbeLoader.load('/textures/environmentMap/2k.hdr',(environmentMap) => 

{
    environmentMap.mapping = THREE.EquirectangularReflectionMapping

    scene.background = environmentMap // 设置背景显示什么
    
    scene.environment = environmentMap // 设置物体反射/受光来自哪里
})

此时我们拥有了一个背景。

想象你在摄影棚里拍一个金属球

  • 普通打光:你需要放好几个灯,调半天位置和亮度,才能让球体表面有好看的反光
  • 用 RGBELoader :直接把球放进一个球形灯箱里,灯箱内壁贴着一张"真实的房间照片"------球体表面的反光,就是这张照片里的窗户、墙壁、灯光

RGBELoader 加载的 .hdr 文件,就是这张"灯箱内壁的照片"

我们使用控件调整金属度到最高,粗糙度为0,最光滑的状态能得到一个金属质感的物体,可以反射到环境贴图中的楼窗户等,非常棒!

参数 作用 取值范围 示例
roughness 表面粗糙程度 0(镜面)→ 1(完全漫反射) 0.3 光滑,0.8 磨砂
metalness 金属化程度 0(非金属)→ 1(纯金属) 0.1 像塑料,0.9 像铁

5.MeshPhysicalMaterial ------ 加镀膜,清漆层(旗舰加强版)

`// MeshPhysicalMaterial const material = new THREE.MeshPhysicalMaterial()

material.metalness = 0//金属度

material.roughness = 0.15//粗糙度

material.map = doorColorTexture //使用门纹理

`

可以看出来我们的门好像被困在一种清漆里面被封起来的质感。

下一篇预告:材质篇(下)------ Standard vs Physical,普通车漆和豪华镀膜的区别在哪?

本篇的五种光照材质里,MeshStandardMaterial 是 PBR 主力,能应付 90% 的场景。

但如果你想要车漆的表层清漆反光玻璃的透射折射 、或者丝绸的绒毛光泽 ------就需要升级到 MeshPhysicalMaterial

下一篇,我们用对比表格和代码示例,把 StandardPhysical 的区别讲透,顺便解锁 transmissionclearcoatsheen 等高级参数。

📚 本文是学习 Three.js Journey(Bruno Simon 的付费课程)的学习笔记,代码为个人练习所写,概念讲解融入了个人的理解和比喻。

相关推荐
郭老二1 小时前
【前端】vue3:编译步骤
前端
不在逃避q2 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁2 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9852 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易2 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师3 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174463 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈3 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen4 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒5 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端