0评论

Unity后期特效shader之photoshop混合模式公式的应用

文章来自https://blog.csdn.net/zgjllf1011/article/details/79244087 2019-01-30 481浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏美术行业精英群167422913

部分颜色混合模式的公式如下:

觉着挺实用的,写个shader来尝试一下看看效果。

因为这里都是混合模式,所以需要两张图片,但是我们对摄像机的内容进行后处理,只有1个图层,所以我就把A和B都使用相同内容来处理。

很明显A和B图层内容相同的话前两个公式变量和变暗肯定是没有效果的,我们从第三个公式来尝试。

首先把公式放到shader里,像这样:
            //正片叠底
            fixed4 Muitiply(fixed4 _color){
                fixed r = pow(_color.r,2);
                fixed g = pow(_color.g,2);
                fixed b = pow(_color.b,2);
                return fixed4(r,g,b,1.0f);
            }

图片公式中的颜色值都是按照0-255来计算的,而我们的shader里颜色值是0-1,所以我们要把公式中的所有颜色值除以255来得到0-1范围的颜色值。经过换算后,代码中的公式就变成了上面的样子。

_color为一个像素点,对像素的rgb值分别进行计算,透明度这里不考虑,直接填1.0即可。

看看效果:

第一张是原图,第二张是photoshop里正片叠底的效果,第三张是我们在unity中看到效果。

可以看到unity中得到的结果与photoshop中还是基本一致的,下面我们再试试其他的公式。

这次我们看一下滤色,相应的shader代码如下:
            //滤色
            fixed4 Screen(fixed4 _color){
                fixed r = 1-(pow((1-_color.r),2));
                fixed g = 1-(pow((1-_color.g),2));
                fixed b = 1-(pow((1-_color.b),2));
                return fixed4(r,g,b,1.0f);
            }

效果图:

效果也基本一致,看来我们的思路是正确的,这样看来上面图片中给出的那些公式我们都可以正常使用。

这里我们只是对一张图片做了处理,我们看一下应用在场景里的效果:

经过处理后场景感觉更明亮一些,除了上面图片中的公式,其实还有一个比较常用的,就是去色,像王者荣耀里面玩家死亡后的效果,只要知道了公式实现起来也是非常简单的,我们只要让rgb各自都取它们的平均值就可以了,像这样:
//去色
            fixed4 DelColor(fixed4 _color){
                fixed c = _color.r + _color.g + _color.b;
                c /= 3;
                return fixed4(c,c,c,1.0f);
            }

效果:

好了,按照惯例上完整代码

shader内容:
Shader "Custom/ColorCompute" {
	Properties {
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		Pass{  
            CGPROGRAM  
            #include "UnityCG.cginc"  
            #pragma vertex vert_img  
            #pragma fragment frag  
            uniform sampler2D _MainTex;  
            //去色
            fixed4 DelColor(fixed4 _color){
                fixed c = _color.r + _color.g + _color.b;
                c /= 3;
                return fixed4(c,c,c,1.0f);
            }
            //曝光
            fixed4 Exposure(fixed4 _color,fixed force){
                fixed r = min(1,max(0,_color.r * pow(2,force)));
                fixed g = min(1,max(0,_color.g * pow(2,force)));
                fixed b = min(1,max(0,_color.b * pow(2,force)));
                return fixed4(r,g,b,1.0f);
            }
            //颜色加深
            fixed4 ColorPlus(fixed4 _color){
                fixed r = 1-(1-_color.r)/_color.r;
                fixed g = 1-(1-_color.g)/_color.g;
                fixed b = 1-(1-_color.b)/_color.b;
                return fixed4(r,g,b,1.0f);
            }
            //颜色减淡
            fixed4 ColorMinus(fixed4 _color){
                fixed r = _color.r + pow(_color.r,2)/(1-_color.r);
                fixed g = _color.g + pow(_color.g,2)/(1-_color.g);
                fixed b = _color.b + pow(_color.b,2)/(1-_color.b);
                return fixed4(r,g,b,1.0f);
            }
            //滤色
            fixed4 Screen(fixed4 _color){
                fixed r = 1-(pow((1-_color.r),2));
                fixed g = 1-(pow((1-_color.g),2));
                fixed b = 1-(pow((1-_color.b),2));
                return fixed4(r,g,b,1.0f);
            }
            //正片叠底
            fixed4 Muitiply(fixed4 _color){
                fixed r = pow(_color.r,2);
                fixed g = pow(_color.g,2);
                fixed b = pow(_color.b,2);
                return fixed4(r,g,b,1.0f);
            }
            //强光
            fixed4 ForceLight(fixed4 _color){
                fixed r = 1-pow((1-_color.r),2) / 0.5f;
                fixed g = 1-pow((1-_color.g),2) / 0.5f;
                fixed b = 1-pow((1-_color.b),2) / 0.5f;
                if(_color.r < 0.5f) r = pow(_color.r,2)/0.5f;
                if(_color.g < 0.5f) g = pow(_color.g,2)/0.5f;
                if(_color.b < 0.5f) b = pow(_color.b,2)/0.5f;
                return fixed4(r,g,b,1.0f);
            }
            float4 frag( v2f_img o ) : COLOR  
            {  
                fixed4 _color = tex2D(_MainTex, o.uv); 
                _color = DelColor(_color);
                return _color;
            }  
            ENDCG  
        }  
	}
	FallBack "Diffuse"
}

摄像机脚本:
[ExecuteInEditMode] 
public class ColorCompute : MonoBehaviour {
	public Material m;
	void OnRenderImage(RenderTexture src, RenderTexture dest)
	{
		Graphics.Blit(src, dest, m);
	}
}