问答媒体

用户名  找回密码
 立即注册
帖子
热搜: 活动 交友 discuz
查看: 149|回复: 14

模型导入之优雅姿势——glTF

[复制链接]

1

主题

2

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-12-3 19:36:13 | 显示全部楼层 |阅读模式
没错我现在算是入坑图形学了,这是我在知乎的第一篇有关文章。我决定还是分享一些自己的图形学随笔,也许没那么高端,但一定是原创。既是展示自己,也说不定能帮到别人。大佬若有看到瑕疵还望轻喷~
这篇文章适合正在学图形学,尤其是在造渲染器轮子的同学看。
这篇文章并没有讲实质的图形学技术,但应该还是很有价值的,如果你之前没听说过glTF的话。
自己动手造轮子写渲染器的人都会知道,很麻烦的原因之一,就是需要自己写模型导入的部分。
这部分并不能简单地使用一行代码调库来解决,因为最终你总得将parse过的模型数据(无论是你自己parse的,还是调库parse的)填入你自己定义的Primitive, Material, Mesh之类的对象里面。
这时通常会有2种选择:

  • 使用万能的assimp库导入,它支持常见的3D模型/场景格式的解析。然后自己再从assimp定义的中间格式填入自己的类里面。这样可以省一部分力,因为我自己是懒得写parser的,即使自己写了,完整性也会差很多,到时导入可能会遇到各种不兼容的解析失败问题。
于是当时我就用assimp从obj文件里仅读入网格数据,满足了当时的需求。
后来我实现了PBR材质,模型自然也就需要三种贴图(使用metallic workflow)。我也想从obj文件读出有关贴图文件的信息,这时就发现obj格式里的贴图格式还是传统的三种specular, diffuse, glossiness(用这三种贴图也是可以实现PBR的,不过就不是metallic workflow了,而是specular workflow,计算出射光radiance的公式会稍有不同)
后来学习了更多的图形知识,就知道了场景中的物体,还需要包含好多好多的属性,比如emissive map,比如这个物体是不是双面都看得到的(也就是禁不禁用face culling),比如这个物体是不是透明的(也就是使用blend还是depth test)。这些属性,obj都没有定义良好。当然了,obj附属的mtl文件,是可以添加自定义的属性字段的,但仍觉得不妥:谁知道3D建模者和你自己用的字段是不是一样的呢?
2. 第二个解决方案就是,自己定义一种格式,存储需要的属性。各游戏引擎肯定是这样。但这不应该是一个小轮子所重点关注的地方,而且我更希望能使用公开统一的格式——别人建模导出了,我的渲染器就能用。
所以这个方法也被我放弃了。一直以来,我的小轮子就只能画些uv球,平面,以及单个3D模型。而我一直有个愿望,就是把那个著名的Sponza场景加载进来。
glTF

直到我在网上找到了glTF(gl Transmission Format)。
这是由Khronos组织定义的一种交换格式,也就是制定OpenGL标准的那个组织,足见其靠谱程度。
glTF也被称作“3D界的jpeg”,足见其标准化程度。
接着读了下它的介绍,马上就爱了:

  • glTF 2.0原生支持metallic workflow的PBR材质
  • glTF格式其实是一个文件夹,包含一个基于json的属性文件,一个二进制文件用来放顶点数据,以及各种图片作为纹理。这样解析起来就很简单。事实上,使用rapidjson库,我用1天就写好了场景加载的代码(又用了1天调试)。
  • 它兼顾了可读性与加载速度。依我现在的使用经验来看,这部分体现在顶点的存储上。
顶点数据再也不像obj文件那样一行一个顶点,而是与OpenGL中vertex buffer相兼容的方式用二进制存储。甚至表示数据类型的int值,都与opengl里的各枚举类型数值(如GL_FLOAT)相同。这意味着只要提前商量好格式,可以直接把顶点数据从文件拷到内存,再从内存拷到显存。
(这并没有降低可读性,因为即使是一行一个顶点,人也无法直接看出存的是啥。。)

  • 由于是面向渲染器的格式,诸如上文所提到的那些属性,glTF都定义了。同时,通过读glTF的specification,我也了解到3D模型该有的其他属性。
格式虽好,但若大家都不用,那也是白搭。好在Blender, Windows 10自带的3D Viewer等等查看工具,都是支持glTF的。而且在glTF的GitHub页面的Sample models里,已经有足够复杂的场景了,包括我想要的Sponza。
另外,在glTF的GitHub页面顺藤摸瓜,我发现了https://sketchfab.com/这个网站,许多模型质量都挺好,也都支持glTF格式下载,目前看来模型资源是不成问题了。
最后还是放几张自家小轮子渲染的图吧:



走样很严重 软阴影噪点也很多的Sponza


Damaged Halmet 来自glTF GitHub
https://www.zhihu.com/video/1215757547283628032
总结

如开头所说,这篇文章并没有讨论图形学的技术,但glTF真的很值得了解:易学,易parse,支持广泛,可以让渲染器从此摆脱assimp...为何不用?我甚至觉得应该让3D从业者一开始就接触它而不是obj...
回复

举报

0

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-12-3 19:36:19 | 显示全部楼层
感谢,正好我觉得assimp太麻烦,回去查一下glTF,thx
回复

举报

1

主题

4

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-12-3 19:36:48 | 显示全部楼层
不知道应该吧这种glft的文件如何导入常用的max、maya、c4d中,还请答主指教一下
回复

举报

2

主题

6

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2022-12-3 19:37:32 | 显示全部楼层
最近在搞PBR,也遇到了格式不统一的问题,文章正好带入门了,很好,赞一个。
[机智]
回复

举报

3

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2022-12-3 19:38:23 | 显示全部楼层
请教答主,有没有opengl加载gltf文件的demo代码呢,这块网上找了很多资料都没有找到,或者有相应的资料可以分享一下吗?万分感谢了
回复

举报

1

主题

2

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2022-12-3 19:39:09 | 显示全部楼层
你可以看一下这个文件: https://github.com/songchaow/toy-renderer/blob/master/toy_tracer/core/glTFLoader.cpp
回复

举报

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-12-3 19:39:47 | 显示全部楼层
我也想知道 答主能回答一下吗
回复

举报

0

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-12-3 19:40:46 | 显示全部楼层
这种glft的文件如何导入常用的max、maya、c4d中,还请答主指教一下,不然没有学的必要
回复

举报

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2022-12-3 19:41:10 | 显示全部楼层
gltf主要是为3d渲染器设计的。建模这块的话,可能别的格式会主流一些
回复

举报

2

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2022-12-3 19:42:10 | 显示全部楼层
gltf主要是为3d渲染器设计的。建模这块的话,可能别的格式会主流一些
回复

举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver| 手机版| 小黑屋| 问答媒体

GMT+8, 2025-3-16 20:14 , Processed in 0.173598 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2020, LianLian.

快速回复 返回顶部 返回列表