0

我正在构建一个着色器程序和 GL 主机环境,它可以完成一项相对简单的任务:

  1. 在多个三角形(补丁)上运行 VS -> TCS -> TES -> GS 着色器阶段集。TES/TCS 确实会产生额外的镶嵌三角形。
  2. 创建一个由足够多的 vec4 元素组成的简单 SSBO。SSBO 将保存镶嵌的结果,即镶嵌顶点的坐标
  3. 在 GS 运行期间,GS 会将三角形顶点写入 SSBO,以使单个三角形的顶点步长为三个,即(triangle1, vert1), (triangle1, vert2), (triangle1, vert3), (triangle2, vert1), (triangle2, vert2),(triangle2, vert3)等。

为了索引我的 SSBO,我需要以某种方式推断“triangleID”。我仔细阅读了 GS/Tess 规格并做了一些实验。似乎 GS 内置输入只是没有它。gl_PrimitiveIDIn 似乎指的是在顶点着色器中看到的三角形的原始索引,并且在细分期间它没有增加。

最后,我想到了拥有另一个 SSBO 的想法/解决方法,该 SSBO 将具有一个“原始计数器”,atomicAdd(primCount, 1)每次执行 GS 时都会递增:

layout ( triangles ) in;
layout ( triangle_strip, max_vertices = 3 ) out;

layout(std140, binding = 1) buffer AuxSSBO {
    int primCount;
    int lock;
    int pad2;
    int pad3;
};

layout(std140, binding = 2) writeonly buffer TrianglesSSBO {
    writeonly vec4 pos[];
};


void main() {

    int idx = atomicAdd(primCount, 1);

    for (int i = 0; i < 3; ++i) {

        gl_Position = gl_in[i].gl_Position;
        gl_PrimitiveID = gl_PrimitiveIDIn;

        pos[3 * idx + i] = vec4(gl_Position.xyz, 1.0);

        EmitVertex();
    }

    EndPrimitive();

}

昨天我花了很多时间来完善上面的代码,因为我在路上遇到了各种各样的赛车条件。现在看来,它在我的 GPU/驱动程序上起到了作用,但我不完全确定它是 100% 正确的。

所以我的第一个问题是:

  • 在我的情况下推断三角形索引的最佳方法是什么?上面的代码是免费的?

我的第二个问题是关于性能:

  • 我有另一个基于变换反馈对象和缓冲区的任务实现,我必须说它的工作速度快 4 倍(每帧 2.0 毫秒对 0.5 毫秒)。我想知道为什么 SSBO 后端比 TF 后端慢得多,我能做些什么来让它运行得更快吗?

PS 完整代码在这里:https ://pastebin.com/SagKZEyi

PSS 使用 DrawArraysIndirect() 更新的代码在这里:https ://gist.github.com/lhog/432af74ba41259e062f18910b5904684

谢谢!

4

0 回答 0