如何在opengl中最好地实现权重标准化混合操作?

时间:2015-03-23 23:19:42

标签: opengl-es webgl

假设我有RGBA格式的源颜色(sr,sb,sg,sa),同样目标颜色(dr,db,dg,da) ,所有组件均假设为[0.0,1.0]。

p =(sa)/(sa + da) q = da /(sa + da)。请注意,p + q = 1.0。如果sa和da均为0.0,请执行任何操作。

我想在opengl中实现混合,以便混合结果 =

(p*sr + q*dr, p*sg + q*dg, p*sb + q*db, sa+da).

(或者更严格,在https://www.opengl.org/sdk/docs/man/html/glBlendFunc.xhtml之后,我希望f_R,f_G和f_B对于src是p,对于dst是q;并且f_A = 1.)

例如,在(sa + da)== 1.0的特殊情况下,我可以使用glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);但我特意试图处理不总和为1.0的alpha值。 (这就是我称之为'权重规范化'的原因 - 我想将src和dst alphas视为需要归一化为线性组合系数的权重。)

您可以假设我可以完全控制传递给opengl的数据,代码渲染以及顶点和片段着色器。我的目标是WebGL,但我一般也很好奇。

我能想到的最好的方法是将所有src rgb值按一个,一个,预乘的方式与alpha混合,然后在第二个传递中除以alpha。但是我担心这样会牺牲很多颜色深度,特别是如果各种alpha值都很小的话。

1 个答案:

答案 0 :(得分:1)

我不相信标准混合方程可以做到这一点。至少我想不出怎样的方式。

然而,使用OpenGL这很容易。混合可能只是工作的错误工具。我会将您当前描述为“源”和“目标”的内容输入到片段着色器中。然后你可以按照你的心愿来混合和组合它们。

假设您想要以您描述的方式组合两个纹理。现在你可能会有这样的事情:

  1. 绑定纹理1。
  2. 渲染到默认的帧缓冲区,对当前绑定的纹理进行采样。
  3. 设置花式混合。
  4. 绑定纹理2。
  5. 渲染到默认的帧缓冲区,对当前绑定的纹理进行采样。
  6. 你能做什么呢?

    1. 将纹理1绑定到纹理单元0。
    2. 将纹理2绑定到纹理单元1。
    3. 渲染到默认的帧缓冲区,对两个绑定纹理进行采样。
    4. 现在,您可以在着色器代码中使用两种纹理的值,并且可以应用任何类型的逻辑和数学来计算组合颜色。

      如果您的原始数据不是来自纹理,而是渲染的结果,同样的事情也有效。假设您在渲染过程中有两个部分,您希望按照您描述的方式进行组合:

      1. 将纹理1作为渲染目标附加到FBO。
      2. 渲染内容的第一部分。
      3. 将纹理2作为渲染目标附加到FBO。
      4. 渲染内容的第二部分。
      5. 将纹理1绑定到纹理单元0。
      6. 将纹理2绑定到纹理单元1。
      7. 渲染到默认的帧缓冲区,对两个绑定纹理进行采样。