OpenGL 着色器变量传递
OpenGL Shader variable passing
我阅读了很多关于将向量和矩阵等值从顶点着色器阶段传递到片段着色器的文章和帖子。但我仍然不确定这一点:
如果您在顶点着色器中有一些输出变量(我称他为 vtxs),在片段着色器(frgs)中有一些变量,OpenGl 如何关联它们以便它们引用相同的值(我忽略了值传递的事实到 frgs 被插值)?我必须按某种顺序写下来吗?如果我这样写,OpenGl 如何解释这些变量:
vtxs:
out float x;
out vec4 mvp;
frgs:
in vec4 mvp;
in float x;
in double newvar;
注意:我打乱了 var 类型,frgs 中的 var 中还有 1 个,然后 vtxs 中的 out vars。
我看到布局列表中的位置规范是分配...地址的一种方式? ...到一个变量,但我有一个古老的上网本不支持这样的变量装饰器。
提示:您知道某种调试着色器吗?我的意思是,在 cpu 程序中你可以添加一些 printfs 但我没有在 glsl 中看到这样的函数...
所以,总结一下,这是我的问题:
你到底用layout(location=...)指定了什么关于着色器的结果?
不同着色器阶段之间的值matching/association是如何工作的?有无 "location="?
调试 glsl 着色器
默认情况下,阶段之间的变量按名称匹配。
对于位置,您可以从概念上将阶段之间传递的数据视为 vec4 数组。然后 location 是我们用来传递该变量的数组的索引。
大于 vec4 的类型获得多个连续位置。对于较新的 opengl 版本(或 ARB_enhanced_layouts),这些也是一个组件布局限定符,用于在该 vec4 数组中更紧密地打包值。
我不确定按名称和位置进行混合匹配时如何分配位置。
默认情况下,输入和输出在接口之间按名称匹配。对于顶点着色器输入,索引的默认 'automatic' 分配是 arbitrary,因为它可能因实现而异。
layout
限定符允许明确指定 input\output 的存储类型和位置。由于顶点输入的自动分配是任意的,你应该使用 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);
}
你也可以
我阅读了很多关于将向量和矩阵等值从顶点着色器阶段传递到片段着色器的文章和帖子。但我仍然不确定这一点: 如果您在顶点着色器中有一些输出变量(我称他为 vtxs),在片段着色器(frgs)中有一些变量,OpenGl 如何关联它们以便它们引用相同的值(我忽略了值传递的事实到 frgs 被插值)?我必须按某种顺序写下来吗?如果我这样写,OpenGl 如何解释这些变量:
vtxs:
out float x;
out vec4 mvp;
frgs:
in vec4 mvp;
in float x;
in double newvar;
注意:我打乱了 var 类型,frgs 中的 var 中还有 1 个,然后 vtxs 中的 out vars。
我看到布局列表中的位置规范是分配...地址的一种方式? ...到一个变量,但我有一个古老的上网本不支持这样的变量装饰器。
提示:您知道某种调试着色器吗?我的意思是,在 cpu 程序中你可以添加一些 printfs 但我没有在 glsl 中看到这样的函数...
所以,总结一下,这是我的问题:
你到底用layout(location=...)指定了什么关于着色器的结果?
不同着色器阶段之间的值matching/association是如何工作的?有无 "location="?
调试 glsl 着色器
默认情况下,阶段之间的变量按名称匹配。
对于位置,您可以从概念上将阶段之间传递的数据视为 vec4 数组。然后 location 是我们用来传递该变量的数组的索引。
大于 vec4 的类型获得多个连续位置。对于较新的 opengl 版本(或 ARB_enhanced_layouts),这些也是一个组件布局限定符,用于在该 vec4 数组中更紧密地打包值。
我不确定按名称和位置进行混合匹配时如何分配位置。
默认情况下,输入和输出在接口之间按名称匹配。对于顶点着色器输入,索引的默认 'automatic' 分配是 arbitrary,因为它可能因实现而异。
layout
限定符允许明确指定 input\output 的存储类型和位置。由于顶点输入的自动分配是任意的,你应该使用 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);
}
你也可以