PostEffect - Hole


ÁöÁ¤ÇÑ ¿ø ¿µ¿ª ÀÌ¿Ü¿¡´Â È­¸éÀÌ °ËÀº»öÀ¸·Î ·»´õ¸µ Çغ¸ÀÚ.



½ºÅ©¸³Æ® ÀÛ¼º

CustomImageEffect.cs ¼Ò½º
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Camera))]
public abstract class CustomImageEffect : MonoBehaviour
{
    #region Fields

    private Material m_Material;

    #endregion

    #region Properties

    public abstract string ShaderName { get; }
    protected Material Material { get { return m_Material; } }

    #endregion

    #region Messages

    protected virtual void Awake()
    {
        Shader shader = Shader.Find(ShaderName);
        if (shader != null)
        {
            m_Material = new Material(shader);
            m_Material.hideFlags = HideFlags.HideAndDontSave;
        }
    }

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

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

    protected virtual void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (m_Material != null)
        {
            UpdateMaterial();
            Graphics.Blit(source, destination, m_Material);
        }
        else
        {
            Graphics.Blit(source, destination);
        }
    }

    #endregion

    #region Methods

    protected abstract void UpdateMaterial();

    #endregion
}

CustomImageEffect´Â Ãß»ó Ŭ·¡½º·Î ²®µ¥±â¸¸ ¸¸µé¾î ÁØ´Ù. ¼ÎÀÌ´õ°¡ ¹Ù²î´õ¶óµµ ÄÚµå ¼öÁ¤ÀÌ ¾ø´Â Çʼö ÇÔ¼ö¸¸ ±¸ÇöÀ» ÇØ ³õ¾Ò´Ù.
CustomImageEffect´Â¸¦ »ó¼ÓÇϴ Ŭ·¡½º´Â ShaderName, UpdateMaterial µÎ°³ÀÇ ÇÔ¼ö´Â ÇʼöÀûÀ¸·Î ±¸ÇöÇØ¾ß ÇÑ´Ù.
Camera ÄÄÆ÷³ÍÆ®¸¦ Ãß°¡ÇÑ´Ù.

HoleImageEffect.cs ¼Ò½º
using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class HoleImageEffect : CustomImageEffect
{
    #region Fields

    [SerializeField]
    private Vector2 m_Center;

    [SerializeField]
    [Range(100, 2000)]
    private float m_Size;

    [SerializeField]
    [Range(0, 1)]
    private float m_Time;

    #endregion

    #region Properties

    public override string ShaderName
    {
        get { return "Custom/Hole"; }
    }

    #endregion

    #region Methods

    protected override void UpdateMaterial()
    {
        Material.SetVector("_Center", m_Center);
        Material.SetFloat("_Size", m_Size);
        Material.SetFloat("_AnimTime", m_Time);
    }
    #endregion
}

Hole ¼ÎÀÌ´õ·Î À̸§À» ÁöÁ¤ÇÑ´Ù.
HoleImageEffect. Ŭ·¡½ºÀÇ ShaderName ÇÔ¼ö¿¡¼­ ¼ÎÀÌ´õ À̸§À» ÁöÁ¤ÇØÁÖ°í ÀÖ´Ù.
HoleImageEffect. Ŭ·¡½ºÀÇ UpdateMaterial ÇÔ¼ö¿¡¼­ ¼ÎÀÌ´õ ¼Ó¼ºÀ» ¸ÅÇÁ·¹ÀÓ ¾÷µ¥ÀÌÆ® ÇØÁØ´Ù.

½¦ÀÌ´õ ÀÛ¼º

Hole.shader ¼Ò½º
Shader "Custom/Hole" {
    Properties {
        _MainTex ("Source", 2D) = "white" {}
        _Center ("Center", Vector) = (0,0,0,0)
        _Size ("Size", Float) = 1
        _AnimTime ("Animation Time", Range(0,1)) = 0
    }
    SubShader {
        ZTest Always
        Cull Off
        ZWrite Off
        Fog { Mode Off }

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

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

            v2f vert(appdata_img v) {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy);
                return o;
            }

            sampler2D _MainTex;
            float2 _Center;
            float _Size;
            float _AnimTime;

            fixed4 frag(v2f i) : SV_TARGET {
                float d = distance(_Center, i.uv * _ScreenParams.xy);
                float visible = 1.0 - floor(d / _Size + _AnimTime);
                return fixed4(tex2D(_MainTex, i.uv).rgb * visible, 1.0);
            }
            ENDCG
        }
    }
    FallBack Off
}

_Center¿Í ÇöÀç Á¡ÀÇ °Å¸® d¸¦ ±¸ÇÑ´Ù.
_ScreenParams.xy·Î ·»´õŸ°ÙÀÇ width¿Í height¸¦ ±¸ÇÒ¼ö ÀÖ´Ù.
¶ÇÇÑ i.uv * _ScreenParams.xy´Â ÇöÀç Á¡ÀÇ À§Ä¡¸¦ ±¸ÇÒ¼ö ÀÖ´Ù.

float d = distance(_Center, i.uv * _ScreenParams.xy);

floor·Î ¼Ò¼öÁ¡ ÀÌÇϸ¦ ¹ö¸°´Ù.
¸¸¾à¿¡ _Size°¡ 100ÀÌ°í  d°¡ 200, _AnimTimeÀÌ 0À̸é, floor(d / _Size + _AnimTime) °ªÀº 2°¡ ³ª¿Â´Ù.
visible°ªÀº -1ÀÌ´Ù. viible°ªÀÌ À½¼ö°ªÀÌ ³ª¿À¸é Ä®¶ó°ªÀº 0°ú °°´Ù.

float visible = 1.0 - floor(d / _Size + _AnimTime);

_AnimTimeÀº 0~1»çÀ̷θ¸ º¯È­½ÃŲ´Ù.  ¿øÇÏ´Â ¿øÀÇ Å©±â(_Size = 100À϶§)·Î ÀÛ¾ÆÁö¸é _AnimTimeÀ» 0¿¡¼­ 1·Î Á¶Á¤ÇÏ¿© ÃÖÁ¾ÀûÀ¸·Î ¿øÀÌ »ç¶óÁö°Ô ÇÑ´Ù.

visible·Î ¼¾ÅÍ¿Í °¡±î¿ì¸é Ç¥½ÃÇÏ°í _Size¸¦ ¹þ¾î³ª¸é °ËÀº»öÀ¸·Î Ç¥½ÃÇÑ´Ù.

return fixed4(tex2D(_MainTex, i.uv).rgb * visible, 1.0);

½ÇÇàÇϱâ

HoleImageEffect.cs¸¦ MainCamera ÄÄÆ÷³ÍÆ®·Î Ãß°¡ÇÑ´Ù.



Center, Size¸¦ ¼³Á¤ÇÑ´Ù. TimeÀº 0À¸·Î ¼³Á¤ÇÑ´Ù.

CustomImageEffect.cs ¼Ò½º
HoleImageEffect.cs ¼Ò½º
Hole.shader ¼Ò½º

Âü°í)
http://blog.naver.com/PostView.nhn?blogId=dmknight&logNo=220346319656