我如何缓冲模型矩阵数据到纹理使用OpenGL ES2, GLSL, c++

How can I buffer model matrix data into texture using OpenGL ES2, GLSL, C++?

本文关键字:纹理 ES2 c++ GLSL 数据 OpenGL 何缓冲 缓冲 模型      更新时间:2023-10-16

根据这个答案,OpenGL允许你在纹理缓冲中存储任意数据,可以在顶点着色器中访问。

我创建了一个大小为4096 * 256 * 4的Float32Array,其中包含每个模型的世界矩阵(足以用于~256k模型)。每个模型都有一个modelIndex属性,用于从纹理中读取其矩阵。然后在每一帧,gl.texSubImage2D绘制整个纹理,并在每次绘制调用中绘制尽可能多的纹理。

示例场景:
我有一堆独特的模型,他们共享一个共同的着色器,他们的顶点位置打包到一个单独的VBO。我想用从纹理缓冲区中获取的唯一模型矩阵来更新每个模型,然后在单个glDrawElements()调用中绘制这些模型。

一些非常粗糙的伪代码:

// In C++
struct Vertex {
    GLFloat x, y;
    GLuint matrixID;
}
// Create an array of floats that represent a unique model matrix
// Assume pre-calculation of values
GLfloat data[32] { /* 32 floats, two 4x4 matrices */ }
glTexImage2D(..., data);
// Then in the vertex shader
attribute vec4 in_Position; // x, y, 1.0, matrixID;
uniform mat4 uf_Projection;
void main() {
    // I need help implementing this magical function...
    mat4 model = getMatrixFromTextureBuffer(in_Position.w);
    // Apply unique model matrix
    gl_Position = uf_Projection * model * vec4(in_Position.xy, 1.0, 1.0);
}
// Draw everything!
glDrawElements(...);

有人可以分享一个如何实现这一点的例子吗?我在网上找不到相关信息。

OpenGL允许你在纹理缓冲区中存储任意数据可以在顶点着色器中访问。

在OpenGL ES 2.0的一些实现中是可能的,但在规范中没有要求(最大顶点纹理单位允许为0),因此许多OpenGL ES 2.0的gpu不支持它。

同样,OpenGL ES 2.0不支持浮点纹理(除非作为扩展),所以也不能保证工作。

最后,即使你可以让它工作,从每个顶点的纹理加载16元素的FP32矩阵将是非常慢的,所以只是不要这样做,除非这只是一个桌面GPU的玩具项目…(例如,如果你的目标是使用OpenGL ES 2发布商业移动内容。