出于某种原因,我需要在片元着色器中获取形成基本图形(三角形)的所有顶点的位置。
有三种方法可以做到这一点:使用额外属性、uniform变量和几何着色器。
属性:
// 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;
}
问题在于我需要发送额外属性,这意味着需要在VBOs中使用更多的内存。
统一变量:
// fragment shader
uniform vec3 posA;
uniform vec3 posB;
uniform vec3 posC;
void main() {
// ...
}
主要缺点显然是需要为绘制的每个三角形绑定一次uniform,因此我只能在每次绘制调用中绘制一个三角形。
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();
}
使用GS时,我不需要在内存中存储任何东西,可以绘制任意数量的三角形,但问题是整个新的着色器阶段被使用。
我也考虑过使用flat
关键字,但这里行不通。
问题是,是否有其他选项,有什么我可能遗漏的吗?
谢谢。
gl_VertexID
,并且在WebGL中也可以这样做。这里有一个在纹理(texture)中放置顶点数据的WebGL示例。 - gmantexelFetch
和缓冲纹理也需要扩展才能工作。您将不得不归一化纹理坐标并消除整数顶点属性。这基本上是我能想到的最简单的示例,它使用现有的着色器代码作为基础,在每个顶点的基础上执行几何着色器(获取和发出3个顶点)的工作。 我最担心的是让posA
,posB
和posC
对于三角形中的所有顶点保持一致,以便变化的插值不会搞砸事情。 - Andon M. Colemangl_VertexID
的依赖等等,但这将需要更多的代码来解释,并且这样做没有任何好处。 - Andon M. Coleman