Unity Shaders——屏幕灰度效果(Screen Effect)

        以前項目中在後期處理中經常用到屏幕特效,爲了讓畫面更加夢幻或者卡通的效果,就跟添加濾鏡一樣,那時候只是直接從網上找的或者別人的拿過來用了,並沒有深入的理解過,今天看《Unity Shaders and Effects CookBook》剛好涉及到了,就記錄下來,供以後學習參考。


首先說下原理,屏幕特效的腳本必須掛在MainCamera上,渲染相機的效果,實際上你在scene中看到的東西沒有變化。

如圖所示:


然後就是屏幕特效需要shader和腳本共同作用,首先我們看下這個灰度屏幕特效所需要的Shader腳本:

Shader "MyShaders/ZTestImageEffect" 
{
	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white" {}
		_LuminosityAmount("Brightness Amount", Range(0.0, 1)) = 1.0
	}

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

			uniform sampler2D _MainTex;
			fixed _LuminosityAmount;

			fixed4 frag(v2f_img i) : COLOR
			{
				//Get the colors from the RenderTexture and the uv's
				//from the v2f_img struct
				fixed4 renderTex = tex2D(_MainTex, i.uv);

				//Apply the Luminosity values to our render texture
				float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
				fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);


				return finalColor;
			}

		ENDCG
		}
	}
	FallBack off
}


然後C#腳本:

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class TestImageEffectGrey : MonoBehaviour
{
    #region Variables
    public Shader curShader;
    public float grayScaleAmount = 1.0f;
    private Material curMaterial;
    #endregion

    #region Properties
    Material material
    {
        get
        {
            if (curMaterial == null)
            {
                curMaterial = new Material(curShader);
                curMaterial.hideFlags = HideFlags.HideAndDontSave;
            }
            return curMaterial;
        }
    }
    #endregion

    void Start()
    {
        if (!SystemInfo.supportsImageEffects)
        {
            enabled = false;
            return;
        }

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

    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (curShader != null)
        {
            material.SetFloat("_LuminosityAmount", grayScaleAmount);

            Graphics.Blit(sourceTexture, destTexture, material);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }
    }

    void Update()
    {
        grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
    }

    void OnDisable()
    {
        if (curMaterial)
        {
            DestroyImmediate(curMaterial);
        }
    }
}

[ExecuteInEditMode]表示在編輯器模式下運行,實時變化灰度參數。這個就是腳本里設置Shader中的參數值,Shader中根據這個參數值把灰度效果渲染到RenderTexture上。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章