相关文章推荐
小胡子的羽毛球  ·  隐藏相册怎么设置密码_手机_隐私_保护·  12 月前    · 
纯真的圣诞树  ·  北京:严禁违规参加老乡会、校友会、战友会-- ...·  1 年前    · 
温文尔雅的橡皮擦  ·  国漫女神3D合集!旧番_哔哩哔哩_bilibili·  1 年前    · 
天涯  ·  请问notion怎么合并单元格? - 知乎·  2 年前    · 
高兴的太阳  ·  Amazon Live·  2 年前    · 
Code  ›  Threejs进阶之三:通过GUI修改gltf模型(摩托车)颜色开发者社区
gui 摩托车 threejs
https://cloud.tencent.com/developer/article/2276763
欢快的茶叶
11 月前
九仞山

Threejs进阶之三:通过GUI修改gltf模型(摩托车)颜色

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
九仞山
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > Threejs进阶之三:通过GUI修改gltf模型(摩托车)颜色

Threejs进阶之三:通过GUI修改gltf模型(摩托车)颜色

作者头像
九仞山
修改 于 2023-05-19 09:33:06
5K 1
修改 于 2023-05-19 09:33:06
举报
文章被收录于专栏: 前端漫步

上一节我们对摩托车的场景进行了优化,添加了聚光灯及阴影等效果,这一节我们继续对摩托车场景进行优化,我们通过GUI来控制摩托车各个部位颜色的修改 先看下修改后的最终效果

引入GUI

在motor3d.js中通过import引入GUI插件

代码语言: javascript
复制
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js' //引入GUI

motor03.gltf的组成

在对gltf模型进行修改之前,我们需要先了解下这个模型的组成,我们可以通过在控制台打印该模型的方式查看其文件结构,也可以在threejs官网通过editor功能查看。这里我们通过控制台打印发现该模型一共有8个Mesh组成,我们可以在里面找到哪个Mesh是车身,哪个或哪几个Mesh是车架,然后,我们通过获取这些Mesh来对其颜色进行修改。

创建车身材质

定义一个bodyMaterial变量,用于接收Threejs的材质对象,这里我们使用Threejs提供的物理网关材质MeshPhysicalMaterial,这个材质是基于物理渲染,也就是PBR技术,效果更加逼真,能模拟物体表面的漫反射、镜面反射效果; 先来了解下MeshPhysicalMaterial材质的一些属性 .metalness 金属度属性.metalness表示材质像金属的程度. 非金属材料,如木材或石材,使用0.0,金属使用1.0,中间没有(通常). 默认 0.5. 0.0到1.0之间的值可用于生锈的金属外观。如果还提供了粗糙度贴图.metalnessMap,则两个值都相乘 .roughness 粗糙度属性.roughness材质的粗糙程度. 0.0表示平滑的镜面反射,1.0表示完全漫反射. 默认 0.5. 如果还提供粗糙度贴图.roughnessMap,则两个值相乘 .clearcoat 表示clear coat层的强度,范围从0.0到1.0m,当需要在表面加一层薄薄的半透明材质的时候,可以使用与clear coat相关的属性,默认为0.0 .clearcoatRoughness clear coat层的粗糙度,由0.0到1.0。 默认为0.0 .metalnessMap和.roughnessMap 金属度贴图.metalnessMap和粗糙度贴图.roughnessMap 金属度贴图.metalnessMap纹理的蓝色通道用于改变材料的金属度 粗糙度贴图.roughnessMap纹理的绿色通道用于改变材料的粗糙度 Clearcoat Clearcoat: Clearcoat可以在不需要重新创建一个透明的面的情况下实现类似于车漆,碳纤,被水打湿的表面的材质需要在面上再增加一个透明的,具有一定反光特性的面。而且这个面说不定有一定的起伏与粗糙度等类似的效果 定义车身材质

代码语言: javascript
复制
// 车身材质
let bodyMaterial = new THREE.MeshPhysicalMaterial({
  color: "#6e2121",
  metalness: 1, 
  roughness: 0.5, 
  clearcoat: 1.0, 
  clearcoatRoughness: 0.03, //clear coat层的粗糙度,由0.0到1.0。 默认为0.0 
})

创建车架、车座、轮胎及把手材质

用上面同样的方法,创建车架、车座、轮胎及把手材质,代码如下

代码语言: javascript
复制
// 车架
let frameMaterial = new THREE.MeshPhysicalMaterial({
  color:"#c0c0c0",
  metalness:1,
  roughness:0.5,
  clearcoat:1.0,
  clearcoatRoughness:0.03
// 车座
let saddleMaterial = new THREE.MeshPhysicalMaterial({
  color:"#5E2612",
  metalness:0,
  roughness:1
  // clearcoat:1,
  // clearcoatRoughness:1
// 轮胎
let tireMaterial = new THREE.MeshPhysicalMaterial({
  color:"#000000",
  metalness:0,
  roughness:1,
  clearcoat:0,
  clearcoatRoughness:0.33
// 把手
let handleMaterial = new THREE.MeshPhysicalMaterial({
  color:"#000000",
  metalness:0,
  roughness:1,
  clearcoat:0,
  clearcoatRoughness:0.33
})

定义initGUI() 方法

定义一个对象用于存储各个部分的颜色 首先我们在initGUI()方法中先定义一个对象,这个对象包含上面各个部分的颜色

代码语言: javascript
复制
initGUI() {
    var obj = { 
        bodyColor: '#6e2121',// 车身颜色
        frameColor:'#c0c0c0',// 车架颜色
        saddleColor:'#5E2612',// 车座颜色
        tireColor:'#000000' ,// 轮胎颜色
        handleColor:'#000000' ,// 车把颜色
        glassColor: '#aaaaaa', 
}

实例化一个GUI 通过 const gui = new GUI() 来实例化一个GUI 添加车身颜色控制面板 利用gui的.addColor()方法将obj对象绑定到GUI中,并对其命名,然后其onChange()事件中监听用户点击的颜色值,并将该值赋值给上面定义的车身材质

代码语言: javascript
复制
gui.addColor(obj, "bodyColor").name('车身颜色').onChange((value) => {
   bodyMaterial.color.set(value)
})

刷新浏览器,可以看到在右上角已经出现了GUI的控制面板,点击车身颜色,可以弹出颜色面板 添加车架、车座、轮胎及把手的控制面板 用同样的方法添加车架、车座、轮胎及把手的控制面板

遍历模型,修改模型各Mesh的颜色

通过上面的代码,我们已经将GUI添加到了屏幕上, 但是我们在弹出的颜色窗口中点击修改颜色时,三维场景中的摩托车对应的部位并没有修改颜色,这是因为我们还没有将上面定义的Mesh材质与模型中的Mesh关联。

.traverse递归遍历模型

Threejs为我们提供了一个递归遍历的方法.traverse,使用它可以遍历很方便的获取我们需要的Mesh,traverse提供了一个回调函数,我们在traverse的回调函数中通过判断对象的name属性来获取模型的各个部分。在我们之前写的 addGLTFModel()方法中使用traverse方法,通过if语句判断模型的名称,找到对应的模型名称后,将上面定义的各个材质赋值给模型对应部分的material属性,将bodyMaterial属性赋值给模型的车身

代码语言: javascript
复制
 // 加载模型
  addGLTFModel(modelName) { 
    return new Promise((resolve,reject) => {
      const loader = new GLTFLoader().setPath('3dModels/')
      loader.load(modelName,(gltf) =>{ 
        const motorModel = gltf.scene 
        motorModel.traverse(obj => {
          if(obj.name === "网格457") {
            // 车身
            obj.material = bodyMaterial
          } else if (obj.name === "网格457_1") {
            // 车灯
            // obj.material = glassMaterial
          } else if (obj.name === "网格457_2") {
            // 座位
            obj.material = saddleMaterial
          } else if (obj.name === "网格457_4") {
            // 车把
            obj.material = handleMaterial
          } else if (obj.name === "网格457_3" || obj.name === "网格457_5" || obj.name === "网格457_6") {
            // 车架
            obj.material = frameMaterial
          } else if (obj.name === "网格457_7") {
            // 轮胎
            obj.material = tireMaterial
          } else {
          obj.castShadow = true;
        this.scene.add(motorModel)
        resolve(this.modelName + '模型添加成功')
 
推荐文章
小胡子的羽毛球  ·  隐藏相册怎么设置密码_手机_隐私_保护
12 月前
纯真的圣诞树  ·  北京:严禁违规参加老乡会、校友会、战友会--反腐倡廉-人民网
1 年前
温文尔雅的橡皮擦  ·  国漫女神3D合集!旧番_哔哩哔哩_bilibili
1 年前
天涯  ·  请问notion怎么合并单元格? - 知乎
2 年前
高兴的太阳  ·  Amazon Live
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号