webGL建模、调优和未来的发展

直奔主题,秀一下效果图~
使用threejs加载工厂模型和霸王龙模型

一.模型

1.使用建模软件

比如3D Max、maya等等

2.模型网站

比如建模网等等
可以找到各种各样的模型,工业的,生活的,生物,机械等等

3.格式转换

(1)一般下载后的模型是obj文件,而对web友好的是gltf/glb
可以使用 obj2gltf 这个npm包来进行格式转换
可以作为JS库使用,也可以当做命令行工具使用
仓库地址:https://github.com/AnalyticalGraphicsInc/obj2gltf

(2)预览模型
.obj文件 mac电脑的看图软件默认就支持的
gltf推荐一个在线查看工具
https://gltf-viewer.donmccurdy.com/

因为文本主要讲解webgl加载模型和调优的内容,所以关于如何建模等内容,就不过多介绍;

二.Threejs加载gltf模型的基本流程和注意点

1.threejs中基本的一些概念 略过

相机camera
场景scene
材质material
光源
纹理
贴图
等等

2.threejs加载gltf模型的loader ~ GLTFLoader

加载第一步中的gltf模型文件
加载成功的回调函数,我们可以拿到模型对象
就可以随意进行操作了,比如缩放、位移、旋转等等

1
2
3
4
5
6
7
8
9
const loader = new THREE.GLTFLoader().setPath("Model/");
// 加载霸王龙模型
loader.load("bawanglong-processed.glb", function (gltf) {
gltf.scene.scale.set(0.1, 0.1, 0.1);
gltf.scene.position.set(0, 0, 30);
scene.add(gltf.scene);
}, undefined, function (e) {
console.error(e);
});

3.threejs的render

添加antialias抗锯齿参数

4.设置像素比setPixelRatio

很多国企和工业的“智慧城市”“智慧工厂”等等,会使用屏幕墙,需要设置像素比

5.调试技巧

(1)load方法第三个参数,失败的回调
看看模型的加载是否成功
(2)引入OrbitControls轨道控制器
通过鼠标和键盘看看模型试试显示是否正常
(3)增加辅助线和光源

1
2
3
4
5
6
7
8
9
// XYZ轴 辅助线
const axesHelper = new THREE.AxesHelper(60);
scene.add(axesHelper);
// 相机视椎体 辅助线
const helper = new THREE.CameraHelper(camera);
scene.add(helper);
// 半球光
const hemisphereLight = new THREE.HemisphereLight(light, 60);
scene.add(hemisphereLight);

等等

6.给模型增加交互

(1)Raycaster 射线
threejs文档有个demo
射线穿过threejs的模型,拿到一组对象的数组,一般最上层的对象就是我们需要交互的对象;
拿到对象之后,就可以随心所欲的进行各种处理了,缩放,位移,旋转等等

(2)改变视角
推荐一个第三方库tweenjs
比如,我这次的demo实现的一个简单的智慧工厂的效果
点击房顶,房顶会向上移动一段距离,然后点击厂房内部模型,视角会跳到该点,达到一种身临其境的效果。

三.GLTF模型的压缩和优化

1.为什么要压缩?

(1)由于threejs本身性能不是很好,然后稍微复杂一点的模型都比较大,几十兆上百兆,web页面光load一个模型,电脑的风扇就能听到“呜呜呜”的狂转了,所以优化模型大小,是非常有必要的;
(2)比如我这个demo中
工厂模型,obj源文件23.3M,gltf文件23.2M
霸王龙模型,obj文件282.9M,glb文件202.4M

2.压缩库

(1)谷歌出的神器,C++库 ~ Darco
而且谷歌也提供了编译好的wasm文件,前端js可以直接使用,省去了自己编译的各种坑

(2)关于wasm的使用,可以看我个人博客之前写的
《wasm入门》

3.命令行工具

(1)npm包 ~ gltf-pipeline
https://www.npmjs.com/package/gltf-pipeline
压缩的原理就是使用上面的Draco库

(2)命令
gltf-pipeline -i name.gltf -d -s
-d 压缩
-s 分离,会产生一个.gltf/.glb文件和一个.bin文件

(3)压缩效果
工厂模型,obj源文件23.3M,gltf文件23.2M, 压缩后7.4M
霸王龙模型,obj文件282.9M,glb文件202.4M, 压缩后13M左右

4.配置Darco解码器

(1)上一步压缩后的文件不能直接使用,需要配置解码器

1
2
3
4
5
6
<script src="./node_modules/three/examples/js/loaders/DRACOLoader.js"></script>

const loader = new THREE.GLTFLoader().setPath("Model/");
// setDecoderPath设置Draco的wasm文件所在的目录
THREE.DRACOLoader.setDecoderPath("./javascript/");
loader.setDRACOLoader(new THREE.DRACOLoader());

(2)成功调用的结果如下

四.主流webgl库对比

1.Threejs,star 5万5千+
https://github.com/mrdoob/three.js/
3D渲染
性能不是很好,API比较复杂
最近官方文档增加了中文版本

2.Babylon.js, star 1万+
游戏和物理引擎
https://github.com/BabylonJS/Babylon.js

3.xeogl.js, star 600+
https://github.com/xeolabs/xeogl
高性能的3D渲染
好像是webGL委员会的大佬写的,API简单易用,性能也超级好

4.cesium.js, star 4900+
https://github.com/AnalyticalGraphicsInc/cesium
适合做GIS地理信息系统

五.webGL未来的发展

1.九月份W3C在日本福冈举办了TPAC会议,有两个关于webGL的提案
两个方案都在解决同一个问题:

如何更方便的在web上展示3D模型

华为余枝强提出的HTML 3D element方案 ~ X-model提案

他认为,3D已经成为了一种广受欢迎的表现形式,人们从纯展示逐步过渡到希望与现实世界有所互动。

(1)目前云端3D内容服务器和客户端交互面临3大挑战

1)目前只有底层的3D接口,很不方便
2)web 3D 性能不够好
3)在AR支持层面上,用于内容及交互过程没有一种简单的实现方式

为此他提出了xmodel这个标签,希望可以用一行代码来实现3D+AR的优质用户体验,并且可以在不同设备之间进行交互。

1
2
3
4
5
6
<xmodel src="mycar.gltf" ></xmodel>
// Attributes
// mode = “ar” / mode = "3d" 进入AR或者3D展示模式
// autoplay = true 自动播放动画
// live = true 实时模式,可以控制物体的方向
// syncState 同步到其他设备

他希望xmodel作为web 3D-AR的high level接口,成为一个3D标签。

下面的图中展示了他对于xmodel实现结构的构想:

Microsoft的Sushanth提出的Native GLTF

Sushanth提出的这个提案是源于 W3C workshop 的 web games 中 Yasushi Ando提出的关于在浏览器中原生支持GLTF的讨论(https://www.w3.org/2018/12/games-workshop/papers/new-html-3D-element.txt).

1
2
3
4
5
<scene controls vrenabled width="300">
<source src="http://example.com/Monster_small.glb" type="model/gltf-binary" media="(min-width: 320px)">
<source src="http://example.com/Monster.gltf" type="model/gltf+json" media="(min-width: 640px)">
Message for unsupported browsers
</scene>

使用这样的方案,glTF将允许JavaScript操作场景、变换位置以及触发动画。因此他希望能够在整个社区内讨论该提案的价值以及API形态。

他认为,如果实现了对glTF的原生支持,将在如下方面获益:

(1)性能
单独的一个glTF文件不止可以描述单独的一个3D物体,它甚至可以描述整个场景。因此如果可以原生支持对glTF文件描述场景的遍历及渲染,就可以利用硬件的能力(多线程及图形API)从而追求更高的性能及更为丰富的场景。

(2)模型保护
如果有了原生支持,类似EME(Encrypted Media Extensions)这样的解决方案就可以用来对3D资产进行保护,这也是众多开发者所关心的

(3)Foreign Object
和SVG中的Foreign Object这一概念一样,未来我们可以允许将HTML的内容作为3D物体的材质,在3D场景中进行渲染。

(4)Dev Tools Integration
浏览器集成的开发者工具(F12)可以很大程度上提升HTML开发者的开发体验,未来我们也可以同样地在集成的开发者工具中,对场景进行debug,查看节点的属性或观察性能指标等。

(5)3D IFrames
当3D在未来普及后,我们甚至可以想象,在AR/VR的场景中,一部分空间由domain1.com提供而另外一部分由domain2.com提供。这一模型和2D中的iframes很类似,这种可以让浏览器理解不同域的内容在场景中的嵌套会成为构建虚拟实境的基石。

model-viewer

最近逛GitHub看到谷歌出了这个神器,来简化web上的3D模型展示
可以非常方便的加载gltf/glb文件

1
2
3
4
5
6
7
8
9
10
<!doctype html>
<html>
<head>
<title>3D Test</title>
<script src="path/to/bundled/model-viewer.js"></script>
</head>
<body>
<model-viewer src="path/to/model.gltf"></model-viewer>
</body>
</html>

或者

1
2
3
4
import '@google/model-viewer';
const model = document.createElement('model-viewer');
model.src = 'path/to/model.gltf';
document.body.appendChild(model);

我博客上新加的3D小机器人,就是用的这个库~

不知不觉又写到凌晨两点多,暂时先写这么多吧!

END

同时欢迎关注我的个人微信公众号:

分享到:
Disqus 加载中...

如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理