TOOLS GAMES DEVLOG DOCS ABOUT CONTACT
HOME > DOCS > Shader / URP > 노이즈 텍스처와 스텝 함수 기반 URP 디졸브(Dissolve) 번 엣지 셰이더
Shader / URP Intermediate Unity 2021.3+ / Unity 6 (URP)

노이즈 텍스처와 스텝 함수 기반 URP 디졸브(Dissolve) 번 엣지 셰이더

Simplex/Perlin 노이즈와 step/smoothstep 함수를 결합해 오브젝트가 타들어가며 사라지는 가장자리 발광(Emissive Burn Edge) 셰이더 효과.

#Shader #URP #HLSL #Dissolve #VFX
핵심 개념디졸브의 기본 원리는 노이즈 텍스처의 그레이스케일 값과 _Cutoff(0~1) 파라미터를 비교해 특정 임계치 이하의 픽셀을 clip()으로 버리는 것입니다. 여기에 컷오프 경계선 바로 직전 구간을 잡아 발광 색상(HDR Edge Color)을 덧입히면 불에 타들어가는 느낌을 완성할 수 있습니다.

1. URP HLSL 디졸브 셰이더 코드

DissolveBurn.shader
Shader "Custom/URP/DissolveBurn"
{
    Properties
    {
        _BaseMap ("Texture", 2D) = "white" {}
        _BaseColor ("Color", Color) = (1,1,1,1)
        _NoiseMap ("Noise Map", 2D) = "white" {}
        _Cutoff ("Dissolve Amount", Range(0, 1)) = 0.0
        _EdgeWidth ("Edge Width", Range(0, 0.2)) = 0.05
        [HDR] _EdgeColor ("Edge Burn Color", Color) = (2, 0.5, 0, 1)
    }
    SubShader
    {
        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode" = "UniversalForward" }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            TEXTURE2D(_BaseMap);   SAMPLER(sampler_BaseMap);
            TEXTURE2D(_NoiseMap);  SAMPLER(sampler_NoiseMap);

            CBUFFER_START(UnityPerMaterial)
                float4 _BaseMap_ST;
                float4 _NoiseMap_ST;
                half4 _BaseColor;
                half4 _EdgeColor;
                float _Cutoff;
                float _EdgeWidth;
            CBUFFER_END

            Varyings vert(Attributes input)
            {
                Varyings output;
                output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
                output.uv = TRANSFORM_TEX(input.uv, _BaseMap);
                return output;
            }

            half4 frag(Varyings input) : SV_Target
            {
                half noise = SAMPLE_TEXTURE2D(_NoiseMap, sampler_NoiseMap, input.uv).r;
                clip(noise - _Cutoff); // 컷오프보다 작으면 픽셀 폐기

                half4 baseTex = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;
                // 가장자리 영역 마스킹 (noise가 _Cutoff + _EdgeWidth 미만일 때)
                float edgeFactor = 1.0 - saturate((noise - _Cutoff) / max(_EdgeWidth, 0.0001));
                half3 finalColor = lerp(baseTex.rgb, _EdgeColor.rgb, edgeFactor);

                return half4(finalColor, baseTex.a);
            }
            ENDHLSL
        }
    }
}

참고자료 & 관련 링크