本段内容会写在0篇以外所有的,本人所编写的Threejs教程中
对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久
如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
canvas{
display: block;
}
body {
margin: 0;
overscroll-behavior: none;
}
#btns{
position: absolute;
top:10%;
width: 500px;
height: 100px;
left: 50%;
transform:translateX(-50%);
}
style>
head>
<body>
<div id="btns">div>
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js">script>
<script type="importmap">
{
"imports": {
"three": "../../three.js-master/build/three.module.js"
}
}
script>
<script type="module">
import * as THREE from '../../three.js-master/build/three.module.js';
import {OrbitControls} from "../../three.js-master/examples/jsm/controls/OrbitControls.js";
import {GLTFLoader} from "../../three.js-master/examples/jsm/loaders/GLTFLoader.js";
let scene,renderer,camera,orbitControls;
let loader;
function init(){
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
antialias:true
});
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,50000);
camera.position.set(10,10,10);
orbitControls = new OrbitControls(camera,renderer.domElement);
let helper = new THREE.AxesHelper(5);
scene.add(helper);
let light = new THREE.PointLight();
camera.add(light);
scene.add(camera);
scene.background = new THREE.Color("#878787");
loader = new GLTFLoader();
}
function addMesh(){
loader.load("./SimpleSkinning.gltf",(gltf)=>{
console.log(gltf);
scene.add(gltf.scene);
});
loader.load("./Parrot.glb",(glb)=>{
console.log(glb);
let model = glb.scene;
model.scale.setScalar(0.1);
model.position.y += 3;
scene.add(model);
})
loader.load("./glTF/MaterialsVariantsShoe.gltf",(gltf)=>{
scene.add(gltf.scene);
let model = gltf.scene;
model.position.z = 3;
model.scale.setScalar(10);
})
}
function render(){
renderer.render(scene,camera);
requestAnimationFrame(render);
}
init();
addMesh();
render();
script>
body>
html>
以上模型文件均可在官方开发包 examples/models/gltf/ 文件夹下找到
本次案例和前面的OBJLoader的案例几乎一致,仅仅将OBJLoader替换为了GLTFLoader,其他格式的文件也均以这样的方式加载
在console中,我们可以看出,gl文件均由这几部分构成
属性名 | 值类型 | 属性说明 |
---|---|---|
animations | THREE.AnimationClip | 模型导出时,可以选择将动画烘焙好之后,保存到模型中,gl格式读取完成后,读取到的动画就是这个,本篇暂时不谈这个对象,在后续动画部分会着重讲解 |
asset | Object | 一个对象,记录了gltf的版本号以及导出方式 |
cameras | [THREE.Camera] | 相机数组,用于读取模型内的相机 |
parser | GLTFParser | 格式转换器,可以无需关注 |
scene | THREE.Group/Object3D/Scene | 这里就是主要的模型数据,可以被添加到scene中 |
scenes | [THREE.Group/Object3D/Scene] | 场景数组,一个模型可能包含有多个场景时可以用到 |
userData | Object | 用于保存用户数据的对象 |
所以我们在加载完成模型后,只需要把gltf.scene作为模型对象添加到scene中即可
//直接添加到场景中
scene.add(gltf.scene);
//或做了处理后添加到场景中
let model = glb.scene;
model.scale.setScalar(0.1);
model.position.y += 3;
scene.add(model);
//先添加与先处理没有区别,只要你能访问到这个对象即可
scene.add(gltf.scene);
let model = gltf.scene;
model.position.z = 3;
model.scale.setScalar(10);
因为三个模型比例区别较大,所以笔者对三个模型的大小做了基本处理
一般来说,gl文件有三种,单独的一个gltf文件+贴图文件,glb文件+贴图文件,gltf + bin + 贴图文件,贴图文件均为非必须,根据建模师是否在建模过程中使用贴图而定
三种文件没有本质上的区别,只是gltf+bin更详细一些,数据更容易读懂,glb更方便使用一些,一般glb文件可以将贴图文件也附带到这一个文件中
太长了,各位看看这篇博主的文章吧,Draco库简析,没兴趣的做个了解即可,有兴趣的可以深入研究一下Draco算法
Draco在threejs中最实用的点就是压缩模型,以笔者的使用经验来说,Draco至少可以将模型压缩到10%甚至更小,文件越大压缩率越高,比如说我一个50M的中高模型,使用Draco技术能压缩到差不多5M甚至更小,但是如果我一个5M的模型,压缩后差不多能到2M这样
https://github.com/CesiumGS/gltf-pipeline
这个插件在上一篇【ThreeJS基础教程-高级几何体篇】2.4 GL格式(GLTF/GLB)模型讲解与其他常用模型格式介绍中已经提到,当你的环境中已经有了gltf-pipeline之后,babylon插件在导出gltf模型的时候,就会增加压缩模型的选项
这个插件也可以单独使用
安装该插件,建议安装到全局\
npm install -g gltf-pipeline
使用时,在模型的文件夹下,shift+右键打开powershell来使用即可
转换gltf和glb文件
gltf-pipeline -i model.gltf -o model.glb
gltf-pipeline -i model.gltf -b
gltf-pipeline -i model.glb -o model.gltf
gltf-pipeline -i model.glb -j
draco压缩
gltf-pipeline -i model.gltf -o modelDraco.gltf -d
其他用法可以去github查看
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
canvas{
display: block;
}
body {
margin: 0;
overscroll-behavior: none;
}
#btns{
position: absolute;
top:10%;
width: 500px;
height: 100px;
left: 50%;
transform:translateX(-50%);
}
style>
head>
<body>
<div id="btns">div>
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js">script>
<script type="importmap">
{
"imports": {
"three": "../../three.js-master/build/three.module.js"
}
}
script>
<script type="module">
import * as THREE from '../../three.js-master/build/three.module.js';
import {OrbitControls} from "../../three.js-master/examples/jsm/controls/OrbitControls.js";
import {GLTFLoader} from "../../three.js-master/examples/jsm/loaders/GLTFLoader.js";
import {DRACOLoader} from "../../three.js-master/examples/jsm/loaders/DRACOLoader.js";
let scene,renderer,camera,orbitControls;
let loader,dracoLoader;
function init(){
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
antialias:true
});
renderer.setSize(window.innerWidth,window.innerHeight);
document.body.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,0.1,50000);
camera.position.set(5,5,5);
orbitControls = new OrbitControls(camera,renderer.domElement);
let helper = new THREE.AxesHelper(5);
scene.add(helper);
let light = new THREE.PointLight();
camera.add(light);
scene.add(camera);
scene.background = new THREE.Color("#878787");
dracoLoader = new DRACOLoader().setDecoderPath("../../three.js-master/examples/js/libs/draco/gltf/");
loader = new GLTFLoader().setDRACOLoader(dracoLoader);
}
function addMesh(){
loader.load("./dracoModel/IridescentDishWithOlives.glb",(glb)=>{
console.log(glb)
scene.add(glb.scene);
glb.scene.scale.setScalar(10);
})
}
function render(){
renderer.render(scene,camera);
requestAnimationFrame(render);
}
init();
addMesh();
render();
script>
body>
html>
这里使用的模型为examples/models/gltf/IridescentDishWithOlives.glb,这个模型为官方案例所使用的模型
检查你的文件是否执行过draco压缩,一般来说,windows自带的模型查看器直接可以打开gltf/glb文件,但是不能直接打开draco压缩后的gltf/glb,可以通过这个判断你的模型是否经历过draco压缩
使用threejs/editor或babylon模型沙盒检查模型是否可以被加载出来,如果这个模型在这两个编辑器内无法被加载出来,那么在你的程序中也依然无法加载,需重新处理模型
如果加载模型时未报错,请查看笔者前面的文章【ThreeJS基础教程-高级几何体篇】2.2 加载模型,加载模型时的常见错误
BufferGeometry介绍