Vector GLSL,输出颜色的默认值

Vector GLSL,输出颜色的默认值,vector,glsl,shader,default-value,opengl-3,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

如果不设置,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前后深度剥离示例的片段着色器,您可以找到代码org.jogl.demos.dualDepthPeople\org.jogl.demos.dualDepthPeople\src\demos\dualDepthPeople\shaders\front\u People\u final\u fragment.glsl

如果不为片段着色器输出赋值,则结果未定义。来自OpenGL 3.3规范第3.9.2节“着色器执行”,第190页:

未定义与片段着色器未写入的片段关联的任何颜色或颜色组件

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

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

然后在第31页第4.6.3节“输出”中:

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


关于问题的第二部分,我不认为GLSL版本中从
vec4
vec3
的隐式转换是合法的。某些编译器可能没有给出错误,但它们应该给出错误。

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


我注意到您有一个纹理,对“未绑定的”/不完整的纹理进行采样是不同的。有一个默认值,但在实践中,我不会对所有驾驶员都依赖它

如果片段着色器使用采样器,则关联的纹理对象是哪个 未完成,如第3.8.10节所定义,纹理图像单元将 返回值(R,G,B,A)=(0,0,0,1)


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

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


但如果不设置碎片颜色,实际会发生什么? 规范中未定义意味着
(0,0,0,1)
是一个有效值,实际上可能就是您得到的值。如果GL实现(如Nvidia或ATI随其驱动程序+硬件提供的实现)要使其成为一致的返回值,则生成的着色器代码需要设置默认值,或者在未设置默认值时捕捉情况。这只会增加开销。什么都不做反而更快

但是着色器仍然必须返回一个值,并且会返回片段着色器线程的寄存器中的任何值。这是未初始化的数据(从着色器程序的角度)。就像CPU程序中未初始化的内存一样,该值可以是任何值,通常取决于之前存在的内容。根据GPU所执行的上一个任务(即运行的另一个着色器),这是全零的情况,甚至是相当一致的情况并不少见。虽然我发现片段着色器中的未初始化值通常显示为闪烁,并且可以生成如下模式:


要修复错误,请将其更改为
outputColor.rgb=frontColor.rgb+backgroundColor*frontColor.a
@RichardViney,是的,我知道,但这段代码是深度剥离示例的原始示例,我想了解作者的意思是什么,因为他们将
backgroundColor
声明为
vec4
。你不能像那样直接做
vec4+vec3
。@RichardViney我不知道,我认为这不太可能,因为在代码中他们实际上是在加载vec3制服。。(注:我在问题中插入了原始代码的链接)这是一个非常古老的示例。NVIDIA早期的GLSL编译器可能会允许这样的自动转换(早在Cg编译器上构建时),但它在现代GLSL中肯定无效。幸运的是,解决方法很简单。