这是一个五彩缤纷的世界,彩色的玻璃让窗外的风景绚丽夺目。
我们可以把世界想象成一张画布,这个世界里存在着两种风景:
【资料图】
source:即将落笔的风景,比如彩色的玻璃。
destination:已经落笔的风景,比如窗外的城市。
当这两种风景合到一起后,便会形成新的destination,进入我们的眼睛。
在webgl 中有两种合成颜色的方法:
blendFunc(sfactor, dfactor) 基于sfactor, dfactor对source和destination的rgba颜色做合成。
blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) 基于srcRGB, dstRGB对source和destination的rgb颜色做合成;基于srcAlpha, dstAlpha对source和destination的alpha透明度做合成。
blendFunc(sfactor, dfactor) 适合对没有透明度的颜色做合成;
blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) 适合对有透明度的颜色做合成。
其中的参数需要按照下面的Constant来写。
我们详细说一下上面的两个合成方法。
blendFunc(sfactor, dfactor) 的计算原理如下:
举个例子。
已知:
source是(0,0,1,1)
destination是(1,1,0,1)
sfactor是gl.ONE
dfactor是gl.ZERO
求:BlendColor
解:
上面的算法就是常见的颜色覆盖,就像画水粉一样,顶上的source压住下面的dfactor。
我们可以写个webgl测试一下。
那如果黄色是半透明的会怎么样呢?
改下代码:
效果如下:
相信你可以看出,黄色变淡了。
这是为什么呢?用之前的公式印证一番即可:
由上可知,合成颜色的透明度变了。
但为什么合成颜色的透明度变了会导致颜色变淡呢?
这跟webgl颜色与canvas画布背景色的合成方式有关,其具体算法我先不细说,大家先知道颜色的透明度会影响颜色的最终渲染效果即可。
接下来,我们还要解决一个问题。
既然黄色半透明了,那黄色与蓝色相交的部分就应该有所变化。
这样我们就得换一套合成因子了:
效果如下:
其算法如下:
通过上面的算法可以看到合成颜色变灰了。
但同时也出现了一个问题:合成区域的透明度变低了。
一个半透明的图像合上一个不透明的图像后,其透明度是不可能降低的。
因此,这个透明度需要与rgb分开计算。
webgl就提供了一个这样的方法-blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)。
改一下代码,把之前的blendFunc()方法改成blendFuncSeparate()方法。
效果如下:
现在的合成颜色就明显比之前颜色暗了。
看一下其算法:
因为透明度的极大值就是1,所以1.5 的透明度依旧是1。
现在关于blendFunc()和blendFuncSeparate()的常规用法,我们就说完了。
我们还可以在其中写入其它的constant,让图像出现不同的合成效果,其作用,大家可以联想一下photoshop里的合成方式:
具体我就不给大家写了,接下来再聊点其它的相关方法。
我们之前在合成source和destination的时候,用的是加法。
其实,我们也可以用减法。
blendEquation(mode):blendFunc()方法中source和destination的合成方式。
gl.FUNC_ADD: source + destination (default value)
gl.FUNC_SUBTRACT: source - destination
gl.FUNC_REVERSE_SUBTRACT: destination - source
gl.MIN: Minimum of source and destination
gl.MAX: Maximum of source and destination
上面的mode我是从MDN里复制粘贴的,英语很好理解,不翻译了。
既然blendFunc()有了一个blendEquation(),那blendFuncSeparate()也自然有一个blendEquationSeparate()。
blendEquationSeparate(modeRGB, modeAlpha):对应blendFuncSeparate()中rgb和a的两种合成方式,其中的参数类型与blendEquation()一样。
在代码里测试一下。
为了方便看减法效果,把蓝色的点改成紫色。
效果如下:
相关算法就不写了,理解这个功能就好,免得在three.js的合成里的遇到一堆没见过的单词。
参考链接:
https://wgld.org/d/webgl/w029.html
https://wgld.org/d/webgl/w030.html
标签: