使用顶点属性缓冲区或实例数据的统一缓冲区进行实例化渲染

问题描述 投票:0回答:1

我已经看到使用顶点属性缓冲区的实例化渲染。因此,除了“位置”和“正常”等常用数据之外,实例数据还有一个额外的“属性”:

in vec3 position;
in vec3 normal;
in instanceData
{
    mat4 worldMatrix;
};

对于每个顶点,“位置”和“正常”的指针前进一个顶点的步长,但对于每个绘制的实例,“in instanceData”的指针前进一个步长。在 OpenGL 中,这是使用 glVertexAttribDivisor 函数设置的,在 Direct3D 中我认为是使用 IndexCountPerInstance。

但是我想知道是否可以使用从统一缓冲区或常量缓冲区读取的“instanceData”缓冲区来完成实例化渲染。在 OpenGL 中,这会是这样的:

in vec3 position;
in vec3 normal;
uniform instanceData
{
    mat4 worldMatrix[4000]; // Drawing 4000 objects
};

int main()
{
     worldMatrix[glInstanceID]; // If we're drawing for example the 4th instance then the instance data
// is read from the uniform buffer using the instance ID at index 4
}

通过这种方式,您的实例数据可以输入统一的缓冲区,而不是将其作为顶点属性,这需要在您想要实例化渲染时更改顶点输入布局。我知道在 OpenGL 中统一缓冲区的大小是有限的,因此与使用顶点属性方法相比,您将被限制为更少的实例。但如果您需要绘制很多实例,您始终可以使用着色器存储缓冲区对象,它允许更大的缓冲区(可能是无限的),因此 SSBO 无论如何都可以像制服一样工作。

我只是想知道:

  1. 使用统一缓冲方法是否可行/一个好主意,两种方法之间的权衡是什么?例如,统一缓冲方法是否较慢?您将在每个着色器调用时为每个顶点建立索引。

  2. 使用这个方法还是实例化渲染吗?我只见过使用顶点属性方法进行实例化渲染的示例。

opengl graphics rendering
1个回答
0
投票

是的,这可行,我目前正在使用我的引擎进行此操作。

我担心的是你提到的事情......使用顶点数组方法,你可以拥有 GPU 内存允许的尽可能多的实例数据。另一方面,统一缓冲区对象的限制相当低(取决于实现,但标准设置 16kb 作为最低保证)。 SSBO 更好,但该标准并不能保证您可以像使用顶点数组时那样为该数据使用最大内存(我相信)。

我想我会改用顶点数组。编码也比跟踪绑定点等更简单。您在寻找统一缓冲区对象的什么优势?

© www.soinside.com 2019 - 2024. All rights reserved.