【发布时间】:2012-04-08 15:58:37
【问题描述】:
我目前正在使用 3 个不同的着色器(顶点、几何和片段),每个着色器属于不同的程序,全部收集在一个程序管道中。
问题在于 Geometry 和 Fragment 将它们的变化归零,也就是说,它们不包含管道中先前着色器先前写入的值。
对于每个着色器:
glCreateShader(...)
glShadersource(...)
glCompileShader(...)
glGetShaderiv(*shd,GL_COMPILE_STATUS,&status)
对于每个程序:
program[index] = glCreateProgram()
glAttachShader(program[index],s[...])
glProgramParameteri(program[index],GL_PROGRAM_SEPARABLE,GL_TRUE)
glLinkProgram(program[index])
glGetProgramiv(program[index],GL_LINK_STATUS,&status)
然后:
glGenProgramPipelines(1,&pipeline_object)
在 gl 绘图中:
glBindProgramPipeline(pipeline_object)
glUseProgramStages(pipeline_object,GL_VERTEX_SHADER_BIT,program[MY_VERTEX_PROGRAM])
and again for the geometry and fragment programs
顶点着色器:
#version 330
//modelview and projection mat(s) skipped
...
//interface to geometry shader
out vec3 my_vec;
out float my_float;
void main() {
my_vec = vec3(1,2,3);
my_float = 12.3;
gl_Position = <whatever>
}
几何着色器:
#version 330
//input/output layouts skipped
...
//interface from vertex shader
in vec3 my_vec[];
in float my_float[];
//interface to fragment shader
out vec3 my_vec_fs;
out float my_float_fs;
void main() {
int i;
for(i=0;i<3;i++) {
my_vec_fs = my_vec[i];
my_float_fs = my_float[i];
EmitVertex();
}
EndPrimitive();
}
片段着色器:
#version 330
//interface from geometry
in vec3 my_vec_fs;
in float my_float_fs;
void main() {
here my_vec_fs and my_float_fs come all zeroed
}
我是否错过了在程序管道的不同阶段之间进行写入/读取变化的一些关键步骤?
更新:
我尝试使用布局位置限定符,以确保每个人都在同一个向量上“交谈”,因为 GLSL 规范规定:
layout-qualifier-id location = integer-constant 只接受一个论点。比如vec4 normal中的layout(location = 3);将确定着色器输入法线分配给矢量位置编号 3。对于顶点着色器输入,位置指定从中获取输入值的通用顶点属性的编号。对于所有其他着色器类型的输入,该位置指定一个向量编号,该向量编号可用于匹配前一个着色器阶段的输出,即使该着色器位于不同的程序对象中。
但添加
layout(location = 3) out vec3 my_vec;
不编译
所以我尝试通过 glBindAttribLocation() 做同样的事情,我得到 no 错误,但行为仍然没有改变
更新 2
如果我添加 "#extension GL_ARB_separate_shader_objects: 启用"
然后我可以使用 layout(location = n) in/out var; 然后它就可以工作了。
找到:
GLSL 330: Vertex shaders cannot have output layout qualifiers
GLSL 420: All shaders allow location output layout qualifiers on output variable declarations
这很有趣.. 如果您声明#version 330,您不应该能够使用布局输出限定符,即使您启用了扩展.. ..但扩展名再次声明:
此 ARB 扩展扩展了 GLSL 语言对布局限定符的使用,以提供跨阶段接口。
现在我想知道为什么使用 glBindAttribLocation() 或仅使用纯名称匹配+启用 ARB 扩展时它不起作用!
【问题讨论】:
-
如果使用
#extension GL_ARB_separate_shader_objects : enable命令显式启用扩展会发生什么?在这种情况下它是否必要并不完全清楚,因为您的着色器本身没有使用可分离的功能。但它不会受伤。