本章的图片和之前两张的图替换一下,第一张是底层的图片,第二张图是进行混合模式的,这是png图片,空白的地方全是透明的。
公式图如下:
叠加
叠加这里就需要进行进行各个通道也就是rgb的值是否小于128
,在webgl中就是0.5
,根据大小的判断去进行公式计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const FSHADER_SOURCE = ` precision mediump float; varying vec2 v_PointUV; uniform sampler2D u_Image; uniform sampler2D u_Image1;
float colorValue(float color1, float color2){ float value = 0.0; if(color1 <= 0.5){ value = color1 * color2 / 0.5; }else{ value = 1.0 - (1.0-color1) * (1.0-color2)/0.5; } return value; }
void main() { vec4 baseColor = texture2D(u_Image, v_PointUV); vec4 blendColor = texture2D(u_Image1, v_PointUV); vec4 color = vec4(1.0);
color.r = colorValue(baseColor.r,blendColor.r); color.g = colorValue(baseColor.g,blendColor.g); color.b = colorValue(baseColor.b,blendColor.b);
if(blendColor.a == 0.0){ color = baseColor; } gl_FragColor = color; } `;
|
运行效果:
强光
强光的判断是和叠加反着来的,shader就不写了,和上面的例子判断是相反的,效果图:
柔光
这里要用到平方
和根号
,glsl里面的内建的函数有这两种方法,分别是 pow(x,y)
,sqrt(x)
。pow代表x的次方。和js的表达意思差不多。
注意:下面公司用到的乘2
,要写成2.0
,因为之前声明的就是浮点数,所以所有的计算都是浮点数的计算。
代码如下:
1 2 3 4 5 6 7 8 9
| float colorValue(float color1, float color2){ float value = 0.0; if(color2 <= 0.5){ value = color1 * color2 / 0.5 + pow(color1,2.0) * (1.0-2.0 * color2); }else{ value = color1 * (1.0 - color2)/0.5 + sqrt(color1) * (2.0 * color2 - 1.0); } return value; }
|
效果图如下:
亮光
亮光也是需要做0.5
的判断的,如下
1 2 3 4 5 6 7 8 9
| float colorValue(float color1, float color2){ float value = 0.0; if(color2 <= 0.5){ value = color1 - (1.0 - color1) * (1.0 - 2.0 * color2) / (2.0 * color2); }else{ value = color1 + color1 * (2.0 * color2-1.0) / (2.0 * (1.0 - color2)) ; } return value; }
|
效果图:
点光
1 2 3 4 5 6 7 8 9
| float colorValue(float color1, float color2){ float value = 0.0; if(color2 <= 0.5){ value = min(color1,2.0 * color2); }else{ value = max(color1,2.0 * color2 - 1.0); } return value; }
|
效果:
线性光
线性光的效果和点光的差不多的,但是线性光的呈现效果会比点光的更亮一些。
1 2 3
| float colorValue(float color1, float color2){ return color1 + color2 * 2.0 - 1.0; }
|
实色混合
实色混合这里代码要用到三目运算符?:
(实现效果和ps有点不一致)
1 2 3
| float colorValue(float color1, float color2){ return (color1 + color2) >= 1.0 ? 1.0 : 0.0; }
|
效果图:
排除和差值
排除和差值的公式都很简单就放在一起了
1 2 3 4 5 6 7 8 9
| float colorValue(float color1, float color2){ return color1 + color2 - color1 * color2 / 0.5; }
float colorValue(float color1, float color2){ return abs(color1 - color2); }
|
排除和差值效果如下: