技术标签: OpenGL gltf json glb 三维图形
目录
4. buffers, bufferViews, accessors
gltf采用json格式描述3D模型的结构,主要用来解决3D模型在网络中的高效传输问题。
gltf 主要包括以下元素。
名称 | 含义 |
scenes, nodes | 场景基本结构 |
cameras | 相机 |
meshes | 三维几何 |
buffers, bufferViews, accessors | 数据块 |
materials | 材质 |
textures, images, samplers | 纹理,图片,采样器 |
skins | 蒙皮 |
animations | 动画 |
gltf中元素的关系图如下:
gltf中可以定义若干个场景(scenes),每个场景引用若干个节点(nodes),节点以树形结构的方式组织。
节点(nodes)可以包含坐标转换。该转换可以用平移(translation),旋转(rotation),缩放(scale)分别表示。
"nodes": [
{
"translation": [ 0,0,0 ],
"rotation": [ 0,0,0,1 ],
"scale": [ 1,1,1 ]
...
}
]
也可以通过4*4的矩阵(matrix)表示坐标转换。即:
"nodes": [
{
"matrix": [
1,0,0,0,
0,1,0,0,
0,0,1,0,
5,6,7,1
],
...
}
]
其中,矩阵(matrix)与表示平移(translation),旋转(rotation),缩放(scale)的矩阵之间,存在如下关系:
matrix = translation * rotation * scale
node还可以包含三维几何(mesh)和相机(camera)的信息。在渲染中,这些信息与上述变换矩阵相乘,就可以确定在场景中的位置。
"nodes": [
{
"mesh": 4,
...
},
{
"camera": 2,
...
},
]
三维几何(meshes)中可以包含多个片元(primitives)。 片元(primitives)包含了渲染需要信息。片元(primitives)中包含的信息如下:
字段 | 含义 |
---|---|
mode | 表示几何类型。如点(POINTS),线(LINES) , 或者三角形(TRIANGLES) |
attributes | 表示几何顶点信息。如位置(POSITION)和法线(NORMAL) |
indices | 表示几何顶点索引 |
material | 表示材质信息 |
三维几何(meshes)的例子如下:
"meshes": [
{
"primitives": [
{
"mode": 4,
"indices": 0,
"attributes": {
"POSITION": 1,
"NORMAL": 2
},
"material": 2
}]
}]
buffers包含了场景的几何数据,bufferViews是对buffers中数据的索引,accessors为bufferViews中的数据添加类型和布局。
buffers包含了场景的几何数据,一般是二进制数据的形式。buffers包含的字段如下:
字段 | 含义 |
---|---|
byteLength | 表示二进制数据的长度。 |
uri | 指向二进制数据的地址 |
二进制的几何数据有两种方式存储:一种是通过 base64的压缩后存入gltf文件中,此时字段uri的内容如下:
"buffers" : [
{
"byteLength" : 827640,
"uri" : "data:application/gltf-buffer;base64,AAAB..."
}
]
另一种单独存入以.bin为后缀名的文件中,然后以链接文件的方式接入gltf。此时字段uri的内容如下:
"buffers": [
{
"byteLength": 827640,
"uri": "gltf.bin"
}
]
bufferViews指向buffers中数据的一个片段。 bufferViews包含的字段如下:
字段 | 含义 |
---|---|
buffer | 表示一个二进制数据块,该块中存储了场景中的几何信息。 |
byteOffset | 表示相对buffer块起始位置的偏移。 |
byteLength | 表示了二进制数据的长度。 |
byteStride | 表示数据之间的间隔。 |
target | 表示opengl缓冲区的类型,如ARRAY_BUFFER,ELEMENT_ARRAY_BUFFER。 |
bufferViews的例子如下:
"bufferViews": [
{
"buffer": 0,
"byteOffset": 4,
"byteLength": 28,
"byteStride": 12,
"target": 34963
}]
accessors定义了bufferViews中的数据如何解释。accessors包含的字段如下:
字段 | 含义 |
---|---|
bufferViews | 指向一段二进制数据。 |
byteOffset | 表示相对bufferViews起始位置的偏移。 |
type | 表示数据类型,如"SCALAR","VEC2","MAT3"等。 |
componentType | 表示分量的数据类型,如unsigned short,float等。 |
count | 表示分量的个数。 |
min | 表示分量的最小值。数组的长度必须与分量的个数相同。 |
max | 表示分量的最大值。数组的长度必须与分量的个数相同。 |
accessors的例子如下:
"accessors": [
{
"bufferView": 0,
"byteOffset": 4,
"type": "VEC2",
"componentType": 5126,
"count": 2,
"min" : [0.1, 0.2],
"max" : [0.9, 0.8]
}]
示例
将上述三者结合起来,就可以准确的获取渲染所需的几何信息。如下图:
其中,bufferViews中的数据可以使用glBindBuffer绑定到openGL的缓冲区,accessor可以指定该缓冲区中定义了顶点的属性数据,并通过glVertexAttribPointer告诉顶点着色器(vertex shader)改如何解释和使用该缓冲区中的数据。
材质(materials)描述物体表面的特征,它决定了渲染器该如何渲染该物体。
材质模型 Metallic-Roughness-Model 描述了物体表面材质的金属特征和粗糙程度,是gltf中默认的材质模型。其中,Metallic描述了材质的金属特征,取值在0到1之间。取值越靠近1,表示金属特征越强。Roughness则描述了材质的粗糙程度,取值在0到1之间。取值越靠近1,表示越粗糙。
材质模型Metallic-Roughness-Model是gltf默认使用的材质模型。在gltf中, 对象pbrMetallicRoughness 定义了该模型。
字段 | 含义 |
---|---|
baseColorTexture | 物体表面纹理。 |
baseColorFactor | 颜色RGBA。没有纹理时,该项定义了物体表面颜色。 |
metallicRoughnessTexture | 在颜色的blue分量中,存储了金属程度。在颜色的green分量中,存储了粗糙程度。 |
metallicFactor | 金属程度因子。 |
roughnessFactor | 粗糙程度因子。 |
pbrMetallicRoughness的例子如下:
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1,
"texCoord": 1
},
"baseColorFactor": [ 1.0, 0.75, 0.35, 1.0 ],
"metallicRoughnessTexture": {
"index": 5,
"texCoord": 1
},
"metallicFactor": 1.0,
"roughnessFactor": 0.0
}
}]
material中通过纹理索引(index)和纹理坐标(texCoord)引用纹理。纹理索引(index)是纹理数组中元素的索引号。纹理坐标(texCoord)定义在图元(primitive)在顶点属性中。
有两种类型的相机:透视投影相机和正交投影相机。
透视投影相机(perspective cameras)的定义如下:
字段 | 含义 |
---|---|
aspectRatio | 裁剪面的宽高比 |
yfov | 垂直夹角。可视空间顶面和底面的夹角。 |
zfar | 远裁剪面的位置 |
znear | 近裁剪面的位置 |
透视投影相机(perspective cameras)的示例如下:
"cameras": [
{
"type": "perspective",
"perspective": {
"aspectRatio": 1.5,
"yfov": 0.65,
"zfar": 100,
"znear": 0.01
}
}]
正交投影相机(orthographic cameras)的定义如下:
字段 | 含义 |
---|---|
xmag | 裁剪面宽度的1/2 |
ymag | 裁剪面高度的1/2 |
zfar | 远裁剪面的位置 |
znear | 近裁剪面的位置 |
正交投影相机(orthographic cameras)的示例如下:
"cameras": [
{
"type": "orthographic",
"orthographic": {
"xmag": 1.0,
"ymag": 1.0,
"zfar": 100,
"znear": 0.01
}
}]
材质(materials)中可以使用纹理(textures)指定物体表面的颜色和物理特征。纹理(textures)的定义的字段如下:
字段 | 含义 |
---|---|
source | 图片(images)数组的索引。 |
sampler | 采样器(samplers)数组的索引。 |
纹理(textures)的示例如下:
"textures": [
{
"source": 4,
"sampler": 2
}]
图片(images)的格式为jpg/png等,在纹理(texture)中引用。图片(images)有两种存储方式:
一种是通过base64的压缩成字符串,存入gltf;
"images": [
{
"uri": "data:image/png;base64,iVBORw0K..."
}
]
另一种以链接文件的方式接入gltf。
"images": [
{
"uri": "image01.png"
}
]
采样器(samplers)定义了图片放大或缩小时,如何获取颜色信息,类似于opengl中的设置纹理参数的函数glTexParameter。
采样器(samplers)定义的字段如下:
字段 | 含义 |
---|---|
magFilter | 纹理放大时,如何获取像素颜色。取值有Nearest或Linear |
minFilter | 纹理缩小时,如何获取像素颜色。取值有Nearest或Linear |
wrapS | 如何填充纹理图像左侧或右侧的区域。 |
wrapT | 如何填充纹理图像上方或下方的区域。 |
采样器(samplers)的示例如下:
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987,
"wrapS": 10497,
"wrapT": 10497
}]
文章浏览阅读3.6k次,点赞2次,收藏2次。DELL7080台式机两块硬盘。_没有u盘怎么装ubuntu
文章浏览阅读32次。题面Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conv...
文章浏览阅读2.6w次,点赞21次,收藏112次。机器视觉则主要是指工业领域视觉的应用研究,例如自主机器人的视觉,用于检测和测量的视觉系统等。它通过在工业领域将图像感知、图像处理、控制理论与软件、硬件紧密结合,并研究解决图像处理和计算机视觉理论在实际应用过程中的问题,以实现高效的运动控制或各种实时操作。_工业机器视觉系统的构成与开发过程(理论篇—1
文章浏览阅读5.9w次,点赞32次,收藏58次。legend 传奇、图例。plt.legend()的作用:在plt.plot() 定义后plt.legend() 会显示该 label 的内容,否则会报error: No handles with labels found to put in legend.plt.plot(result_price, color = 'red', label = 'Training Loss') legend作用位置:下图红圈处。..._plt.legend
文章浏览阅读2.2k次,点赞3次,收藏11次。深入理解 C# .NET Core 中 async await 异步编程思想引言一、什么是异步?1.1 简单实例(WatchTV并行CookCoffee)二、深入理解(异步)2.1 当我需要异步返回值时,怎么处理?2.2 充分利用异步并行的高效性async await的秘密引言很久没来CSDN了,快小半年了一直在闲置,也写不出一些带有思想和深度的文章;之前就写过一篇关于async await 的异步理解 ,现在回顾,真的不要太浅和太陋,让人不忍直视!好了,废话不再啰嗦,直入主题:一、什么是异步?_netcore async await
文章浏览阅读6.5w次,点赞166次,收藏309次。当我看到别人的类上面的多行注释是是这样的:这样的:这样的:好装X啊!我也想要!怎么办呢?往下瞅:跟着我左手右手一个慢动作~~~File--->Settings---->Editor---->File and Code Templates --->Includes--->File Header:之后点applay--..._idea作者和日期等注释
文章浏览阅读175次。Netperf是一种网络性能的测量工具,主要针对基于TCP或UDP的传输。Netperf根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求/应答(request/reponse)模式。工作原理Netperf工具以client/server方式工作。server端是netserver,用来侦听来自client端的连接,c..._netperf 麒麟
文章浏览阅读1.1k次,点赞2次,收藏3次。作者| qcrao责编 | 屠敏出品 | 程序员宅基地刚开始写这篇文章的时候,目标非常大,想要探索 Go 程序的一生:编码、编译、汇编、链接、运行、退出。它的每一步具体如何进行,力图弄清 Go 程序的这一生。在这个过程中,我又复习了一遍《程序员的自我修养》。这是一本讲编译、链接的书,非常详细,值得一看!数年前,我第一次看到这本书的书名,就非常喜欢。因为它模仿了周星驰喜剧..._go run 每次都要编译吗
文章浏览阅读1.4k次,点赞4次,收藏2次。0、C++的输入输出分为三种:(1)基于控制台的I/O (2)基于文件的I/O (3)基于字符串的I/O 1、头文件[cpp] view plaincopyprint?#include 2、作用istringstream类用于执行C++风格的字符串流的输入操作。 ostringstream类用_c++ istringstream a >> string
文章浏览阅读2k次,点赞3次,收藏14次。我们在每个修改的地方都记录一条对应的 redo 日志显然是不现实的,因此实现方式是用时间换空间,我们在数据库崩了之后用日志还原数据时,在执行这条日志之前,数据库应该是一个一致性状态,我们用对应的参数,执行固定的步骤,修改对应的数据。1,MySQL 就是通过 undolog 回滚日志来保证事务原子性的,在异常发生时,对已经执行的操作进行回滚,回滚日志会先于数据持久化到磁盘上(因为它记录的数据比较少,所以持久化的速度快),当用户再次启动数据库的时候,数据库能够通过查询回滚日志来回滚将之前未完成的事务。_binglog
文章浏览阅读3k次。概述之前介绍过 移动Web开发基础-flex弹性布局(兼容写法) 里面有提到过想做一个Chrome插件,来生成flexbox布局的css代码直接拷贝出来用。最近把这个想法实现了,给大家分享下。play-flexbox插件介绍play-flexbox一秒搞定flexbox布局,可直接预览效果,拷贝CSS代码快速用于页面重构。 你也可以通过点击以下链接(codepen示例)查_chrome css布局插件
文章浏览阅读308次。我自己的配置是GeForce GTX 1660 +CUDA10.0+CUDNN7.6.0 + TensorFlow-GPU 1.14.0Win10系统安装tensorflow-gpu(按照步骤一次成功)https://blog.csdn.net/zqxdsy/article/details/103152190环境配置——win10下TensorFlow-GPU安装(GTX1660 SUPER+CUDA10+CUDNN7.4)https://blog.csdn.net/jiDxiaohuo/arti