You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

blending与composite的区别及Canvas图层叠加色值计算规则咨询

关于blending与composite的差异及Canvas叠加色值计算问题

我当前问题涉及blending和composite两个术语,暂不明确二者的具体差异。

现有两个Canvas元素D、C,各元素RGBA参数如下:

  • D的RGBA值为:( 44 , 0 , 22 , 0.70 )
  • C的RGBA值为:( 134 , 55 , 0 , 0.35 )
  • 页面body的RGBA值为:( 122 , 200 , 0 , 1.00 )

绘制顺序为先绘制D,后绘制C,我需要明确二者相交区域的色值计算逻辑。

我目前推测计算逻辑近似如下函数:

gl.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE_MINUS_SRC_ALPHA);
// color(RGB) = (sourceColor * srcRGB) + (destinationColor * dstRGB)
// color(A) = (sourceAlpha * srcAlpha) + (destinationAlpha * dstAlpha)

但我实测发现D、C单独显示区域以及D覆盖C的区域的Alpha值始终为1,既然Alpha恒为1,为什么还需要使用blendFuncSeparate?

我已通过Gimp记录了D单独显示、C单独显示、D覆盖C三个区域的色值,对应截图如下:
色值对照截图

问题复现代码如下:

CSS代码

#c {
  position:absolute;
  top:50px;
  left:150px;
  background-color: rgba(134,55,0,0.35);
}
#d {
  position:absolute;
  top:0px;
  left:0px;
  background-color: rgba(44,0,22,0.7);
 
}
#namec {
  position:absolute;
  top:100px;
  left:350px;
  font-size: xx-large;
  color:white;

}
#named {
  position:absolute;
  top:50px;
  left:50px;
    font-size: xx-large;
  color:white;

 
}
body,html {
  background-color: rgb(122,200,0);
}

HTML代码

<canvas id="d"></canvas>
<canvas id="c"></canvas>
<div id='named'>D</div>
<div id='namec'>C</div>

术语差异说明

  • blending(混合) 特指在同一渲染目标上,将新绘制的源像素和已存在的目标像素,按照指定的权重公式计算得到最终像素的过程,核心是像素RGBA的数值运算规则。
  • composite(合成) 是更宽泛的概念,指多个图层堆叠时的最终视觉效果计算,blending是合成流程中处理RGBA数值的核心步骤之一,合成还包含图层裁剪、蒙版、混合模式选择等额外逻辑。

相交区域色值计算逻辑

你推测的混合函数是正确的,Canvas默认的混合逻辑就是基于blendFuncSeparate的预乘Alpha混合,计算分两步:

  1. 两个Canvas图层的混合(D为底,C为源)
    先计算叠加后的图层RGBA:
    • Alpha通道计算:A = C_A * 1 + D_A * (1 - C_A) = 0.35 + 0.7 * 0.65 = 0.805
    • RGB通道计算(预乘Alpha后计算):
      R = 134*0.35 + 44*0.7*0.65 ≈ 46.9 + 20.02 = 66.92
      G = 55*0.35 + 0*0.7*0.65 = 19.25
      B = 0*0.35 + 22*0.7*0.65 ≈ 10.01
  2. 混合后的图层再和不透明的body背景混合
    因为最终要输出到不透明的屏幕,所以会用上面得到的叠加图层再和背景混合,此时Alpha通道最终会被压缩为1:
    最终RGB:
    R = 66.92 + 122*(1-0.805) ≈ 66.92 + 23.79 = 90.71
    G = 19.25 + 200*(1-0.805) ≈ 19.25 + 39 = 58.25
    B = 10.01 + 0*(1-0.805) ≈ 10.01
    取整后就和你GIMP里测得的交叠区域色值一致。

为什么Alpha恒为1还需要用blendFuncSeparate

你看到的最终输出Alpha为1,是因为最后和不透明的页面背景混合后,透明通道被覆盖了,这不代表中间图层混合的过程不需要计算Alpha:

  1. 中间图层叠加时必须通过Alpha通道计算权重,才能得到正确的RGB混合结果,没有Alpha的权重计算,两个半透明图层的颜色混合会出现偏色。
  2. 如果后续你需要把Canvas的绘制结果导出为带透明通道的图片,或者再作为半透明图层和其他元素叠加,中间计算得到的Alpha值就会直接生效,而blendFuncSeparate可以保证RGB和Alpha通道的混合规则独立可控,避免混合后Alpha通道计算错误。

内容的提问来源于stack exchange,提问作者oceanGermanique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 09:51:03