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 디졸브 셰이더 코드
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
}
}
}