【问题标题】:GLSL, default value for output colorGLSL,输出颜色的默认值
【发布时间】:2015-05-21 01:30:03
【问题描述】:

如果您不设置,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

【问题讨论】:

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

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


【解决方案1】:

关于默认片段着色器输出: 没有默认值,如果不设置,结果为 undefined。查看其他答案。


我注意到您有一个纹理,并且对“未绑定”/不完整纹理进行采样是不同的[1][2]一个默认值,但实际上我不会对所有驱动程序都依赖它!:

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


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

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


但是当您不设置片段颜色时,实际上会发生什么?

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

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

【讨论】:

    【解决方案2】:

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

    与片段相关联的任何颜色或颜色分量都未由片段着色器写入。

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

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

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

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

    关于问题的第二部分,我不相信 GLSL 版本中从 vec4vec3 的隐式转换是合法的。一些编译器可能没有给出错误,但他们应该有。

    【讨论】:

      猜你喜欢
      • 2013-02-03
      • 2021-08-02
      • 2012-05-08
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多