记录下three.js学习过程中不理解问题----材质(material)⑤
材质定义了3D对象的外观。它们决定了物体如何在场景中显示,比如颜色、光泽度、反射等等。
常见的材质类型
MeshBasicMaterial(基础材质)
特点:不受光照影响。
用途:适用于简单的物体,比如界面元素或静态对象,或者需要表现无光照效果的物体。
const matrial=new THREE.MeshBasicMaterial( color:"0xFF0000"//红色 )
MeshLambertMaterial(兰伯特材质)
特点:受光照影响,但计算较简单。适用于漫反射(不反射光的材质,比如墙壁)。
用途:常用于表现简单的物体,光线照射下有一定的反射,但不需要高精度的计算。
MeshPhonegMaterial(冯氏材质)
特点:在每个像素上计算光照,支持镜面高光(比如金属或光滑表面上的反射光)。
用途:适合表现有反射光泽的物体,如金属、光滑表面等。
const material=new THREE.MeshphonegMaterial( color:"0xFF0000", shininess:3 //光泽度 )
MeshToonMaterial(卡通材质)
特点:使用渐变图来决定物体如何着色,效果像是卡通风格(分层颜色,不是平滑过渡)。
用途:如果你想要制作卡通风格的效果,适合用于需要简单、鲜艳颜色的物体。
MeshstandardMaterial(标准物理材质)
特点:基于物理渲染,支持 roughness(粗糙度)和 metalness(金属度)。它通过更加真实的计算方式模拟现实世界的材质。
用途:如果你希望物体看起来更接近现实世界的材质,可以使用它。比如石头、木材、金属等。
const meterial=new THREE.MeshStandardMaterial( color:‘0xFF0000’, roughness:0.5,// 粗糙度 matalness:0.8// 粗糙度 )
MeshPhysicalMaterial(物理材质)
特点:基于 MeshStandardMaterial,但增加了 clearcoat(清漆层)和 clearCoatRoughness(清漆层粗糙度),用于增加额外的光泽。
用途:适合需要非常真实的光泽效果,比如汽车表面。
特殊材质
ShadowMaterial(只渲染阴影部分)
MeshDepthMaterial(根据物体与相机的距离来计算深度(类似于深度图),用于特效。)
MeshNormalMaterial()显示物体的法线(面朝哪个方向)
如何设置材质属性?
你可以在创建材质时传入属性值
const material=new THREE.MeshPhoneMaterial({ color:0xFF0000, shininess:3 })
在实例化之后设置属性:
你也可以在材质实例化之后,通过访问材质对象的属性来修改它:
const material=new.THREE.MeshPhoneMaterial() material.color.set(0xFF0000) material.shininess=30
常用材质属性
flatshading:是否使用平面着色。默认是
false
,设置为true
时会让表面看起来像是由平面组成的多边形。material.flatshading=true
side:控制材质在哪一面显示(正面、反面或双面)。
material.side=new.DoubleSide;//双面显示
性能优化
不同材质的计算复杂度不同,越复杂的材质会消耗更多的计算资源,影响渲染效率。例如:
MeshBasicMaterial 是最简单的,适合性能较弱的设备。
MeshPhonegMaterial和MeshStandardMaterial较为复杂,适合需要更高质量渲染的场景,但会增加 GPU 负担。
如果你的应用在手机或低功耗设备上运行,可以选择 MeshBasicMaterial 或 MeshLambertMaterial 来提高性能。
材质更新
当你修改材质的某些属性(比如添加或删除纹理),你可能需要通知 three.js 重新计算渲染。这时需要设置
material.needsUpdate = true
。material.needsUpdate=true
总结
简单材质(如 MeshBasicMaterial)适用于对性能要求较高、无需光照的情况。
高级材质(如 MeshPhongMaterial、MeshStandardMaterial)适合表现复杂的光照效果和更逼真的材质。
物理材质(如 MeshStandardMaterial 和 MeshPhysicalMaterial)提供了更高的真实性,适合模拟现实世界中的材质。
特殊材质(如 MeshNormalMaterial)有特定用途,如调试或显示法线等。
注意
什么是平面着色(Flat Shading)?
平面着色是指在渲染一个三角形面片时,该面片上的所有像素都使用同一个颜色,通常是这个面片的法线方向与光源的光照结果。这种着色方式会让物体的每个面看起来非常锋利,因为每个面都有明确的边界,不会有过渡的光照。
默认设置:
flatShading: false
当
flatShading
设置为false
时,Three.js 使用 平滑着色(Smooth Shading)。在平滑着色下,顶点的颜色会根据邻近的顶点平滑过渡。这样,整个物体表面看起来更加柔和,没有明显的面与面的边界。启用平面着色:
flatShading: true
当
flatShading
设置为true
时,每个三角形的面都会被单独着色,并且相邻的面之间没有光照平滑过渡效果。因此,这种方式会让物体的每个面呈现出一个“块状”的效果,看起来比较硬朗、几何化。举个例子:
平滑着色: 物体表面看起来比较柔和,没有明显的面与面之间的边界。例如,球体表面看起来会有平滑的过渡。
平面着色: 每个面都是一个平面,面与面之间的边界非常明显,通常适用于低多边形风格的渲染。
示例代码:
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 更新材质,因为这是一个涉及计算的属性。material.flatShading = true; // 改变为平面着色 material.needsUpdate = true; // 通知 Three.js 更新材质
2. 添加或删除纹理
当你给材质添加或删除纹理时,也需要设置
needsUpdate = true
来确保变化生效。material.map = new THREE.TextureLoader().load('texture.jpg'); // 添加纹理 material.needsUpdate = true; // 通知 Three.js 更新材质
或者在不使用纹理时,将纹理设置为
null
:material.map = null; // 移除纹理 material.needsUpdate = true; // 通知 Three.js 更新材质
为什么会用到
material.needsUpdate
?在 Three.js 渲染循环中,材质的属性通常在创建时就被设置好。如果你在之后修改了材质的属性(例如,修改了
flatShading
或纹理),默认情况下这些修改并不会自动应用。设置needsUpdate = true
就是强制 Three.js 在下一帧重新计算并应用这些修改。