【问题标题】:OpenGl es 2.0 Geometry instancingOpenGL es 2.0 几何实例化
【发布时间】:2018-07-17 16:49:30
【问题描述】:

我有 170 个对象要绘制,每个对象都是由 312 个顶点构建的。 我有一个对象,我用不同的矩阵绘制了 170 次,我发现如果我一个一个地绘制它们,我不需要调用一些函数,所以我只在开始时调用它们,这给了我大约 5fps,我我正在使用带有 drawArrays 的非索引三角形。

if(!started)
{
    glUseProgram( __programObject );
    glEnableVertexAttribArray(attPosition);
    glVertexAttribPointer(attPosition, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), vVertices);//3*sizeof(float)
    glEnableVertexAttribArray(attNormals);
    glVertexAttribPointer(attNormals, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), vNormals);//3*sizeof(float)
}

在 es 2.0 下有什么方法可以让它更快吗?我在 sgx 540 上得到大约 23fps, 将每个对象的顶点细节降低到 36 个不会增加帧速率,矩阵计算(缩放、乘法、平移、转置、反转)大约有 10fps,但它们是在 cpu 上制作的,我认为将它们移动到着色器中并不是一个好主意。我知道大部分时间都花在每次传递制服上。我知道有一种方法可以实例化对象并传递制服并在一次调用中绘制它,但我找不到任何描述它的教程,你知道我在哪里可以找到它吗?

【问题讨论】:

  • 使用带有交错数据的单个 VBO 应该会有很大帮助。一些 GPU 也更喜欢 16 的步幅。
  • 遗憾的是,gl_ext_draw_instancedgl_ext_instanced_arrays 在 SGX540 上不可用,仅在 SGX543、544、554(所谓的 5XT 系列 as distinct from 5 系列)上可用。

标签: opengl-es opengl-es-2.0


【解决方案1】:

尝试像这样在一个数组中包含法线和顶点:

sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
GLES20.glVertexAttribPointer(
                                GLES20.glGetAttribLocation(programTextured, "aPosition"), 3,
                                GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));

sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
GLES20.glVertexAttribPointer(
                                GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
                                GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));

在这个例子中,我有一个顶点和 tex 坐标数组

引用自 OpenGL ES 2.0 编程指南:

 How to store different attributes of a vertex
We described the two most common ways of storing vertex attributes—
array of structures and structure of arrays. The question to ask is which allocation
method would be the most efficient for OpenGL ES 2.0 hardware
implementations. The answer is array of structures. The reason is that the
attribute data for each vertex can be read in sequential fashion and so will
most likely result in an efficient memory access pattern. A disadvantage of
using array of structures is when an application wants to modify specific
attributes. If a subset of vertex attribute data needs to be modified (e.g., texture
coordinates), this will result in strided updates to the vertex buffer.
When vertex buffer is supplied as a buffer object, the entire vertex attribute
buffer will need to be reloaded. One can avoid this inefficiency by storing
vertex attributes that are dynamic in nature in a separate buffer.

那本书也有以这种方式使用的例子

【讨论】:

  • 一开始我只通过一次法线和顶点,我认为我可以一次通过法线和位置矩阵,它应该更快一点->完成,将 gluniformmatrix3fv 和 4fv 更改为浮点数组的位置和法线矩阵作为 7 vec4 传递,现在得到 28-29 fps。我一直在考虑为所有具有预先计算的位置和法线的对象制作一个大顶点数组。我想我会尝试一下。
  • 向量不同数组的问题是GPU需要为每个顶点从一个内存源跳到另一个内存源。这是额外的操作。恕我直言
  • 我读过一篇来自 Nvidia 的文章,他说 总是 使用 interleaved verticestriangle-strip。因为缓存命中。他们列出了其他一些原因,但主要关注的是缓存命中。无论如何,我不记得我在哪里看到的:(
  • 可能这是依赖于硬件的建议,不是吗?但是nvidia是主流
  • 线性化数据不依赖于硬件以获得最佳缓存性能。每当一组指令在多个数据源上运行时,为了缓存局部性,建议交错该数据。即使在 CPU 上,这也是一个很好的建议。
【解决方案2】:

您可以尝试通过属性而不是制服传递每个实例的数据。它有时对桌面 OpenGL 有帮助。

因此,顶点着色器将如下所示:

attribute vec3 position;
attribute mat4 proj_view_matrix;
void main()
{
    gl_Position = proj_view_matrix * position;
}

渲染代码将如下所示:

glUseProgram( programObject );
glEnableVertexAttribArray(attPosition);
glVertexAttribPointer(attPosition, ..., pPositions);
glDisableVertexAttribArray(attProjViewMatrix+0);
glDisableVertexAttribArray(attProjViewMatrix+1);
glDisableVertexAttribArray(attProjViewMatrix+2);
glDisableVertexAttribArray(attProjViewMatrix+3);

foreach( instance )
{
    glVertexAttrib4fv(attProjViewMatrix+0, instance.proj_view_matrix.column0);
    glVertexAttrib4fv(attProjViewMatrix+1, instance.proj_view_matrix.column1);
    glVertexAttrib4fv(attProjViewMatrix+2, instance.proj_view_matrix.column2);
    glVertexAttrib4fv(attProjViewMatrix+3, instance.proj_view_matrix.column3);
    glDrawArrays( ... );
}

【讨论】:

    猜你喜欢
    • 2013-08-13
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多