当前位置: 首页 > news >正文

记录下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 负担。

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

材质更新 

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

material.needsUpdate=true

总结

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

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

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

  • 特殊材质(如 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 在下一帧重新计算并应用这些修改。

http://www.xdnf.cn/news/979003.html

相关文章:

  • 在前端元素中,点击当前元素,但是却选中其他元素的文字的问题
  • Cesium圆锥渐变色实现:融合顶点着色器、Canvas动态贴图与静态纹理的多方案整合
  • 深度剖析:UI 设计怎样为小程序构建极致轻量体验
  • 在 Windows 上安装和配置 Redis 及可视化工具指南
  • C#接口代码记录
  • 物联网基础概述【一】
  • 容器化部署案例一wordpress
  • 递归法解N叉树的后序遍历
  • 若依微服务Openfeign接口调用超时问题
  • Java面向对象编程(OOP)深度学习解析
  • Flutter布局系统全面解析:从基础组件到复杂界面构建
  • ttyd:安全地通过网络共享您的 Linux 终端
  • Cpp 知识3
  • github action推送-构建准备步骤获取私有dockerhub镜像仓库镜像的一系列错误尝试
  • Solidity 开发从入门到精通:语法特性与实战指南
  • 在Linux下使用vscode使用交叉编译工具链的gdb对core文件进行堆栈、变量查看
  • Ubuntu下编译安装DLib的GPU版本并实现人脸检测和人脸关键点检测
  • “十五五”时期智慧城市赋能全国一体化数据市场建设:战略路径与政策建议[ 注:本建议基于公开政策文件与行业实践研究,数据引用截至2025年6月11日。]
  • 商品中心—3.商品可采可补可售的技术文档下
  • 前端面试宝典---事件循环面试题
  • 小白学Pinia状态管理
  • STM32G DMA串口发送接收
  • Linux开发工具之VsCode(Filezila、MobaXterm、Vim三合一)
  • 【笔记】NVIDIA AI Workbench 中安装 cuDNN 9.10.2
  • 每日Prompt:人像写真
  • 内存泄漏系列专题分析之二十:camx swap内存泄漏实例分析
  • Babylon.js引擎(二)
  • 【Chipyard】 conda 环境安装与使用
  • k8s在节点上加污点
  • k8s 部署服务常见错误原因