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

threejs(六)加载外部模型 .gltf

一、GLTF科普篇

1、三维建模软件简介

3D美术常用的三维建模软件,比如Blender、3dmax、C4D、maya等等
可以用Blender软件导出绘制好的三维模型,也可以打开和预览gltf格式文件模型。

blender可以导出不同形式的 gltf 模型

  • 单独.gltf文件
  • 单独.glb文件
  • .gltf + .bin + 贴图文件

2、GLTF格式简介

  1. GLTF格式是三维模型格式
  2. .gltf格式文件几乎可以包含所有的三维模型相关信息的数据,比如模型层级关系、PBR材质、纹理贴图、骨骼动画、变形动画
  3. GLTF文件就是通过JSON的键值对方式来表示模型信息,比如meshes表示网格模型信息,materials表示材质信息…
{"asset": {"version": "2.0",},
...
// 模型材质信息"materials": [{"pbrMetallicRoughness": {//PBR材质"baseColorFactor": [1,1,0,1],"metallicFactor": 0.5,//金属度"roughnessFactor": 1//粗糙度}}],// 网格模型数据"meshes": ...// 纹理贴图"images": [{// uri指向外部图像文件"uri": "贴图名称.png"//图像数据也可以直接存储在.gltf文件中}],"buffers": [// 一个buffer对应一个二进制数据块,可能是顶点位置 、顶点索引等数据{"byteLength": 840,//这里面的顶点数据,也快成单独以.bin文件的形式存在   "uri": "data:application/octet-stream;base64,AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAC/.......}],
}

3、.bin文件

二进制文件

4、.glb

.glb就是gltf格式的二进制文件。比如你可以把.gltf模型和贴图信息全部合成得到一个.glb文件中,.glb文件相对.gltf文件体积更小,网络传输自然更快

二、加载.gltf文件

效果

在这里插入图片描述

关键点

  1. 引入GLTFLoader.js
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
  1. 执行new GLTFLoader()就可以实例化一个gltf的加载器对象
// 创建GLTF加载器对象
const loader = new GLTFLoader();
  1. 通过gltf加载器方法.load()就可以加载外部的gltf模型
loader.load( 'gltf模型.gltf', function ( gltf ) {console.log('控制台查看加载gltf文件返回的对象结构',gltf);console.log('gltf对象场景属性',gltf.scene);// 返回的场景对象gltf.scene插入到threejs场景中scene.add( gltf.scene );
})
  1. 相机选择:要近大远小的规律的话,就采用透视投影相机PerspectiveCamera;如果不需要模拟人眼远小近大的投影规律,可以选择正投影相机OrthographicCamera
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);
  1. 相机参数设置:可以借助 Blender 看下美工的模拟图是多大,然后给相机设置 .position,比如下面这张图就可以设置相机位置在200
camera.position.set(200, 200, 200);

在这里插入图片描述
6. 让位置在canvas画布居中:调 camera.lookAt()。如果美术建模,把工厂整体居中,也就是说模型的几何中心,大概位于世界坐标原点。你设置camera.lookAt(0,0,0),相机视线指向坐标原点。
注意相机控件OrbitControls会影响lookAt设置,注意手动设置OrbitControls的目标参数


camera.lookAt(100, 0, 0); // 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement); // 相机控件.target属性在OrbitControls.js内部表示相机目标观察点,默认0,0,0
controls.target.set(100, 0, 0);
controls.update(); //update()函数内会执行camera.lookAt(controls.targe)
  1. 解决加载 gltf 格式模型纹理贴图和原图不一样的问题
renderer.outputEncoding = THREE.sRGBEncoding; // 解决加载 gltf 格式模型纹理贴图和原图不一样的问题

完整代码

index.js

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';import  model  from './model.js';//模型对象//场景
const scene = new THREE.Scene();
scene.add(model); //模型对象添加到场景中//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);//光源设置
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(400, 200, 300);
scene.add(directionalLight);
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);//渲染器和相机
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);// 解决加载 gltf 格式模型纹理贴图和原图不一样的问题
renderer.outputEncoding = THREE.sRGBEncoding;// 渲染循环
function render() {renderer.render(scene, camera);requestAnimationFrame(render);
}
render();const controls = new OrbitControls(camera, renderer.domElement);// 画布跟随窗口变化
window.onresize = function () {renderer.setSize(window.innerWidth, window.innerHeight);camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();
};

model.js

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';// *实例化加载器对象
const loader = new GLTFLoader();
const model = new THREE.Group();loader.load("../../工厂.gltf", function (gltf) {console.log('gltf', gltf);model.add(gltf.scene);
})export default model

三、相机初始位置的调试技巧

1、修改相机位置

通过OrbitControls旋转和缩放,本质上就是在改变透视投影相机PerspectiveCamera的位置.position
在render中,打印 camera.position 即可查看相机位置改变,这样就可以根据这个位置设置相机初始化时的位置

function render() {requestAnimationFrame(render);// 浏览器控制台查看相机位置变化console.log('camera.position',camera.position);
}
render();
camera.position.set(200, 200, 200);//第1步:根据场景渲染范围尺寸设置
camera.position.set(-144, 95, 95); //第2步:通过相机控件辅助设置OrbitControls

2、改变相机观察目标

function render() {requestAnimationFrame(render);// 浏览器控制台查看controls.target变化,辅助设置lookAt参数console.log('controls.target',controls.target);
}
render();
// camera.lookAt(0, 0, 0);
const x = -1.2,y = -15,z = 10;//通过OrbitControls辅助设置
camera.lookAt(x, y, z);// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 相机控件.target属性在OrbitControls.js内部表示相机目标观察点,默认0,0,0
// console.log('controls.target', controls.target);
controls.target.set(x, y, z); //与lookAt参数保持一致
controls.update(); //update()函数内会执行camera.lookAt(controls.target)

四、程序命名(程序与美工的协作)

美工提供的三维模型中的名称,可以在 threejs 中查看,并可通过名称获取节点

1、查看3D模型树结构 ---- gltf.scene

加载gltf模型,通过gltf.scene可以获取模型的数据,你可以通过浏览器控制打印gltf.scene,然后和你三维建模软件中的模型目录树对比,比较两者的结构是否相同。

模型父对象节点可以用Object3D对象表示,也可以用组对象Group表示。
通过.children属性可以查看一个父对象模型的的所有子对象。
通过.name属性可以查看模型节点的名称

loader.load("./简易小区.glb", function (gltf) { console.log('场景3D模型树结构', gltf.scene);model.add(gltf.scene);
})

在这里插入图片描述
在这里插入图片描述

2、根据名称查看节点 ---- getObjectByName

// 返回名.name为"1号楼"对应的对象
const nameNode = gltf.scene.getObjectByName("1号楼");
nameNode.material.color.set(0xff0000);//改变1号楼Mesh材质颜色

五、遍历模型节点 traverse

1、递归遍历所有模型节点批量修改材质

// 递归遍历所有模型节点批量修改材质
gltf.scene.traverse(function(obj) {if (obj.isMesh) {console.log('gltf默认材质',obj.material);}
});

2、批量修改gltf所有Mesh的材质

gltf.scene.traverse(function(obj) {if (obj.isMesh) {// 重新设置材质obj.material = new THREE.MeshLambertMaterial({color:0xffffff,});}
});

3、代码方式解决多个mesh共享材质的问题

//用代码方式解决mesh共享材质问题
gltf.scene.getObjectByName("小区房子").traverse(function (obj) {if (obj.isMesh) {// .material.clone()返回一个新材质对象,和原来一样,重新赋值给.material属性obj.material = obj.material.clone();}
});
mesh1.material.color.set(0xffff00);
mesh2.material.color.set(0x00ff00);
http://www.dtcms.com/a/497134.html

相关文章:

  • 达人设计网官方网站工信部官网备案查询系统
  • soho外贸网站建设做外贸推广要做哪些平台
  • 网站建设 中企动力西安竹子建站邀请码
  • C++----变量存储空间
  • 天津正规网站建设调试公司wordpress recaptcha
  • 如果让你建设网站之前你会想什么seo关键词优化软件合作
  • 阿里巴巴吧网站怎么做开发网站的过程
  • 怎么做网站例如京东口碑好的网站推广软件
  • 百度网站地图天津网站建设-中国互联
  • 高效学习闭环:如何导出功能构建可复用的知识库?
  • 网站建设汇报评估关键词推广是什么意思
  • 外贸商城网站开发静安手机网站建设
  • 怎么做代理网站项目管理软件免费
  • 网站设计计划漳州模板网站建设
  • 网站管理与维护方案开个人网站如何赚钱
  • 哪里有做网站排名优化教学成果申报网站 化工专业建设
  • 做网站推广员工中企动力是不是国企
  • 外包网站都有哪些网络考试
  • 律师行业做网站的必要性珠海市住房和城乡建设局网站
  • 做服装到哪个网站拿货品质好中国建筑网官网企业愿景
  • Windows 固定 U 盘或移动硬盘的盘符
  • 做足彩推荐赚钱的网站手机访问跳转手机网站
  • 装修公司网站建设长春火车站照片
  • Linux 教程:如何查看服务器当前目录中的文件
  • 做网站备案与不备案的区别网站申请备案流程
  • Datawhale25年10月组队学习:math for AI+Task2线性代数
  • 南昌网站建设基本流程濮阳网站建设专家团队
  • 常州网站建设设计建设视频网站要求吗
  • 自己怎么搭建个人博客网站爱站工具包手机版
  • 石家庄微网站个人博客是什么