GLSL,输出颜色的默认值

时间:2015-03-18 10:05:10

标签: vector glsl shader default-value opengl-3

如果你没有设置它,GLSL中输出颜色的默认值是什么?

#version 330

uniform sampler2DRect colorTex;
uniform vec3 backgroundColor;

out vec4 outputColor;

void main(void)
{
    vec4 frontColor = texture(colorTex, gl_FragCoord.xy);
    outputColor.rgb = frontColor + backgroundColor * frontColor.a;
}

是(0,0,0,1)?

Ps:该代码属于旧GL,尝试将其与GL3一起使用,我收到以下错误

  

错误C7011:来自" vec4"的隐式演员表到" vec3"

我认为在旧GL中允许隐式演员是正确的吗?

这是Nvidia前后深度剥离示例的片段着色器,你可以找到代码here,org.jogl.demos.dualdepthpeeling \ org.jogl.demos.dualdepthpeeling \ src \ demos \ dualDepthPeeling \着色器\ front_peeling_final_fragment.glsl

2 个答案:

答案 0 :(得分:4)

关于默认片段着色器输出: 如果您没有设置默认值,则结果为未定义。请参阅其他答案。


我注意到你有一个纹理,并且'未绑定'/不完整纹理的采样不同[1] [2] 是默认值,但实际上我并不依赖于所有驱动程序!:

  

如果片段着色器使用与关联纹理对象相关的采样器       不完整,如3.8.10节所定义,纹理图像单元将       return(R,G,B,A)=(0,0,0,1)。 [↱]


还有一个统一值,也可能无法设置。这些对于整个绘制调用保持不变,并且像采样器一样,也有一个默认值(尽管这更像是一个“初始”值)。

  

由于链接操作成功,属于程序的所有活动用户定义的统一变量将初始化为0 [↱]


但是当你没有设置片段颜色时,实际会发生什么?

在规范中未定义意味着(0, 0, 0, 1)是一个有效值,实际上可能是你得到的值。如果GL实现(例如Nvidia或ATI提供的驱动程序+硬件)要使其成为一致的返回值,则生成的着色器代码需要设置默认值或在未设置默认值时捕获大小写。这只会增加开销。不做任何事情都会更快。

着色器必须仍然返回一个值,并且返回片段着色器线程的寄存器/ s中的值。这是未初始化的数据(从着色器程序的角度来看)。就像CPU程序中未初始化的内存一样,值可以是任何值,通常取决于事先的内容。根据GPU正在执行的先前任务(即您运行的另一个着色器),这通常为全零,甚至是非常一致的情况并不罕见。虽然我发现片段着色器中未初始化的值通常表现为闪烁,并且可以制作如下模式:

nvidia rasterizer pattern

答案 1 :(得分:3)

如果您没有为片段着色器输出分配值,则结果是未定义的。从OpenGL 3.3规范,第3.9.2节"着色器执行",第190页:

  

与片段相关联的任何颜色或颜色组件都未被片段着色器写入。

相应的GLSL规范证实了这一点。在第4.3节"存储限定符",第28页:

  

没有在声明或应用程序中初始化的存储限定符的全局变量不会被OpenGL初始化,而是输入带有未定义值的main()。

然后在第4.6.3节"输出",第31页:

  

必须在全局范围内声明输出变量。在着色器执行期间,它们将表现为正常的非限定全局变量。

在问题的第二部分,我不相信有一个GLSL版本,其中从vec4vec3的隐式演员是合法的。有些编译器可能没有给出错误,但它们应该有。