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 的付费课程)的学习笔记,代码为个人练习所写,概念讲解融入了个人的理解和比喻。

相关推荐
计算机魔术师2 小时前
AI 写了一半代码,谁来背锅?Anthropic 的安全重构笔记
前端
半个落月2 小时前
JavaScript 单例模式详解:从唯一实例到按钮事件
javascript
明月_清风2 小时前
vLLM 深度实战:2026 年生产级 LLM 推理引擎完全指南
前端·后端·ai编程
风月说与山鬼2 小时前
七、uni-app页面与组件生命周期
前端·uni-app
绿岛之北3 小时前
Electron 安全第三章:URL 加载与 WebView
前端·electron
sunoo-2293 小时前
C 语言文件 IO 全攻略:从基础函数到实战踩坑(BMP 读取 + 词典查询)
linux·c语言·前端·笔记·vscode·学习
Shinner欣儿3 小时前
React18 并发渲染小记
前端
用户921080262863 小时前
AI 对话里的消息时间线分页:上滑加载更多历史记忆的实现与坑点
前端
PedroQue993 小时前
Vue-Router 2.4.0 新增可控重定向功能
前端·uni-app
阿萨德528号3 小时前
npm 包发布实战指南:从零发布、更新迭代到版本治理
前端·npm·策略模式