获取片段着色器中的顶点位置

Abs*_*thm 6 opengl opengl-es glsl webgl

由于某些原因,我需要获取在片段着色器中形成图元(三角形)的所有顶点的位置。

我可以通过三种方式做到这一点:附加属性、制服和通过几何着色器。

属性

// vertex shader
in vec3 vPosition;
in vec3 vposA;
in vec3 vposB;
in vec3 vposC;
out vec3 posA;
out vec3 posB;
out vec3 posC;

void main() {
    // ....
    posA = vposA;
    posB = vposB;
    posC = vposC;
}
Run Code Online (Sandbox Code Playgroud)

问题是我需要发送额外的属性,这意味着 VBO 中使用了额外的内存。

制服

// fragment shader
uniform vec3 posA;
uniform vec3 posB;
uniform vec3 posC;

void main() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

主要缺点显然是需要为正在绘制的每个三角形绑定制服,因此每次绘制调用只能绘制一个三角形。

GS :

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

out vec3 posA;
out vec3 posB;
out vec3 posC;

void main()
{
    posA = gl_in[0].gl_Position.xyz;
    posB = gl_in[1].gl_Position.xyz;
    posC = gl_in[2].gl_Position.xyz;

    gl_Position = gl_in[0].gl_Position;
    EmitVertex();
    gl_Position = gl_in[1].gl_Position;
    EmitVertex();
    gl_Position = gl_in[2].gl_Position;
    EmitVertex();
    EndPrimitive();
}
Run Code Online (Sandbox Code Playgroud)

使用 GS,我不需要在内存中存储任何内容,我可以绘制任意数量的三角形,但问题是正在使用整个新的着色器阶段。

我也考虑过使用flat关键字,但在这里不行。

问题是,还有其他选择吗?我可能会错过什么?

谢谢。

And*_*man 3

几何着色器是最实用的方法,但这通常排除了 WebGL。

您可能会考虑从可编程顶点拉取中获取页面,其中实际顶点数据存储在缓冲区纹理中,并使用索引来查找位置值。我无法评论性能,但这样做将需要显着减少每个顶点的存储空间。

这是原始基于属性的尝试的修改版本:

// vertex shader
in int vIdxA; // Index of vtx 0 in current triangle
in int vIdxB; // Index of vtx 1 in current triangle
in int vIdxC; // Index of vtx 2 in current triangle

out vec3 posA;
out vec3 posB;
out vec3 posC;

uniform samplerBuffer vtx_buf; // Actual vertex position array, as a buffer texture

void main() {
    int vtx = gl_VertexID % 3;

    // ....
    posA = texelFetch (vtx_buf, vIdxA);
    posB = texelFetch (vtx_buf, vIdxB);
    posC = texelFetch (vtx_buf, vIdxC);

    if (vtx == 0)
        gl_Position = posA;
    else if (vtx == 1)
        gl_Position = posB;
    else
        gl_Position = posC;
}
Run Code Online (Sandbox Code Playgroud)

在实现时,这也将排除 WebGL,但这种方法应该比基于几何着色器的方法更容易适应 OpenGL ES。

  • 看起来你可以使用属性而不是使用`gl_VertexID`,并且你可以在WebGL中做同样的事情?[这是一个将顶点数据放入纹理的 WebGL 示例](http://jsfiddle.net/greggman/7t2Dj/)。 (3认同)