解开在不同渲染目标的OpenGL混合中何时和什么值被钳位

时间:2015-05-10 16:39:47

标签: opengl blending

TL; DR:在启用混合时,哪些值被钳制以及在什么情况下(启用标志和渲染缓冲区类型(特别是RGBA_F32))?

  • 片段着色器输出?
  • 混合因素?
  • 混合方程的结果?
  • 其他吗

我发现的夹紧机制:

  1. 着色器输出(通过glClampColor:这似乎可以控制glReadPixels,但有extension flags GL_CLAMP_VERTEX_COLORGL_CLAMP_FRAGMENT_COLOR做什么“东西”。据我所知,从扩展规范来看,它们会钳制顶点或片段着色器的输出。
  2. 着色器输出(通过渲染到定点):请参阅引用GL规范的this answer:“从浮点值f到相应的转换无符号归一化定点值c的定义是首先将f钳位到[0,1] ... “相反,(当写入浮点渲染目标时,大概是),Nicol Bolas写道{{ 3}}“碎片着色器写的内容将永远松开。”。
  3. 隐含裁剪:来自here:“所有比例系数都有范围[0,1]。”这是否意味着源和目标因素是方程式发生之前被夹住了吗?
  4. 隐含夹紧:来自documentation for glBlendFunc:“对于这些等式,所有颜色分量都被理解为具有[0,1]范围内的值。”这是否意味着在方程发生之前,源和目标颜色被钳制?
  5. 结果夹紧:从同一页面:“这些方程的结果被限制在[0,1]范围内。
  6. 在我对RGBA_F32渲染目标的实验中,没有发生这些钳位模式(我通过使用glGetTexImage读回渲染目标的值来确认这一点)。我最好需要(3)发生,但我要求对文件进行澄清,以便我能够自己解决。

1 个答案:

答案 0 :(得分:2)

你引用的部分内容非常陈旧,可能存在混淆的根源。我从现代 GL的角度来看看你的观点,我将引用OpenGL 4.5 core profile规范。但是,这些都不是特定于OpenGL 4.x.自GL 3.2核心以来,这基本没有变化。

1。 glClampColor()唯一剩余的功能是在glReadPixels期间进行限制。引用第680页的规范:

  

请注意,FrontFaceClampColor命令不会被弃用,因为它们仍会影响其他未弃用的功能;然而   ClampColor个目标是CLAMP_VERTEX_COLORCLAMP_FRAGMENT_COLOR   。弃用"

限制顶点着色器输出仅对gl_FrontColorgl_BackColor等已删除的内置变换有意义。那些只需要模仿固定功能顶点处理,根本不是一个好主意。对于通用输出,GL无法知道哪些值是颜色,哪些值不是。

2. 片段着色器的情况类似。使用现代渲染方法,输出不再是必然的颜色,而是表示通用数据,因此隐含地钳位值是有害的。如果需要,您始终可以手动钳制着色器中的值。

规格Reto Koradi的答案在GL 4.5规范中没有变化。只有在相应的渲染目标是定点或整数格式时,才会限制着色器输出。

<强> 3.,4。和5. 那些文件已经过时了。 GL规范在第17.3.8节中对此进行了说明:

  

如果颜色缓冲区是定点的,则源和的组件   目标值和混合因子各自被钳位到[0; 1]或   [-1; 1]分别用于无符号归一化或有符号归一化   在评估混合方程之前的颜色缓冲区。如果颜色   缓冲区是浮点数,不会发生钳位。由此产生的四个   值被发送到下一个操作。混合仅适用于   颜色缓冲区具有定点或浮点格式。如果颜色   buffer具有整数格式,继续执行下一步操作。

混合结果的钳位发生在下一步中,它处理可选的sRGB转换(但是,钳位步骤与sRGB转换相关联)。引用第17.3.9节:

  

R,G和B的结果cs值,未修改的A形成a   新的RGBA颜色值。如果颜色缓冲区是固定点,则各自   元件被钳位到[0; 1]然后转换为   使用公式2.3定点值。得到的四个值是   发送到随后的抖动操作。

所以是的,当使用GL_RGBA32F帧缓冲时,没有隐式钳位发生。实际上,这是通用案例唯一有用的操作模式。如果您需要在步骤3中进行一些限制:只需将这些因素钳制到glBlendFunc()之前。