为什么这个OpenGL 3顶点着色器非常慢?

3

我有以下顶点着色器:

#version 150

in vec4 position;
in vec2 texture;
in int layer;

out vec2 pass_texture;
out float pass_layer;

uniform mat4 _modelToClipMatrix;
uniform float layerDepth[255];

void main (void)
{
    gl_Position = _modelToClipMatrix*vec4(position.xy,layerDepth[layer]/255,position.w);
    // gl_Position = _modelToClipMatrix*position;
    pass_layer = float(layer);
    pass_texture = texture;
}

当我按照这里的方法使用它时,我的帧速率大约为7 FPS。如果我使用第二行(注释掉的那一行)而不是第一行,我的帧速率跳到大约50 FPS。似乎数组查找是这里的主要问题。为什么它如此缓慢?如何在保持功能的同时提高性能?
我的硬件是ATI Radeon HD 4670 256 MB(iMac 2010型号)。
我的顶点结构看起来像:
typedef struct
{
    floatVector2 position; //2*4=8
    uByteVector2 textureCoordinate; //2*1=2
    GLubyte layer; //1
} PCBVertex;

我按照以下方式设置缓冲区:

glVertexAttribPointer((GLuint)positionAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(PCBVertex), (const GLvoid *)offsetof(PCBVertex, position));
glVertexAttribPointer((GLuint)textureAttribute, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(PCBVertex), (const GLvoid *)offsetof(PCBVertex, textureCoordinate));
glVertexAttribIPointer(layerAttribute, 1, GL_UNSIGNED_BYTE, sizeof(PCBVertex), (const GLvoid *)offsetof(PCBVertex, layer));

一些背景信息: 我正在开发一个绘图软件包。用户可以在多个图层上进行绘制,其中一个图层处于活动状态,并且被绘制在最前面。他还可以“翻转”图层,就像从另一侧看一样。我认为在图层顺序更改时更新所有顶点会效率低下,因此我给每个顶点分配一个图层号码,并在统一变量中查找其当前位置(我只发送x和y作为位置数据)。此外,值得一提的是:片段着色器也使用相同的图层号码来确定颜色,同样使用统一数组。


一维纹理查找可能比数组统一更快。 - Ben Voigt
它是否降回软件模式?此外,GL_MAX_VERTEX_UNIFORM_COMPONENTS是什么? - harold
如果您明确计算并加载 uniform float layerz[255] 以获取 layerDepth[layer]/255.0f 并在矩阵乘法之前设置 position.z = layerz[layer],那么它在语义上是等效的,但着色器编译器可能会生成更有效的代码。 - Brett Hale
谢谢你到目前为止的回复。我已经尝试了一下,似乎与统一量大小有关。当我将大小减小到100时,一切都运行得非常流畅。我还注意到,在255大小的情况下,CPU使用率为100%,因此可能是顶点着色器在CPU上运行。在大小为100的情况下,所有颜色都丢失了,因此传递到片段着色器的pass_layer出现问题。 - Remco Poelstra
是的,我打算尝试一下,但我从未使用过纹理,所以在弄清如何使用它们之前需要一段时间。 - Remco Poelstra
显示剩余9条评论
1个回答

0

如果你移除这行代码

gl_Position = _modelToClipMatrix*vec4(position.xy,layerDepth[layer]/255,position.w);

从您的着色器中,uniform float layerDepth[255]; 将变得未使用。这意味着编译器会将其优化掉。

此外,layerAttribute 位置将变为 -1,防止任何数据传输到该属性指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接