我阅读了许多文章和帖子,内容涉及从顶点着色器阶段向片段着色器传递矢量和矩阵等值。但我还是不确定这个: 如果你在顶点着色器中有一些out vars(我称之为vtxs),而片段着色器(frgs)中有一些vars,那么OpenGl如何关联它们以便它们引用相同的值(我忽略了这一事实:传递给frgs的值是插值的)?我必须按照某种顺序写下来吗?如果我写的话,OpenGl如何解释这些变量:
vtxs:
out float x;
out vec4 mvp;
frgs:
in vec4 mvp;
in float x;
in double newvar;
注意:我改变了var类型,并且在frgs中有1个以上的var,然后在vtxs中有vars。
我看到布局列表中的位置规范是一种分配...地址的方法吗? ...到一个变量,但我有一个古老的上网本不支持这样一个变量装饰。
并作为提示:你知道某种调试着色器吗?我的意思是,在cpu程序中你可以添加一些printfs,但我没有在glsl中看到这样的函数...
总而言之,这是我的问题:
你用布局指定了什么(location = ...)有关着色器的后果是什么?
各种着色器阶段之间的值匹配/关联如何工作?有没有" location ="?
调试glsl着色器
答案 0 :(得分:3)
默认情况下,输入和输出在接口之间按名称匹配。对于顶点着色器输入,默认的“自动”索引分配是arbitrary,因为它可能在实现之间有所不同。
layout
限定符允许显式指定输入\输出的存储类型和位置。由于顶点输入的自动分配是任意的,您应该使用GLSL中的layout
位置或函数glBindAttribLocation
来保证苹果是苹果和橘子橙。
因此layout
规范在顶点着色器中非常常见。但它可以在任何界面之间使用。例如,如果您没有为vec4
和float
使用相同的名称,那么您就完成了
<强> vtxs:强>
layout(location = 0) out float x;
layout(location = 1) out vec4 mvp;
<强> frgs:强>
layout(location = 0) in float y;
layout(location = 1) in vec4 pvm;
现在,界面中没有的任何输入都会破坏管道。如果您使用新变量
in double newvar;
然后glLinkProgram
将失败。
<强>调试:强>
第一个调试步骤是检查状态着色器编译和链接。失败时,您可以使用glGetShaderInfoLog
检索错误。
//compilation
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success)
{
GLchar infoLog[512];
glGetShaderInfoLog(shader, 512, NULL, infoLog);
}
//program
glLinkProgram(shaderProgram);
GLint success;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success)
{
GLchar infoLog[512];
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
}
你也可以
答案 1 :(得分:1)
默认情况下,阶段之间的变量按名称匹配。
对于位置,您可以在概念上将阶段之间传递的数据视为vec4的数组。然后location是我们用来传递该变量的数组的索引。
大于vec4的类型会获得多个连续位置。对于较新的opengl版本(或ARB_enhanced_layouts),这些也是一个组件布局限定符,用于在该vec4数组中更紧密地打包值。
我不确定在按名称和位置进行匹配时如何分配位置。