UnityShader 屏幕特效 模糊

  1. 上一篇文章寫了屏幕特效必須的幾個要素,這邊通過一個 腳本繼承與PostEffectsBase .以及通過shader 交互實現屏幕模糊特效。

  2. 下面通過添加在攝像機,引用3的shader。

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class Test : PostEffectsBase {

    public Shader edgeDetectShader;
    private Material edgeDetectMaterial = null;
    public Material material
    {
        get
        {
            edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial);
            return edgeDetectMaterial;
        }
    }

    [Range(0.0f, 1.0f)]
    public float Parameter = 0.0f;

   //類似Update,也是會不斷通過輸入,輸出結果
    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (material != null)
        {
            material.SetFloat("_BlurAmount", Parameter);
            Graphics.Blit(src, dest, material);
        }
        else
        {
            Graphics.Blit(src, dest);
        }
    }
}

3.下面Shader

Shader "Futile/Blur"
{
    Properties
    {
        _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
    _Color("Main Color", Color) = (0.2,0,1,1.5)
        _BlurAmount("Blur Amount", Range(0,02)) = 0.0005
    }

    Category
    {
        Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque"  }
        ZWrite Off
        //Alphatest Greater 0
        Cull Off

    SubShader
    {
        Pass
    {

        CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma profileoption NumTemps=64
        float4 _Color;
    sampler2D _MainTex;
    float _BlurAmount;

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

    float4 _MainTex_ST;

    v2f vert(appdata_base v)
    {
        v2f o;
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        return o;
    }

    half4 frag(v2f i) : COLOR
    {
        half4 texcol = half4(0,0,0,0);
        float remaining = 1.0f;
        float coef = 1.0;
        float fI = 0;
        for (int j = 0; j < 3; j++) {
            fI++;
            coef *= 0.32;
            texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y - fI * _BlurAmount)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x - fI * _BlurAmount, i.uv.y)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x + fI * _BlurAmount, i.uv.y)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y + fI * _BlurAmount)) * coef;

            remaining -= 4 * coef;
        }
        //return texcol;

        texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y)) * remaining;

        return texcol;
    }
        ENDCG



    }
    }
    }
}

4.簡單介紹Category :就是同一個Shader,如果下面有多個Shader的話,都會套用下面這一套

    Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" }
    ZWrite Off
    //Alphatest Greater 0
    Cull Off

5.簡單講一下這個算法,這個通過在片元着色器進行上下左右進行像素微偏移

for (int j = 0; j < 3; j++) {
            fI++;
            coef *= 0.32;
            texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y - fI * _BlurAmount)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x - fI * _BlurAmount, i.uv.y)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x + fI * _BlurAmount, i.uv.y)) * coef;
            texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y + fI * _BlurAmount)) * coef;

            remaining -= 4 * coef;
        }

原圖
原圖
模糊圖,通過調參數Parameter
這裏寫圖片描述
這邊的Remaining爲了 在下面保證迭代後基數爲1。這樣不會影響原本圖像的亮度。比如這邊基數默認設置10。就會銳化圖像這裏寫圖片描述


總結
這邊計算可以在頂點v2f vert(appdata_base v)裏面計算,這樣一位頂點計算量數比片元着色器計算更少。

發佈了76 篇原創文章 · 獲贊 23 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章