OpenGL 或 DirectX 中 3d 几何存储和使用的一般方案
general scheme of 3d geometry storage and usage in OpenGL or DirectX
我对 OpenGL 知之甚少,而且所有这些文档和教程都非常难读,所以我没有帮助。我对它的工作原理有了一些了解,只希望对我的愿景进行一些澄清或验证
我假设 3D 世界是从 3d 网格构建的,每个网格可能保存在某个数组或几个数组中(存储该网格的几何形状)。我还假设某些网格可能有点像克隆并使用更多在现场不止一次..所以在我看来我有 50 个网格,但其中一些被使用了不止一次......可以说那些克隆我将命名为网格的实例(每个网格可能有 0 个实例,1实例或更多实例)
这个视力可以吗?可以再添加一些吗?
我知道每个实例都应该有自己的位置和方向,那么我们是否有一些实例数组,每个元素都包含一个位置方向矩阵?或者只存在于代码分支中的硫糖矩阵(你知道我的意思,我设置这样的矩阵然后发送一个网格然后修改这个位置矩阵然后再次发送网格直到所有实例都发送完)?
这会耗尽几何(非着色器)部分吗?
(然后着色器部分来了,我也不太明白,着色器上有大量的骗局,其中这个几何部分对我来说似乎更重要,无论如何)
有人可以验证我在这里传播的愿景吗?
所以您有一个包含一个或多个网格的模型,一个包含一个或多个组的网格,以及一个包含顶点数据的组。
模型和网格之间只有很小的区别,例如模型将包含其他数据,例如将由一个或多个网格使用的纹理。
网格还将包含有关如何绘制矩阵等组的数据。
组是网格的一部分,通常用于使用子矩阵移动模型的一部分。看看"skeletal animation".
因此,正如传统的固定管道所建议的那样,您通常会有一堆矩阵,这些矩阵可以被推入和弹出以定义某种程度 "sub-positions"。想象有一个代表龙的模型。该模型很可能由单个网格、纹理和绘图上的一些其他数据组成。在运行时,这个模型会有一些矩阵定义模型的基本位置和旋转,甚至比例。然后当龙需要飞翔时,你会移动它的翅膀。由于机翼可能相同,因此可能只有一组,但网格将包含数据以使用不同的矩阵绘制两次。所以模型有一个矩阵,然后乘以机翼组矩阵来绘制机翼本身:
- 推送模型矩阵
- 乘以龙阵
- 推送模型矩阵
- 与机翼矩阵相乘
- 画翅膀
- 弹出矩阵
- 推送矩阵
- 与第二个翼矩阵相乘
- 绘制第二翼
- 弹出矩阵
- ...画龙的其他部位
- 弹出矩阵
你大概可以想象机翼被分成多个部分,每个部分又包含一个内部相关矩阵,实现更深层次的矩阵使用和绘制。
然后将在 model/mesh 的其他部分使用相同的程序。
所以我们的想法是将尽可能少的数据放在 GPU 上并重复使用它们。因此,当加载模型时,所有纹理和顶点数据都应发送到 GPU 并准备好使用。 CPU 必须知道这些缓冲区及其使用方式。整个模型可能只有一个顶点缓冲区,其中每个绘制调用将重用缓冲区的不同部分,而是想象模式的每个主要部分都有一个缓冲区,例如机翼、头部、body, 腿...
最后我们通常会想出类似于共享 object 的东西,其中包含绘制龙所需的所有数据,即纹理和顶点缓冲区。然后我们有另一条龙 object,它将指向该模型并包含在场景中绘制特定龙的所有必要数据。这将包括场景中位置的矩阵数据,用于为翅膀和其他部分制作动画的组的矩阵,可能是一些尺寸甚至一些基本颜色以与原始模型结合......通常还有一些状态存储在这里比如速度,一些AI参数,甚至生命值。
所以最后我们想要做的是像 foreach(dragon in dragons) dragon.draw()
这样的事情,它将使用其内部数据来设置基本模型矩阵并使用所需的任何其他数据。然后draw
方法会调出模型中所有的组,meshs也要绘制,直到"recursion"完成,整个模型绘制完成。
所以是的,数据的结构最终非常复杂,但如果您从较小的部分开始并继续向外延伸,那么所有这些都非常适合。
为了顺利加载,还需要处理其他运行时系统。例如,如果您在游戏中并且附近有龙,您将不会加载龙的模型。当龙进入附近时,模型应尽可能在后台加载,但仅在需要时(在可视范围内)绘制。然后当龙消失时你可能不会简单地卸载模型,你必须确保所有的龙都消失了,如果有人可能 return,甚至可以稍等片刻。然后这会导致类似于垃圾收集器的东西。
希望这能帮助您更好地理解。
我对 OpenGL 知之甚少,而且所有这些文档和教程都非常难读,所以我没有帮助。我对它的工作原理有了一些了解,只希望对我的愿景进行一些澄清或验证
我假设 3D 世界是从 3d 网格构建的,每个网格可能保存在某个数组或几个数组中(存储该网格的几何形状)。我还假设某些网格可能有点像克隆并使用更多在现场不止一次..所以在我看来我有 50 个网格,但其中一些被使用了不止一次......可以说那些克隆我将命名为网格的实例(每个网格可能有 0 个实例,1实例或更多实例)
这个视力可以吗?可以再添加一些吗?
我知道每个实例都应该有自己的位置和方向,那么我们是否有一些实例数组,每个元素都包含一个位置方向矩阵?或者只存在于代码分支中的硫糖矩阵(你知道我的意思,我设置这样的矩阵然后发送一个网格然后修改这个位置矩阵然后再次发送网格直到所有实例都发送完)?
这会耗尽几何(非着色器)部分吗? (然后着色器部分来了,我也不太明白,着色器上有大量的骗局,其中这个几何部分对我来说似乎更重要,无论如何)
有人可以验证我在这里传播的愿景吗?
所以您有一个包含一个或多个网格的模型,一个包含一个或多个组的网格,以及一个包含顶点数据的组。
模型和网格之间只有很小的区别,例如模型将包含其他数据,例如将由一个或多个网格使用的纹理。
网格还将包含有关如何绘制矩阵等组的数据。
组是网格的一部分,通常用于使用子矩阵移动模型的一部分。看看"skeletal animation".
因此,正如传统的固定管道所建议的那样,您通常会有一堆矩阵,这些矩阵可以被推入和弹出以定义某种程度 "sub-positions"。想象有一个代表龙的模型。该模型很可能由单个网格、纹理和绘图上的一些其他数据组成。在运行时,这个模型会有一些矩阵定义模型的基本位置和旋转,甚至比例。然后当龙需要飞翔时,你会移动它的翅膀。由于机翼可能相同,因此可能只有一组,但网格将包含数据以使用不同的矩阵绘制两次。所以模型有一个矩阵,然后乘以机翼组矩阵来绘制机翼本身:
- 推送模型矩阵
- 乘以龙阵
- 推送模型矩阵
- 与机翼矩阵相乘
- 画翅膀
- 弹出矩阵
- 推送矩阵
- 与第二个翼矩阵相乘
- 绘制第二翼
- 弹出矩阵
- ...画龙的其他部位
- 弹出矩阵
你大概可以想象机翼被分成多个部分,每个部分又包含一个内部相关矩阵,实现更深层次的矩阵使用和绘制。
然后将在 model/mesh 的其他部分使用相同的程序。
所以我们的想法是将尽可能少的数据放在 GPU 上并重复使用它们。因此,当加载模型时,所有纹理和顶点数据都应发送到 GPU 并准备好使用。 CPU 必须知道这些缓冲区及其使用方式。整个模型可能只有一个顶点缓冲区,其中每个绘制调用将重用缓冲区的不同部分,而是想象模式的每个主要部分都有一个缓冲区,例如机翼、头部、body, 腿...
最后我们通常会想出类似于共享 object 的东西,其中包含绘制龙所需的所有数据,即纹理和顶点缓冲区。然后我们有另一条龙 object,它将指向该模型并包含在场景中绘制特定龙的所有必要数据。这将包括场景中位置的矩阵数据,用于为翅膀和其他部分制作动画的组的矩阵,可能是一些尺寸甚至一些基本颜色以与原始模型结合......通常还有一些状态存储在这里比如速度,一些AI参数,甚至生命值。
所以最后我们想要做的是像 foreach(dragon in dragons) dragon.draw()
这样的事情,它将使用其内部数据来设置基本模型矩阵并使用所需的任何其他数据。然后draw
方法会调出模型中所有的组,meshs也要绘制,直到"recursion"完成,整个模型绘制完成。
所以是的,数据的结构最终非常复杂,但如果您从较小的部分开始并继续向外延伸,那么所有这些都非常适合。
为了顺利加载,还需要处理其他运行时系统。例如,如果您在游戏中并且附近有龙,您将不会加载龙的模型。当龙进入附近时,模型应尽可能在后台加载,但仅在需要时(在可视范围内)绘制。然后当龙消失时你可能不会简单地卸载模型,你必须确保所有的龙都消失了,如果有人可能 return,甚至可以稍等片刻。然后这会导致类似于垃圾收集器的东西。
希望这能帮助您更好地理解。