我正在研究图形管道,我对曲面细分阶段有一些疑问。我的基本阅读材料是" OpenGL SuperBible第六版:综合教程和参考"。
问题#1: 在SuperBible中,我读到顶点着色器每个贴片顶点(或曲面细分上下文中的控制点)运行一次"进给"曲面细分控制着色器一次一个顶点。反过来,TCS在顶点组上运行。在这个链接虽然
http://web.engr.oregonstate.edu/~mjb/cs519/Handouts/tessellation.1pp.pdf
它说TCS运行一次"输出顶点" (我假设是由VS输出的顶点)。哪两个是真的?我弄错了还是其中一个错了?
问题#2: 这个是关于GLSL的。以下着色器来自SuperBible示例。
顶点着色器
#version 410 core
void main(void)
{
const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID];
}
Tessellation Contron Shader
#version 410 core
layout (vertices = 3) out;
void main(void)
{
if (gl_InvocationID == 0)
{
gl_TessLevelInner[0] = 5.0;
gl_TessLevelOuter[0] = 5.0;
gl_TessLevelOuter[1] = 5.0;
gl_TessLevelOuter[2] = 5.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
a)令牌gl_VertexID(在顶点着色器上)和gl_InvocationID(在TCS上)是什么意思?他们让我感到困惑,因为他们没有在程序中的任何地方明确声明。
b)我知道在TCS中gl_Position变量从顶点着色器获取其数据,但在顶点着色器中没有明确声明gl_Position应该是输出(例如在主程序之前使用out关键字)。我认为要通过各种着色器和管道阶段传递数据,必须明确声明具有相同名称的输入和输出,那么在这种情况下会发生什么?
答案 0 :(得分:1)
以下是我可以回忆并显示一些不太精确的定义,对于详细定义,最好访问opengl.org,检查GLSL规范,最新版本应该是GLSL 4.5。
第一个问题,这两个都是正确的,;)直到几何着色器,每个着色器将为输入顶点运行一次,但混淆的事情是顶点着色器将处理'补丁顶点',TCS也将处理'补丁'顶点',TES将处理由Tessellator生成的真实顶点[这是一个硬件单元,使您的GPU与DX10 / GL3.x cap设备不同]。 VS [顶点着色器,与以下短名称相同]和TCS之间的区别是TCS还将配置Tessellator所需的prope参数。基本上,VS和TCS处理相同的顶点。
第二个问题#a,gl_VertexID表示输入顶点的id,gl_InvocationID表示已在着色器上运行了多少次,您应该检查GS的某些教程或doc,有时使用gl_InvocationID。实际上,gl_InvocationID == 0使得跟随if - { - }的管理就像D3D中的“恒定外壳着色器”
第二个问题#b,gl_Position是顶点位置的内置变量,当然你可以使用'out'关键字来定义你喜欢的东西,但是OGL SB是一本很长的历史书〜
希望这会有所帮助,;)