Shader "LeEthER/GradientFlowEmission" { Properties { [MainTexture] _BaseMap("Base Map", 2D) = "white" {} [MainColor] _BaseColor("Base Color", Color) = (1,1,1,1) _EmissionMask("Emission Mask", 2D) = "white" {} [HDR] _EmissionColorA("Emission Color A", Color) = (0, 0.8, 1, 1) [HDR] _EmissionColorB("Emission Color B", Color) = (1, 0.2, 0.8, 1) _EmissionIntensity("Emission Intensity", Range(0, 10)) = 1.5 _FlowDirection("Flow Direction", Vector) = (1, 0, 0, 0) _FlowSpeed("Flow Speed", Range(-5, 5)) = 1 _FlowScale("Flow Scale", Range(0.1, 20)) = 3 _FlowSharpness("Flow Sharpness", Range(0.1, 10)) = 2 _FlowContrast("Flow Contrast", Range(0.1, 5)) = 1 _EmissionPulse("Emission Pulse", Range(0, 1)) = 0.25 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" "Queue"="Geometry" } Pass { Name "ForwardUnlit" 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 positionHCS : SV_POSITION; float2 uv : TEXCOORD0; }; TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap); TEXTURE2D(_EmissionMask); SAMPLER(sampler_EmissionMask); CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _EmissionMask_ST; float4 _BaseColor; float4 _EmissionColorA; float4 _EmissionColorB; float4 _FlowDirection; float _EmissionIntensity; float _FlowSpeed; float _FlowScale; float _FlowSharpness; float _FlowContrast; float _EmissionPulse; CBUFFER_END Varyings vert(Attributes IN) { Varyings OUT; OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz); OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap); return OUT; } half4 frag(Varyings IN) : SV_Target { float2 uv = IN.uv; half4 baseCol = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, uv) * _BaseColor; half emissionMask = SAMPLE_TEXTURE2D(_EmissionMask, sampler_EmissionMask, uv).r; float2 dir = _FlowDirection.xy; dir = length(dir) > 0.0001 ? normalize(dir) : float2(1, 0); // 방향을 따라 흐르는 값 float flowCoord = dot(uv, dir) * _FlowScale + _Time.y * _FlowSpeed; // 0~1 반복되는 부드러운 웨이브 float wave = sin(flowCoord * 6.2831853) * 0.5 + 0.5; // 명암 대비 조절 wave = pow(saturate(wave), _FlowSharpness); wave = saturate((wave - 0.5) * _FlowContrast + 0.5); // 추가로 밝기 맥동 float pulse = lerp(1.0, wave, _EmissionPulse); // A -> B 그라데이션 half3 emissionGradient = lerp(_EmissionColorA.rgb, _EmissionColorB.rgb, wave); half3 emission = emissionGradient * emissionMask * _EmissionIntensity * pulse; return half4(baseCol.rgb + emission, baseCol.a); } ENDHLSL } } }