记录下three.js学习过程中不理解问题----材质(material)⑤

材质定义了3D对象的外观。它们决定了物体如何在场景中显示,比如颜色、光泽度、反射等等。

常见的材质类型

MeshBasicMaterial(基础材质)

  • 特点:不受光照影响。

  • 用途:适用于简单的物体,比如界面元素或静态对象,或者需要表现无光照效果的物体。

javascript 复制代码
const matrial=new THREE.MeshBasicMaterial(
color:"0xFF0000"//红色
)

MeshLambertMaterial(兰伯特材质)

  • 特点:受光照影响,但计算较简单。适用于漫反射(不反射光的材质,比如墙壁)。

  • 用途:常用于表现简单的物体,光线照射下有一定的反射,但不需要高精度的计算。

MeshPhonegMaterial(冯氏材质)

  • 特点:在每个像素上计算光照,支持镜面高光(比如金属或光滑表面上的反射光)。

  • 用途:适合表现有反射光泽的物体,如金属、光滑表面等。

javascript 复制代码
const material=new THREE.MeshphonegMaterial(
color:"0xFF0000",
shininess:3 //光泽度
)

MeshToonMaterial(卡通材质)

  • 特点:使用渐变图来决定物体如何着色,效果像是卡通风格(分层颜色,不是平滑过渡)。

  • 用途:如果你想要制作卡通风格的效果,适合用于需要简单、鲜艳颜色的物体。

MeshstandardMaterial(标准物理材质)

  • 特点 :基于物理渲染,支持 roughness (粗糙度)和 metalness(金属度)。它通过更加真实的计算方式模拟现实世界的材质。

  • 用途:如果你希望物体看起来更接近现实世界的材质,可以使用它。比如石头、木材、金属等。

javascript 复制代码
const meterial=new THREE.MeshStandardMaterial(
color:'0xFF0000',
roughness:0.5,// 粗糙度
matalness:0.8// 粗糙度
)

MeshPhysicalMaterial(物理材质)

  • 特点 :基于 MeshStandardMaterial ,但增加了 clearcoat (清漆层)和 clearCoatRoughness(清漆层粗糙度),用于增加额外的光泽。

  • 用途:适合需要非常真实的光泽效果,比如汽车表面。

特殊材质

ShadowMaterial(只渲染阴影部分)

MeshDepthMaterial(根据物体与相机的距离来计算深度(类似于深度图),用于特效。)

MeshNormalMaterial()显示物体的法线(面朝哪个方向)
如何设置材质属性?

你可以在创建材质时传入属性值

javascript 复制代码
const material=new THREE.MeshPhoneMaterial({
color:0xFF0000,
shininess:3
})

在实例化之后设置属性

你也可以在材质实例化之后,通过访问材质对象的属性来修改它:

javascript 复制代码
const material=new.THREE.MeshPhoneMaterial()
material.color.set(0xFF0000)
material.shininess=30

常用材质属性

flatshading: 是否使用平面着色。默认是 false,设置为 true 时会让表面看起来像是由平面组成的多边形。

javascript 复制代码
material.flatshading=true

side:控制材质在哪一面显示(正面、反面或双面)。

javascript 复制代码
material.side=new.DoubleSide;//双面显示

性能优化

不同材质的计算复杂度不同,越复杂的材质会消耗更多的计算资源,影响渲染效率。例如:

MeshBasicMaterial 是最简单的,适合性能较弱的设备。

MeshPhonegMaterial和MeshStandardMaterial较为复杂,适合需要更高质量渲染的场景,但会增加 GPU 负担。

如果你的应用在手机或低功耗设备上运行,可以选择 MeshBasicMaterialMeshLambertMaterial 来提高性能。
材质更新

当你修改材质的某些属性(比如添加或删除纹理),你可能需要通知 three.js 重新计算渲染。这时需要设置 material.needsUpdate = true

javascript 复制代码
material.needsUpdate=true

总结

  • 简单材质 (如 MeshBasicMaterial)适用于对性能要求较高、无需光照的情况。

  • 高级材质 (如 MeshPhongMaterialMeshStandardMaterial)适合表现复杂的光照效果和更逼真的材质。

  • 物理材质 (如 MeshStandardMaterialMeshPhysicalMaterial)提供了更高的真实性,适合模拟现实世界中的材质。

  • 特殊材质 (如 MeshNormalMaterial)有特定用途,如调试或显示法线等。

注意

什么是平面着色(Flat Shading)?

平面着色是指在渲染一个三角形面片时,该面片上的所有像素都使用同一个颜色,通常是这个面片的法线方向与光源的光照结果。这种着色方式会让物体的每个面看起来非常锋利,因为每个面都有明确的边界,不会有过渡的光照。

默认设置:flatShading: false

flatShading 设置为 false 时,Three.js 使用 平滑着色(Smooth Shading)。在平滑着色下,顶点的颜色会根据邻近的顶点平滑过渡。这样,整个物体表面看起来更加柔和,没有明显的面与面的边界。

启用平面着色:flatShading: true

flatShading 设置为 true 时,每个三角形的面都会被单独着色,并且相邻的面之间没有光照平滑过渡效果。因此,这种方式会让物体的每个面呈现出一个"块状"的效果,看起来比较硬朗、几何化。

举个例子:

  • 平滑着色: 物体表面看起来比较柔和,没有明显的面与面之间的边界。例如,球体表面看起来会有平滑的过渡。

  • 平面着色: 每个面都是一个平面,面与面之间的边界非常明显,通常适用于低多边形风格的渲染。

示例代码:

javascript 复制代码
const material = new THREE.MeshPhongMaterial({
  color: 0xFF0000, // 红色
  flatShading: true, // 启用平面着色
});

const geometry = new THREE.BoxGeometry(1, 1, 1);
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

flatShading: true 时,立方体的每个面都会有明显的边界,不会有平滑的过渡效果。
material.needsUpdate 是 Three.js 中一个比较少用的属性,它的作用是告诉 Three.js,当你修改了材质的某些属性时,需要重新更新材质的渲染结果。

什么时候需要用 material.needsUpdate = true

在 Three.js 中,材质(material)的一些属性在初始化后就会生效,而如果你在材质创建后修改了这些属性,有些修改可能不会立即反映出来,因为 Three.js 需要重新计算并应用这些变化。这时,needsUpdate 属性的作用就是通知 Three.js 需要重新渲染材质。

举几个常见的例子:

1. 修改 flatShading 属性

flatShading 是一种控制平面着色的属性。修改这个属性之后,通常需要告诉 Three.js 更新材质,因为这是一个涉及计算的属性。

javascript 复制代码
material.flatShading = true;  // 改变为平面着色
material.needsUpdate = true;  // 通知 Three.js 更新材质
2. 添加或删除纹理

当你给材质添加或删除纹理时,也需要设置 needsUpdate = true 来确保变化生效。

javascript 复制代码
material.map = new THREE.TextureLoader().load('texture.jpg');  // 添加纹理
material.needsUpdate = true;  // 通知 Three.js 更新材质

或者在不使用纹理时,将纹理设置为 null

javascript 复制代码
material.map = null;  // 移除纹理
material.needsUpdate = true;  // 通知 Three.js 更新材质

为什么会用到 material.needsUpdate

在 Three.js 渲染循环中,材质的属性通常在创建时就被设置好。如果你在之后修改了材质的属性(例如,修改了 flatShading 或纹理),默认情况下这些修改并不会自动应用。设置 needsUpdate = true 就是强制 Three.js 在下一帧重新计算并应用这些修改。

相关推荐
西岸行者3 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意3 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码4 天前
嵌入式学习路线
学习
毛小茛4 天前
计算机系统概论——校验码
学习
babe小鑫4 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习