一、什么是混合模式
- 混合
- 就是两种颜色混在一起。具体就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现新的效果
- 透过红色玻璃看绿色玻璃
- 可以先绘制绿色玻璃,再绘制红色玻璃。在绘制红色的时候,利用混合功能,把将要绘制上去的红色和原来的颜色(绿色)进行混合,于是得到新的颜色
- 也可以理解成,绿色首先对背景施加影响,无论红色玻璃存在与否,这个影响都是存在的,所以首先计算后面的绿色。然后再考虑前面的红色的影响。这也是我理解透明物体从后往前绘制的原理的一种方式。
最终颜色=Shader计算后的颜色值*源因子(SrcFactor)+累计颜色*目标因子(DstFactor)
二、混合模式的类型
PS中的混合模式
ShaderLab内的混合
如果颜色的某一分量超过1.0,则会被自动截取位1.0,不需要考虑越界的问题。
再所有着色器执行完毕,所有纹理都被应用,所有像素准备被呈现到屏幕之后,使用Blend命令来操作这些像素混合。
语法
语法 Blend Off 关闭blend混合(默认) Blend SrcFactor DstFactor 配置并启动混合计算 Blend SrcFactor DstFactor, SrcFactorA DstFactorA 同上,但是使用不同的要素来混合Alpha通道 BlendOp Value 如果使用BlendOp命令,则混合操作将设置为该值。否则,混合操作默认为Add。 BlendOp OpColor, OpAlpha 同上,但是使用不同的操作来处理alpha通道 AlphaToMaskOn 常用于开启MSAA的地表植被的渲染
Blend和BlendOp
1 | finalValue = sourceFactor * sourceValue operation destinationFactor * destinationValue |
- 可以写在Pass中或SubShader中(BlendOp在同一个代码块中还必须有一个Blend命令)
- 启用混合会禁用GPU上的一些优化(主要是隐藏表面去除Early-Z)
三、混合模式的实现方式
Unity附带的Blend枚举
1 | //混合模式 |
Photoshop的Blend实现方式
自己查吧
- 普通的Blend
- Blend SrcAlpha OneMinusSrcAlpha
- //Alpha混合 Alpha Blending
- Blend SrcAlpha OneMinusSrcAlpha
- 变暗Darken
- BlendOp Min
- Blend One One
- min(当前颜色,缓存颜色)*1
- 正片叠底
- Blend Discolors Zero
- 当前颜色*缓存颜色+缓存颜色*0
- 滤色Screen
- Blend OneMinusDstColor One 或Blend One OneMinusSrcColor
- Src*(1-Dst)+Dst*1 = Src+Dst-Src*Dst
- 当前颜色*(1-缓存颜色)+缓存颜色*1 或 当前颜色*1 + 缓存颜色* (1-缓存颜色)
- 变亮Lighten
- BlendOp Max
- Blend One One
- max(当前颜色,缓存颜色)
- 线性减淡LinearDodge
- Blend One One
- 缓存颜色*1+当前颜色*1
- 颜色加深ColorBurn
- 高级Opengl混合
- 此模式目前仅在具有GL_KHR_blend_equation_advanced或GL_NV_blend_equation_advanced扩展支持的Opengl硬件上可用
- 1-(1-Dst)/Src
- 。。。
四、剔除的实现方式
- 法线剔除
- 也称背面消隐,根据法线朝向判断哪个面被剔除掉,可以用来控制是否双面渲染
- Cull + [Off, Front, Back]
- 面裁切
- Clip函数会参数小于某像素点直接在片元阶段丢弃,常用于制作溶解,裁剪等效果
- Clip();//默认会切掉0.5的部分,或者使用if
1 | if(input.posInObjectCoords.y > 0.5) discard; |
总结
- 开启双面渲染相当于绘制了两次
- Clip函数在某些PowerVR的机型上效率低
- 面裁切Clip使用AlphaTest队列
作业
实现常用的混合模式,并设计使用界面