根据this answer,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(...);
有人可以分享一个如何实现这个的例子吗?我正努力在网上找到相关信息。
答案 0 :(得分:1)
OpenGL允许您在纹理缓冲区中存储任意数据 可以在顶点着色器中访问。
在OpenGL ES 2.0的某些实现中可能,但在规范中不需要它(最大顶点纹理单元允许为0),并且许多OpenGL ES 2.0只有GPU不支持它。
同样,OpenGL ES 2.0不支持浮点纹理(除了作为扩展名),因此无法保证其工作。
最后,即使你可以使它工作,从每个顶点的纹理加载一个16元素FP32矩阵将会非常慢,所以除非这只是桌面GPU的玩具项目,否则不要这样做...(即如果您的目标是使用OpenGL ES 2.x发送商业移动内容,那么这可能不是一个好主意。)