본문 바로가기
개발/Unity) Shader

Unity Shader) 녹아서 사라지는 효과 (Dissolve)

by 테샤르 2024. 11. 20.

녹아서 사라지는 효과 (Dissolve)

객체가 녹아 사라지는 효과를 표현하는 데 쓰이며, 객체의 텍스처가 점차 사라지는 듯한 느낌을 줄 수 있다.

일반적으로 AlphaClip을 사용하여 픽셀을 잘라내고, Dissolve를 위한 노이즈 텍스처를 함께 사용한다.

반응형
반응형

 

< Material 속성 >


< Shader Code >

Shader"Custom/DissolveShader"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _NoiseTex ("Noise Texture", 2D) = "white" {}
        _DissolveAmount ("Dissolve Amount", Range(0, 1)) = 0.5
        _DissolveColor ("Dissolve Color", Color) = (1, 0.5, 0, 1)
        _Transparency ("Transparency", Range(0, 1)) = 1.0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        Blend
SrcAlpha OneMinusSrcAlpha

        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 pos : SV_POSITION;
};

sampler2D _MainTex;
sampler2D _NoiseTex;
float _DissolveAmount;
float4 _DissolveColor;
float _Transparency;

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

            // SmoothStep 함수 사용: 부드러운 경계를 위해서
float SmoothDissolve(float noise, float dissolveAmount)
{
                // 부드러운 경계 생성: DissolveAmount의 변화에 따라 Noise 값이 부드럽게 변하게 함
    return smoothstep(dissolveAmount - 0.05, dissolveAmount + 0.05, noise);
}

fixed4 frag(v2f i) : SV_Target
{
                // 메인 텍스처 색상
    fixed4 col = tex2D(_MainTex, i.uv);

                // 메인 텍스처의 알파 값
    float mainTexAlpha = col.a;

                // DissolveAmount가 0일 경우, 원본 MainTex만 사용
    if (_DissolveAmount <= 0.0)
    {
                    // DissolveAmount가 0일 때는 Noise나 DissolveColor를 사용하지 않고, 원본 텍스처만 반환
        col.a = col.a * _Transparency;
        return col;
    }

                // 노이즈 텍스처에서 Dissolve 효과를 위한 값 추출
    float noise = tex2D(_NoiseTex, i.uv).r;

                // Dissolve가 완전히 진행되는 상태를 보장하려면, DissolveAmount가 1일 경우 모든 노이즈값을 넘기게 처리
    if (_DissolveAmount >= 1.0)
    {
        noise = 0.0; // DissolveAmount가 1이면 노이즈 값에 관계없이 완전히 Dissolve된 상태로 처리
    }

                // Noise Texture 적용 조건: MainTexture의 알파 값이 0이 아닌 부분에만 Noise 효과 적용
    if (mainTexAlpha > 0.01)
    {
                    // SmoothStep으로 부드러운 Dissolve 효과 계산
        float dissolveFactor = SmoothDissolve(noise, _DissolveAmount);

                    // Dissolve 기준에 따른 투명도 및 색상 설정
        if (dissolveFactor < 1.0)
        {
                        // Dissolve 효과가 발생할 때 경계 색상으로 설정
            col = _DissolveColor;
            col.a = _Transparency * dissolveFactor; // 투명도 부드럽게 설정
        }
        else
        {
                        // Dissolve가 일어나지 않을 때 메인 텍스처를 그대로 보여줌
            col.a = col.a * _Transparency; // 텍스처의 알파 값과 투명도 조정
        }
    }
    else
    {
                    // MainTex가 투명한 부분에서는 Noise가 적용되지 않도록
        col.a = 0; // 완전히 투명
    }

                // 알파 값이 너무 낮으면 픽셀을 렌더링하지 않음
    if (col.a < 0.01)
    {
        discard; // 거의 0에 해당하는 알파는 discard
    }

    return col;
}
            ENDCG
        }
    }
}

 

 

★★★☆☆

 

반응형

댓글