我想用GS绘制多个粉丝。每个风扇应该每次都向摄像机广告,这使得每个顶点必须与MVP矩阵相乘。 由于每个风扇都可由用户移动,我想出了为GS提供位置的想法。
以下几何着色器按预期工作,其中包含输入和输出:
uniform mat4 VP;
uniform mat4 sharedModelMatrix;
const int STATE_VERTEX_NUMBER = 38;
layout (shared) uniform stateShapeData {
vec2 data[STATE_VERTEX_NUMBER];
};
layout (triangles) in;
layout (triangle_strip, max_vertices = 80) out;
void main(void)
{
int i;
mat4 modelMatrix = sharedModelMatrix;
modelMatrix[3] = gl_in[0].gl_Position;
mat4 MVP = VP * modelMatrix;
gl_Position = MVP * vec4( 0, 0 , 0, 1 );
EmitVertex(); // epicenter
for (i = 37; i >= 0; i--) {
gl_Position = MVP * vec4( data[i], 0, 1 );
EmitVertex();
}
gl_Position = MVP * vec4( data[0], 0, 1 );
EmitVertex();
}
我尝试使用glDrawElements
,glDrawArrays
和glMultiDrawArrays
运行此功能。这些命令都没有绘制完整的风扇。每个绘制第一个填充的三角形,剩余的顶点绘制为点。
所以,最底层的问题是:是否可以使用GS创建的顶点绘制扇形?如何?
答案 0 :(得分:2)
如您所发现的那样,在几何着色器中输出粉丝非常不自然。
您当前正在以扇形顺序输出顶点,这是一种在原始程序集之后对GPU 完全陌生的构造。风扇作为汇编器输入非常有用,但就输出而言,光栅化器只能理解条带的概念。
要正确编写此着色器,您需要将此扇形分解为一系列单独的三角形。这意味着您编写的循环实际上将在每次迭代时输出震中。
void main(void)
{
int i;
mat4 modelMatrix = sharedModelMatrix;
modelMatrix[3] = gl_in[0].gl_Position;
mat4 MVP = VP * modelMatrix;
for (i = 37; i >= 0; i--) {
gl_Position = MVP * vec4( 0, 0 , 0, 1 );
EmitVertex(); // epicenter
gl_Position = MVP * vec4( data[i], 0, 1 );
EmitVertex();
gl_Position = MVP * vec4( data[i-1], 0, 1 );
EmitVertex();
// Fan and strip DNA just won't splice
EndPrimitive ();
}
}
以这种方式绘制时,您无法利用条带排序;你不得不多次结束输出原语(strip)。关于绘制扇形顺序的唯一可能的好处是循环内的缓存局部性。如果您了解几何着色器应该输出三角形条带,为什么不以这种方式开始命令您的输入顶点?