Blend混合模式 与 20余种颜色混合模式代码实现
混合模式
-
可简单理解为 指上下层图片相互有重叠时如何取色的一种称呼
-
以下是百科给的解释 但我们今天要说的是Unity中的颜色混合
混合模式是图像处理技术中的一个技术名词,不仅用于广泛使用的Photoshop中,也应用于AfterEffect、llustrator 、 Dreamweaver、 Fireworks等软件。主要功效是可以用不同的方法将对象颜色与底层对象的颜色混合。当您将一种混合模式应用于某一对象时,在此对象的图层或组下方的任何对象上都可看到混合模式的效果。
Blend
-
在编写shader时我们可以在SubShader或Pass中用Blend与BlendOp指明该对象与下一层色彩如何进行颜色混合
-
常用的混合模式通过Blend实现 如下所示
![](http://i0.hdslb.com/bfs/article/bde48f427684fc834cab69fd9c22d0ed707753dc.png@1124w_1050h.webp)
-
以下为测试图片
![](http://i0.hdslb.com/bfs/article/e9f21f02943e17c61a65a28c054480e3b7a52c0d.png@1320w_818h.webp)
![](http://i0.hdslb.com/bfs/article/2119f83419440750dc417659042181cb33c4f296.png@1320w_922h.webp)
-
常用的滤色混合效果如下
![](http://i0.hdslb.com/bfs/article/43a1e8888859260f83e22b67bbb352952c0bdc21.png@1320w_742h.webp)
代码实现混合模式
-
可以看到Blend已经可以实现很多种混合效果 但这也只是混合模式的一部分
-
而接下来才是重点 我们要在Shader中代码自己实现更多的混合模式
-
以方便实现更多的Shader效果
-
框架代码如下 还是前几篇文章一样 只更改frag中代码
![](http://i0.hdslb.com/bfs/article/cd1d3fa5bb681a6f005a12da5d843669e648c87a.png@1262w_1950h.webp)
-
其中MainTex为底图 BlendTex为要混合的图片
-
颜色取值为(0-1) A为底图颜色 B为混合图颜色 C为输出图颜色
![](http://i0.hdslb.com/bfs/article/113f7fae8426b56c877be3219830002f8e2bffbd.png@1250w_508h.webp)
-
使用step()函数来代替if判断
注意:非常多资料 点光效果 使用两个min函数 实际效果还原应该是一个min一个max函数
![](http://i0.hdslb.com/bfs/article/90fbd2f4bbbeef24ba7dd6fe4bdbf2580146dc30.png@1320w_1288h.webp)
Unity实现与Ps效果对比图
-
创建材质球 给与材质球该shader 将材质球赋给 Image UI 或者 2D Sprite
-
添加对应贴图 如下
![](http://i0.hdslb.com/bfs/article/8bd506f9cf7f1a6dbd3522494956ad7fa2943643.png@582w_850h.webp)
-
查看实验效果(左 Unity实现 右 Ps对比)
![](http://i0.hdslb.com/bfs/article/34ed141d0cb9acbebd1aec38cc6ce35122272aba.png@1320w_514h.webp)
![](http://i0.hdslb.com/bfs/article/2ec3fddcfd5683342142fd3a917eb17b4497ab0f.png@1320w_498h.webp)
![](http://i0.hdslb.com/bfs/article/a960a1494f7996eb030fc746bc9632ba4d3fecd4.png@1320w_494h.webp)
![](http://i0.hdslb.com/bfs/article/8d2fbc990859d6f6270128914e329a74757b41be.png@1320w_490h.webp)
![](http://i0.hdslb.com/bfs/article/fb618ba4d0d92446a3d81d44933923f177a4f1cb.png@1320w_524h.webp)
![](http://i0.hdslb.com/bfs/article/fed74e42c5b3ccb10950866722322363f8e7a87a.png@1320w_498h.webp)
![](http://i0.hdslb.com/bfs/article/8885f15c4f07578084ac831474bf1f3a1280e185.png@1320w_518h.webp)
![](http://i0.hdslb.com/bfs/article/6089c6cb11b86bf275f7c851ba8bc88371898b43.png@1320w_478h.webp)
![](http://i0.hdslb.com/bfs/article/c74be5879d4a127dd9729eace0b01c0e818d91db.png@1320w_500h.webp)
![](http://i0.hdslb.com/bfs/article/2b7432c81bfa0d894d19b62b26a71b3d237ac6d1.png@1320w_502h.webp)
![](http://i0.hdslb.com/bfs/article/a3e9489766565064a562cc9fcd5e62dd2d3d9058.png@1320w_490h.webp)
![](http://i0.hdslb.com/bfs/article/d02b8a242bca031a3df9d02a035bfd29dacd188d.png@1320w_496h.webp)
![](http://i0.hdslb.com/bfs/article/8d454d937faadf72cee08752ceaed7278e5b3b04.png@1320w_502h.webp)
![](http://i0.hdslb.com/bfs/article/03e7acd1b530a47e20b56649e2e923e2e12774a3.png@1320w_500h.webp)
![](http://i0.hdslb.com/bfs/article/c0eb0ac9b0be857c879ad10d89699f75f2cf98cb.png@1320w_496h.webp)
![](http://i0.hdslb.com/bfs/article/4a7b3dc2397c9aff8ff60f6cdbbaa8d895df9028.png@1320w_516h.webp)
![](http://i0.hdslb.com/bfs/article/fbeedb313252a9d8e412ddef0b1b214041610e34.png@1320w_488h.webp)
![](http://i0.hdslb.com/bfs/article/dfcc6a789414d9c1556687de40b491a775e93d2c.png@1320w_494h.webp)
![](http://i0.hdslb.com/bfs/article/f3605765bd6e93790cbddd060c440b147bb3ebc7.png@1320w_500h.webp)
![](http://i0.hdslb.com/bfs/article/df8e624cfaafbcecf81c43a9b35fcf44246ddaab.png@1320w_514h.webp)
核心代码
fixed4 C =A*(1-B.a)+B*(B.a); //正常透明度混合
fixed4 C =min(A,B); //变暗
fixed4 C =max(A,B); //变亮
fixed4 C =A*B ; //正片叠底
fixed4 C=1-((1-A)*(1-B));//滤色 A+B-A*B
fixed4 C =A-((1-A)*(1-B))/B; //颜色加深
fixed4 C= A+(A*B)/(1-B); //颜色减淡
fixed4 C=A+B-1;//线性加深
fixed4 C=A+B; //线性减淡
fixed4 ifFlag= step(A,fixed4(0.5,0.5,0.5,0.5));
fixed4 C=ifFlag*A*B*2+(1-ifFlag)*(1-(1-A)*(1-B)*2);//叠加
fixed4 ifFlag= step(B,fixed4(0.5,0.5,0.5,0.5));
fixed4 C=ifFlag*A*B*2+(1-ifFlag)*(1-(1-A)*(1-B)*2); //强光
fixed4 ifFlag= step(B,fixed4(0.5,0.5,0.5,0.5));
fixed4 C=ifFlag*(A*B*2+A*A*(1-B*2))+(1-ifFlag)*(A*(1-B)*2+sqrt(A)*(2*B-1)); //柔光
fixed4 ifFlag= step(B,fixed4(0.5,0.5,0.5,0.5));
fixed4 C=ifFlag*(A-(1-A)*(1-2*B)/(2*B))+(1-ifFlag)*(A+A*(2*B-1)/(2*(1-B))); //亮光
fixed4 ifFlag= step(B,fixed4(0.5,0.5,0.5,0.5));
fixed4 C=ifFlag*(min(A,2*B))+(1-ifFlag)*(max(A,( B*2-1))); //点光
fixed4 C=A+2*B-1; //线性光
fixed4 ifFlag= step(A+B,fixed4(1,1,1,1));
fixed4 C=ifFlag*(fixed4(0,0,0,0))+(1-ifFlag)*(fixed4(1,1,1,1)); //实色混合
fixed4 C=A+B-A*B*2; //排除
fixed4 C=abs(A-B); //差值
fixed4 ifFlag= step(B.r+B.g+B.b,A.r+A.g+A.b);
fixed4 C=ifFlag*(B)+(1-ifFlag)*(A); //深色
fixed4 ifFlag= step(B.r+B.g+B.b,A.r+A.g+A.b);
fixed4 C=ifFlag*(A)+(1-ifFlag)*(B); //浅色
fixed4 C=A-B; //减去
fixed4 C=A/B; //划分
结语
-
这些公式不用记住 再用到的时候查找挑选合适的方法就好
-
项目源代码:https://github.com/QinZhuo/ShaderLab