Opengl 是否可以使用唯一的几何体着色器绘制带有线的球体?
我想显示一个简单的UV球体(从Blender导出),并使用唯一的几何体着色器生成具有法线坐标的线 第一次,我编写了一个简单的几何体着色器,它只将输入顶点信息返回到片段着色器。为了简单起见(对于示例),我删除了片段着色器中的亮度计算 顶点着色器:Opengl 是否可以使用唯一的几何体着色器绘制带有线的球体?,opengl,glsl,shader,geometry-shader,Opengl,Glsl,Shader,Geometry Shader,我想显示一个简单的UV球体(从Blender导出),并使用唯一的几何体着色器生成具有法线坐标的线 第一次,我编写了一个简单的几何体着色器,它只将输入顶点信息返回到片段着色器。为了简单起见(对于示例),我删除了片段着色器中的亮度计算 顶点着色器: #version 400 layout (location = 0) in vec3 VertexPosition; layout (location = 1) in vec3 VertexNormal; uniform mat4 MVP; out
#version 400
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
uniform mat4 MVP;
out vec3 VPosition;
out vec3 VNormal;
void main(void)
{
VNormal = VertexNormal;
gl_Position = vec4(VertexPosition, 1.0f);
}
几何体着色器:
#version 400
layout(points) in;
layout(line_strip, max_vertices = 2) out;
uniform mat4 MVP;
in vec3 VNormal[];
out vec3 fcolor;
void main(void)
{
float size = 2.5f;
fcolor = vec3(0.0f, 0.0f, 1.0f);
gl_Position = MVP * gl_in[0].gl_Position;
EmitVertex();
fcolor = vec3(1.0f, 1.0f, 0.0f);
gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
EmitVertex();
EndPrimitive();
}
和片段着色器:
#version 400
in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
out vec4 FragColor;
in vec3 fcolor;
void main(void)
{
FragColor = vec4(fcolor, 1.0f);
}
现在在C++代码中绘制的原始类型(这里是三角形):
最后是输出: 直到这里一切都好。 现在我想在球体上生成线作为法线。为了完成这项工作,我编写了以下几何体着色器(顶点着色器和片段着色器是相同的)输入原语类型为点i,修改C++代码绘制场景:
glDrawArrays(GL_POINTS, 0, meshList[idx]->getVertexBuffer()->getBufferSize());
以及输出:
最后,如果我想在几何体着色器中获得三角形输入作为输入基本体和线条条作为输出基本体,我有以下着色器:
#version 400
layout(triangles, invocations = 3) in;
layout(line_strip, max_vertices = 6) out;
uniform mat4 MVP;
in vec3 VNormal[];
out vec3 fcolor;
void main(void)
{
float size = 1.0f;
for (int i = 0; i < 3; i++)
{
fcolor = vec3(0.0f, 0.0f, 1.0f);
gl_Position = MVP * gl_in[i].gl_Position;
EmitVertex();
fcolor = vec3(1.0f, 1.0f, 0.0f);
gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
EmitVertex();
EndPrimitive();
}
}
#版本400
中的布局(三角形,调用=3);
布局(线带,最大顶点=6)输出;
均匀mat4-MVP;
在vec3 VNormal[];
输出vec3颜色;
真空总管(真空)
{
浮子尺寸=1.0f;
对于(int i=0;i<3;i++)
{
fcolor=vec3(0.0f,0.0f,1.0f);
总账位置=MVP*总账在[i]中的位置。总账位置;
发射顶点();
fcolor=vec3(1.0f,1.0f,0.0f);
gl_Position=MVP*vec4(gl_在[0]中)。gl_Position.xyz+vec3(
VNormal[0].x*大小,VNormal[0].y*大小,VNormal[0].z*大小),1.0f);
发射顶点();
EndPrimitive();
}
}
输出如下:
但我的目标是使用相同的几何体着色器在一个输出中显示场景(球体+股线)。我想知道是否有可能做到这一点。我不这么认为,因为几何体着色器必须只有一种类型的输入基元,另一种类型的输出基元,而不是几种类型。我想确定这是否可行。谁知道呢,也许有一天会有一个从几何体着色器发射多个基本体类型的扩展,但正如您所说,它目前无法完成 另一种方法是用三角形绘制法线 另一种方法是使用“变换反馈”扩展保存顶点着色器结果,并使用两个单独的几何体着色器重用该数据,但在本例中完全没有用处。我之所以提到这一点,是因为这是我能想到的在顶点阶段之后发射多个基本体类型的最接近的方法 编辑
用于绘制法线的两个几何体着色器使我感到困惑。在第二个循环中,
max_texts=3
,对于3个单独的行,它应该是6
,并且EndPrimitive
也应该在for循环中,这样3行就不会连接。但是您已经通过在上一个中绘制GL_点
来解决这个问题。如果支持多原语输出,是否打算将其结构化?(固定)
考虑到几何体重用了许多顶点,使用
gldrawerelements
的索引将更有效。尽管您仍然希望使用glDrawArrays
绘制法线,以避免绘制索引数组引用的重复顶点。第一个几何体着色器似乎未粘贴-第二个几何体着色器的副本。谢谢您的回答。我怀疑这个想法是不可能的,但我想确定这一点。关于最后一个几何体着色器,您是对的。我更新了源代码和图片。关于glDrawArray,我将通过glDrawElement对其进行更改,这肯定更有效。再次感谢。@user1364743噢,还需要将[0]/VNormal[0]
中的gl\u更改为[i]
/VNormal[i]
中的gl\u。第一个几何体着色器仍然使用点入/线出,而不是实心三角形。
glDrawArrays(GL_POINTS, 0, meshList[idx]->getVertexBuffer()->getBufferSize());
#version 400
layout(triangles, invocations = 3) in;
layout(line_strip, max_vertices = 6) out;
uniform mat4 MVP;
in vec3 VNormal[];
out vec3 fcolor;
void main(void)
{
float size = 1.0f;
for (int i = 0; i < 3; i++)
{
fcolor = vec3(0.0f, 0.0f, 1.0f);
gl_Position = MVP * gl_in[i].gl_Position;
EmitVertex();
fcolor = vec3(1.0f, 1.0f, 0.0f);
gl_Position = MVP * vec4(gl_in[0].gl_Position.xyz + vec3(
VNormal[0].x * size, VNormal[0].y * size, VNormal[0].z * size), 1.0f);
EmitVertex();
EndPrimitive();
}
}