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

相关推荐
用户6919026813391 小时前
JS 初了解:从“网页玩具”到企业级语言的进化
javascript
且白1 小时前
leaflet切片变色、地图滤镜逻辑实现 colorfilter
前端·javascript
用户887665426631 小时前
Linux 终端入门:新手必须掌握的常用命令和基本思路
前端·操作系统
丷丩1 小时前
MapLibre GL JS第30课:添加视频
javascript·音视频·gis·mapbox·maplibre gl js
techdashen2 小时前
拆开任意 Electron 应用:从 Windows 安装包到 Discord 的私有更新协议
javascript·windows·electron
用户125758524362 小时前
Vue3 后台框架的网络请求怎么设计?看 XYGo Admin 三套 Axios 实例与拦截器方案
前端
ZengLiangYi2 小时前
多格式文件解析:JSONL / SQLite / Event Stream
前端·javascript·后端
边界条件╝2 小时前
微前端进阶(一)
前端
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_34:(CSS 布局全面解析)
前端·css·ui·html·tensorflow