Surface Shader Dissolve

Dissolve Shader´Â ¿ÀºêÁ§Æ®°¡ »ç¶óÁö´Â È¿°ú¸¦ ÁÙ¶§ »ç¿ëÇÑ´Ù.
Dissolve  È¿°ú¸¦ ÁÖ±â À§Çؼ­´Â º°µµÀÇ ÅؽºÃÄ°¡ ÇÊ¿äÇÏ´Ù

¾ËÆÄ Dissolve ¼ÎÀÌ´õ

¼ø°£ÀûÀ¸·Î ¹à¾ÆÁøÈÄ °ÔÀÓ ¿ÀºêÁ§Æ®¸¦ »ç¶óÁö°Ô ÇÑ´Ù.
¾ËÆÄ °ª¿¡ ÀÇÇØ ¿ÀºêÁ§Æ®°¡ »ç¶óÁø´Ù.



_CutOff °ªÀÌ 1¿¡¼­ 0À¸·Î º¯ÇÏ¸é °ÔÀÓ¿ÀºêÁ§Æ®°¡ Á¡Á¡ ¹à¾ÆÁø´Ù.
_CutOff °ªÀÌ 0ÀÌ µÇ¸é _Width °ªÀ» °¨¼Ò ½ÃŲ´Ù.
_Width °ªÀÌ 1¿¡¼­ 0À¸·Î º¯ÇÏ¸é °ÔÀÓ¿ÀºêÁ§Æ®°¡ »ç¶óÁø´Ù.

¼ÎÀÌ´õ ¼Ò½º
//http://qiita.com/kaiware007/items/1d9f37bc8c5892d254ac
Shader "Custom/Dissolve" {

    Properties{
        _MainColor("Main Color", Color) = (1,1,1,1)
        _MainTex("Base (RGB)", 2D) = "white" {}     
        _Mask("Mask To Dissolve", 2D) = "white" {}  
        _CutOff("CutOff Range", Range(0,1)) = 0     
        _Width("Width", Range(0,1)) = 0.001         
        _ColorIntensity("Intensity", Float) = 1     
        _Color("Line Color", Color) = (1,1,1,1)     
        _BumpMap("Normalmap", 2D) = "bump" {}       
    }

    SubShader{

        Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
        LOD 300

        Pass{
            ZWrite On
            ColorMask 0
        }

        CGPROGRAM
        #pragma target 2.0
        #include "UnityCG.cginc"
        #pragma surface surf Lambert alpha

        sampler2D _MainTex;
        sampler2D _BumpMap;
        sampler2D _Mask;
        fixed4 _Color;
        fixed4 _MainColor;
        fixed _CutOff;
        fixed _Width;
        fixed _ColorIntensity;

        struct Input {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf(Input IN, inout SurfaceOutput o) {
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex) * _MainColor;
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));

            fixed a = tex2D(_Mask, IN.uv_MainTex).r;

            fixed b = smoothstep(_CutOff, _CutOff + _Width, a);
            o.Emission = _Color * b * _ColorIntensity;

            fixed b2 = step(a, _CutOff + _Width * 2.0);
            o.Alpha = b2;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

½ºÅ©¸³Æ® ¼Ò½º
using UnityEngine;
using System.Collections;

public class AlphaDissolveTest : MonoBehaviour {

    private Material material = null;
    private int _Width = 0;
    private int _Cutoff = 0;

    void Start () {
        material = GetComponentInChildren<Renderer>().material;
        _Width = Shader.PropertyToID("_Width");
        _Cutoff = Shader.PropertyToID("_CutOff");

        if (material != null) {
            material.SetFloat (_Cutoff, 1f);
            material.SetFloat (_Width, 1f);           
            StartCoroutine ("ProcDissolve");
        }
    }

    IEnumerator ProcDissolve ()
    {
        float waitTime = 1f;
        yield return new WaitForSeconds(waitTime);

        float cutoffTime = 1f;
        for (float n = 0f; n <= cutoffTime; n += Time.deltaTime)
        {
            yield return new WaitForSeconds(0.032f); //30fps
            material.SetFloat(_Cutoff, 1 - n/cutoffTime);
        }

        float widthTime = 1f;
        for (float n = 0f; n <= widthTime; n += Time.deltaTime)
        {
            yield return new WaitForSeconds(0.032f); //30fps
            material.SetFloat(_Width, 1- n/widthTime);
        }
    }
}

clip Dissolve ¼ÎÀÌ´õ

clip ¼ÎÀÌ´õ ¸í·É¾î·Î ÀÇÇØ ¿ÀºêÁ§Æ®¸¦ »ç¶óÁö°Ô ÇÑ´Ù.



¼ÎÀÌ´õ ¼Ò½º
Shader "Custom/BasicDissolve" {
    Properties {
      _MainTex ("Texture (RGB)", 2D) = "white" {}
      _SliceGuide ("Slice Guide (RGB)", 2D) = "white" {}
      _SliceAmount ("Slice Amount", Range(0.0, 1.0)) = 0.5
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      Cull Off
      CGPROGRAM
      #pragma surface surf Lambert
      struct Input {
          float2 uv_MainTex;
          float2 uv_SliceGuide;
          float _SliceAmount;
      };
      sampler2D _MainTex;
      sampler2D _SliceGuide;
      float _SliceAmount;
      void surf (Input IN, inout SurfaceOutput o) {
          clip(tex2D (_SliceGuide, IN.uv_SliceGuide).rgb - _SliceAmount);
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

_SliceAmount °ªÀÌ Ä¿Áö¸é(¸¶À̳ʽº °ªÀÌ µÇ¸é) Çȼ¿ÀÌ Å¬¸®ÇÎ µÈ´Ù.

½ºÅ©¸³Æ® ¼Ò½º
using UnityEngine;
using System.Collections;

public class BasicDissoveTest : MonoBehaviour {

    private Material material = null;
    private int _SliceAmount = 0;

    void Start () {
        material = GetComponentInChildren<Renderer>().material;
        _SliceAmount = Shader.PropertyToID("_SliceAmount");

        if(material != null)
            StartCoroutine ("ProcDissolve");
    }

    IEnumerator ProcDissolve ()
    {
        yield return new WaitForSeconds(2);

        //runTime ½Ã°£µ¿¾È _SliceAmount °ªÀ» º¯È­ ½ÃŲ´Ù.
        float runTime = 3f;
        for (float n = 0f; n <= runTime; n += Time.deltaTime)
        {
            yield return new WaitForSeconds(0.032f); //30fps
            material.SetFloat( _SliceAmount, n/runTime);
        }
    }

}

Edge Clip ¼ÎÀÌ´õ

¿ÀºêÁ§Æ®°¡ »ç¶óÁú¶§ Edge Ç¥½ÃÇÑ´Ù.



¼ÎÀÌ´õ ¼Ò½º
Shader "Custom/EdgeDissolve" {
    Properties {
      _MainTex ("Texture (RGB)", 2D) = "white" {}
      _SliceGuide ("Slice Guide (RGB)", 2D) = "white" {}
      _SliceAmount ("Slice Amount", Range(0.0, 1.0)) = 0.5

       _BurnSize ("Burn Size", Range(0.0, 1.0)) = 0.15
       _BurnRamp ("Burn Ramp (RGB)", 2D) = "white" {}
    }

    SubShader {
      Tags { "RenderType" = "Opaque" }
      Cull Off
      CGPROGRAM
      //if you're not planning on using shadows, remove "addshadow" for better performance
      #pragma surface surf Lambert addshadow
      struct Input {
          float2 uv_MainTex;
          float2 uv_SliceGuide;
          float _SliceAmount;
      };

      sampler2D _MainTex;
      sampler2D _SliceGuide;
      float _SliceAmount;
      sampler2D _BurnRamp;
      float _BurnSize;
     
      void surf (Input IN, inout SurfaceOutput o) {
              clip(tex2D (_SliceGuide, IN.uv_SliceGuide).rgb - _SliceAmount);
              o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
 
               half test = tex2D (_SliceGuide, IN.uv_MainTex).rgb - _SliceAmount;
               //half test = tex2D (_SliceGuide, IN.uv_SliceGuide).rgb - _SliceAmount;
               if(test < _BurnSize && _SliceAmount > 0 && _SliceAmount < 1){
                  o.Emission = tex2D(_BurnRamp, float2(test *(1/_BurnSize), 0));
                  o.Albedo *= o.Emission;
              }
      }
      ENDCG
    }
    Fallback "Diffuse"
  }

test °ªÀÌ _BurnSize º¸´Ù ÀÛÀ¸¸é Edge¸¦ Ç¥½ÃÇÑ´Ù.
test °ªÀÌ _Brunsize º¸´Ù ÀÛÀ¸¸é Edge·Î Ãâ·ÂµÇ°í ¸¶À̳ʽº °ªÀ̸é Çȼ¿ÀÌ Ãâ·ÂÀÌ ¾ÈµÈ´Ù.



Edge¸¦ Ç¥½ÃÇϱâ À§ÇÑ ÅؽºÃÄÀÌ´Ù.



½ºÅ©¸³Æ®´Â Clip Disssolve  ¼ÎÀÌ´õ¿Í °°´Ù.

À¯´ÏƼ ÇÁ·ÎÁ§Æ® ÆÄÀÏ : dissole_test.zip

Âü°í)

http://www.codeavarice.com/dev-blog/tutorial-burning-edges-dissolve-shader-in-unity
http://qiita.com/kaiware007/items/1d9f37bc8c5892d254ac

¼ÎÀÌ´õ ¸í·É¾î clip

clip ¸í·É¾î´Â hlsl¿¡¼­µµ Áö¿øµÇ´Â ¸í·É¾îÀÌ´Ù. »ç¿ë¹ýÀº ´ÙÀ½°ú °°´Ù.

clip(x)

x °ªÀÌ 0º¸´Ù ÀûÀ¸¸é Çȼ¿À» ±×¸®Áö ¾Ê´Â´Ù.

»ç¿ë¹ý

clip( Input.Color.A < 0.1f ? -1:1 )

Fixed function(°íÁ¤ ÇÔ¼ö)ÀÇ AlphaTest ¶Ç´Â ÇÁ·Î±×·¡¸Óºí¿¡ ÇØ´çÇÏ ¿ä¼ÒÀÎ clip()Àº ¸ð¹ÙÀÏ¿¡¼­ ´Ù¸¥ ÆÛÆ÷¸Õ½º°¡ ³ª¿Â´Ù.
iOS ¹× ÀϺΠAndroid ÀåÄ¡ÀÇ PowerVR GPU¿¡¼­ ¾ËÆÄ Å×½ºÆ®´Â °í°¡ÀÌ´Ù.

¼ÎÀÌ´õ ¸í·É¾î smoothstep

0~1¹üÀ§¿¡¼­ ºÎµå·¯¿î Ç㸶ÀÌÆ® º¸°£ °ªÀ» ¹ÝȯÇÑ´Ù.

¼ÎÀÌ´õ ¸í·É¾î step(y, x)

(x >= y) ? 1 : 0 °ªÀ» ¹ÝȯÇÑ´Ù.