pan*_*234 0 opengl shader glsl matrix
作为参考,我正在遵循本教程。现在假设我有一个具有多种类型模型的小应用程序,如果我理解正确的话,我必须将每个模型的 MPV 矩阵从 CPU 发送到 GPU(换句话说,发送到我的顶点着色器),因为每个模型可能有不同的模型矩阵从一个到另一个。
现在看看教程和这篇文章,我明白应该为每个帧和每个模型调用将矩阵发送到我的着色器 ( glUniformMatrix4fv(myMatrixID, 1, GL_FALSE, &myModelMVP[0][0])) ,因为每次它都会覆盖我的 MVP 的先前值(我的最后一个值)模型)。但是,考虑到我的应用程序的性能,我不想通过总线发送无用的数据,如果我理解正确的话,我的模型矩阵对于每个模型都是恒定的。
我正在考虑为每个模型的 MVP 矩阵制定一个制服,但我认为它不可扩展,如果我的视图或投影矩阵发生变化,我还必须更新所有这些......有没有办法避免多次发送我的模型矩阵并且仅在更改时发送我的视图和投影矩阵?
这本质上是两个问题:如何避免在仅部分转换序列发生变化时发送数据,以及如何有效地提供自上一帧以来可能发生或未发生变化的每个模型数据。
首先,您有一个转换序列。您的位置位于模型空间中。然后,您从概念上将它们转换为世界空间,然后转换为相机/视图空间,最后转换为剪辑空间,您可以在其中将位置写入gl_Position.
大多数这些变换在整个帧中是恒定的,但可能会在帧与帧之间发生变化。因此,您希望避免更改并非严格需要更改的数据。
如果你想这样做,那么显然你不能提供“MVP”矩阵。也就是说,您不应该拥有包含整个转换的单个矩阵。相反,您应该有一个表示转换的特定部分的矩阵。
但是,您需要出于性能以外的原因进行此分解。您无法在剪辑空间中进行许多照明操作;作为一个非线性空间,它会扰乱许多照明操作。因此,如果您要进行照明,则需要在剪辑空间之前停止转换。
现在,如果您使用模型到相机和相机到剪辑,那么当相机改变时,每个模型的模型到相机矩阵都会改变,即使模型本身没有移动。因此,您可能需要上传一堆并不严格需要更改的矩阵。
为了避免这种情况,您需要使用模型到世界和世界到剪辑(在这种情况下,您在世界空间中进行照明)。这里的问题是,你面临着世界空间的危险,数字精度可能会出现问题。
但这里真的存在性能问题吗?显然,这在某种程度上取决于硬件。然而,考虑到许多应用程序有数百个甚至数千个对象,每个对象都有每帧都会改变的矩阵。动画角色通常有一百多个专门为自己设计的矩阵,每一帧都会发生变化。
因此,上传一些可能恒定的矩阵的性能成本似乎不太可能是一个现实问题。
您真正想要的是将每个对象数据的存储与程序对象本身分开。这可以通过 UBO 或 SSBO 来完成;在这两种情况下,您都将统一的数据存储在缓冲区对象中。
前者的大小通常较小(64KB 左右),而后者的存储空间基本上是无限的(最小 16MB)。显然,前者的访问速度通常更快,但 SSBO 不应被认为是慢的。
每个对象都有一部分缓冲区用于存储每个对象的数据。因此,您可以根据自己的需要选择更改或不更改。
即便如此,这样的系统并不能保证更快的性能。例如,如果当您尝试在本帧中更改缓冲区时,实现仍在从上一帧的缓冲区中读取数据,则实现将必须分配新内存,或者只是等待 GPU 完成。这不是一种假设的可能性;而是一种可能性。复杂场景的 GPU 渲染经常落后于 CPU 一帧。
因此,为了避免这种情况,您需要对每个对象的数据进行双缓冲。但当你这样做时,你将必须始终上传他们的数据,即使它没有改变。为什么?因为它可能在两帧前发生了变化,并且您的双缓冲区中有旧数据。
基本上,尝试避免上传有时是静态的每个模型数据的目标既可能损害性能,也可能有助于提高性能。