Unity实现后处理效果

后处理

后处理可以理解为滤镜,是对渲染得到的帧缓冲再做一次处理的过程。

创建Shader

在Unity的资源管理器中右键Create->Shader->Image Effect Shader,创建出一个Shader,这个默认的Shader就是一个实现反相效果的Shader。

Shader "Hidden/NewImageEffectShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }

    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

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

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;
            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // just invert the colors
                col.rgb = 1 - col.rgb;
                return col;
            }
            ENDCG
        }
    }
}

使用Shader的C#代码

在文件管理器中右键Create->C# Script,创建一个C# 脚本,把这个脚本命名为PostProcessing

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 后处理
public class PostProcessing : MonoBehaviour
{
    public Shader shader;
    public bool effectEnable = true;
    private Material material;
    private void Awake()
    {
        material = new Material(shader);
    }

    // Start is called before the first frame update
    void Start()
    {
    }

    void OnRenderImage(RenderTexture source, RenderTexture target)
    {
        if (material && effectEnable)
        {
            Graphics.Blit(source, target, material);
        }
        else
        {
            Graphics.Blit(source, target);
        }
    }
    // Update is called once per frame
    void Update()
    {

    }
}

OnRenderImage是Unity在渲染完成会调用的函数,可以在这个函数中进行后处理,source是渲染后得到的纹理,用Graphics.Blit可以在输出前加入一个材质对原图像进行一个后处理。在Unity中,材质Material和Shader一般是一起存在的,如果要使用某个Shader,那么一般要有一个材质作为载体。将这个脚本挂载到MainCamera上,把之前创建好的Shader拖到shader变量上

测试

运行场景时通过切换PostProcessing脚本上的effectEnable来切换效果
原场景:

后处理过的场景:

posted @ 2020-06-11 15:15  凌夜霜  阅读(3520)  评论(0编辑  收藏  举报