11.Post Processing

11. Post Processing

52. Preparing for post processing

什么是后处理技术?如果你熟知PS,那么你应该知道什么是滤镜,后处理技术就像滤镜一样。

打开69scene,想想为什么这里会黑屏呢?因为_MainTex没有设置到rendered image上,也就是说纹理在摄像机中渲染了,但是没用到屏幕上。怎么办呢?注意Scene 69 Render Image脚本,这里有一个Cur Shader(Cursor shader),我们将原图传到这个shader里处理,然后渲染到屏幕上。

方便的是,在unity中我们就有这样一个函数OnRenderImage来做这件事。

52.1 Unity 中的OnRenderImage 函数

  • 如果我们不将sourceTexture拷贝到destTexture那么我们就会得到黑色。
  • 默认的destTesture就是黑色
  • 如果摄像机下的脚本中没有这个函数,那么就会正常渲染,但是如果有OnRenderImage这个函数,那么我们必须传入sourceTexture 到 destTexture。
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{

}
52.1.1 Graphics.Blit函数

拷贝功能,将第一个参数拷贝到第二个参数.

Graphics.Blit(sourceTexture,destTexture);这里图像就会显示了。

但是我们现在的需求是将source传递到shader。

这里我们首先在脚本中动态创建了一个应用curShader的材质:

Material ScreenMat
    {
        get
        {
            if (screenMat == null)
            {
                screenMat = new Material(curShader);
                screenMat.hideFlags = HideFlags.HideAndDontSave;
            }

            return screenMat;
        }
    }

然后修改OnRenderImage,如果有处理shader就进入处理shader,没有就直接输出。

void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (curShader != null)//如果curShader不为空,就用这个shader去处理源图
        {
            ScreenMat.SetColor("_TintColor",tintColor);
            Graphics.Blit(sourceTexture,destTexture,ScreenMat);//这里第三个参数是材质
        }
        else
        {
            Graphics.Blit(sourceTexture,destTexture);
        }     
    }

当然在脚本开始还要看这个处理shader是否被支持。

void Start()
    {
        if (!curShader && !curShader.isSupported)
        {
            enabled = false;
        }
    }

52.2 简单的后处理Shader

Shader "NiksShaders/Shader69Unlit"
{
    Properties
    {
        _MainTex("Base (RGB)", 2D) = "white" {}
        _TintColor("Tint Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            fixed4 _TintColor;
            
            fixed4 frag (v2f_img i) : SV_Target
            {
                fixed3 renderTex = tex2D(_MainTex, i.uv).rgb;
                fixed3 grayScale = (renderTex.r + renderTex.g + renderTex.b)/3;//取RGB的平均值可以让最后显示的颜色偏向某一个(这个和显示的颜色一致)
                fixed3 curCol = grayScale * _TintColor;
                
                return fixed4(curCol, 1);
            }
            ENDCG
        }
    }
    FallBack off
}

52.3 Summary

  • When using post processing the developer needs to copy the rendered image to a sampler2D.
  • One way is to use the OnRenderlmage method.
  • Use the Graphics.Blit method
  • When passed a material as the 3rd parameter it will copy destTexture as the sampler2D MainTex

53. Night goggles effect

护目镜效果,基本上和上一节同理。

Shader "NiksShaders/Shader70aUnlit"
{
    Properties
    {
        _MainTex("Base (RGB)", 2D) = "white" {}
        _Tint("Tint", Range(0, 1)) = 1.0
        _ScanLines("Scanlines", Range(50, 150)) = 100
        _ScanlineColor("Scanline Color", Color) = (0,0,0,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #pragma fragmentoption ARB_precision_hint_fastest

            #include "UnityCG.cginc"

            sampler2D _MainTex;
            fixed _Tint;
            float _Scanlines;
            fixed4 _ScanlineColor;

            fixed4 frag (v2f_img i) : SV_Target
            {
                fixed3 renderTex = tex2D(_MainTex, i.uv).rgb;//取样
                fixed3 tintColor = fixed3( 0.6, 1, 0.6 );
                fixed3 grayScale = (renderTex.r + renderTex.g + renderTex.b) / 3;
                fixed3 tinted = grayScale * tintColor;//上滤镜
                fixed3 finalColor = lerp(renderTex, tinted, _Tint);//选择滤镜还是主纹理
                
                float scanline = smoothstep(0.2, 0.4, frac(i.uv.y * _Scanlines));//将uv.y翻倍成_Scanlines取小数,以小于0.2是0是黑色,大于0.4是1,中间是过渡
                finalColor = lerp(_ScanlineColor.rgb, finalColor, scanline);//0的部分返回线的颜色,1的部分返回纹理颜色
            
                
                return fixed4(finalColor, 1);

            }
            ENDCG
        }
    }
    FallBack off
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值