管道程序中着色器之间的输入/输出变量 [英] in/out variables among shaders in a Pipeline Program

查看:231
本文介绍了管道程序中着色器之间的输入/输出变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用3种不同的着色器(顶点,几何和片段),每个着色器都属于一个不同的程序,并且全部收集在一条程序管道中.

I am currently using 3 different shaders (Vertex, Geometry and Fragment), each belonging to a different program, all collected in a single Program Pipeline.

问题在于,几何体"和片段"的变化量为零,也就是说,它们不包含先前由着色器在管道中写入的值.

The problem is that the Geometry and Fragment have their in varyings zeroed, that is, they do not contain the value previously written by the preceeding shader in the pipeline.

对于每个着色器:

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
}

我是否缺少在程序管道中不同阶段之间进行写/读操作的关键步骤?

Am I missing some crucial step in writing/reading varying between different stages in a program pipeline?

更新:

UPDATE:

我尝试使用布局位置限定符,只是为了确保每个人都在同一个向量上交谈",因为GLSL规范指出:

I tried with the layout location qualifier just to be sure everyone was 'talking' on the same vector, since the GLSL specs states:

layout-qualifier-id位置=整数常量 仅接受一个论点.例如,vec4 normal中的layout(location = 3);将确定将着色器输入法线分配给矢量位置编号3.对于顶点着色器输入,位置指定从中获取输入值的通用顶点属性的编号.对于所有其他着色器类型的输入,该位置指定一个向量号,即使该着色器位于不同的程序对象中,该向量号也可用于与先前着色器阶段的输出进行匹配.

layout-qualifier-id location = integer-constant Only one argument is accepted. For example, layout(location = 3) in vec4 normal; will establish that the shader input normal is assigned to vector location number 3. For vertex shader inputs, the location specifies the number of the generic vertex attribute from which input values are taken. For inputs of all other shader types, the location specifies a vector number that can be used to match against outputs from a previous shader stage, even if that shader is in a different program object.

但添加

layout(location = 3) out vec3 my_vec;

不编译

所以我尝试通过glBindAttribLocation()做同样的事情,我得到 no 错误,但是行为仍然没有改变

So I tried to do the same via glBindAttribLocation(), I get no errors, but the behaviour is still unchanged

更新2

UPDATE 2

如果我添加 "#extension GL_ARB_separate_shader_objects:启用"

If I add "#extension GL_ARB_separate_shader_objects: enable"

然后我可以在in/out var中使用layout(location = n); 然后工作.

then I can use layout(location = n) in/out var; and then it works.

发现:

GLSL 330: Vertex shaders cannot have output layout qualifiers
GLSL 420: All shaders allow location output layout qualifiers on output variable declarations

这很有趣.如果您声明#version 330,则即使启用扩展名,也不应使用布局输出限定符. ..但扩展名再次指出:

This is interesting.. If you declare #version 330 you shouldnt be able to use a layout out qualifier, even if you enable an extension.. ..but again the extension states:

此ARB扩展扩展了GLSL语言对布局限定符的使用,以提供跨阶段接口.

This ARB extension extends the GLSL language's use of layout qualifiers to provide cross-stage interfacing.

现在我想知道为什么使用glBindAttribLocation()或仅使用纯名称匹配+启用了ARB扩展名后为什么不起作用!

Now Idlike to know why it does not work using glBindAttribLocation() or just with plain name matches + ARB extension enabled!

推荐答案

在至少一个实现中(我认为是webgl和较旧的chrome),我发现了glBindAttribLocation()的错误,我认为问题是,您必须绑定顶点属性按数字顺序.因此,事实证明,使用它没有用.我必须切换到getAttribLocation()才能使其正常工作.

In at least one implementation (webgl on and older chrome I think) I found bugs with glBindAttribLocation() I think the issue was, you had to bind vertex attribs in numerical order. So it proved not useful to use it. I had to switch to getAttribLocation() to get it to work.

这篇关于管道程序中着色器之间的输入/输出变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆