首页 > 资讯 > 正文

WebGL颜色合成|世界热点

发布时间:2023-04-25 07:13:10 来源:哔哩哔哩

这是一个五彩缤纷的世界,彩色的玻璃让窗外的风景绚丽夺目。

我们可以把世界想象成一张画布,这个世界里存在着两种风景:


【资料图】

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

标签:

上一篇:天天通讯!存货占用率
下一篇:最后一页