Project_WL/Assets/WL/Look/Character/Shaders/WLWeaponGlow.shader

73 lines
3.5 KiB
Plaintext

// WLWeaponGlow.shader — 무기 위에 덧그리는 흰 빛(가산 · 테두리 강조) (#912 · 2026-10-17)
// PD 「모으기 이펙트가 재생될 때 망치가 점차 하얗게 빛날 수 있게」 — 해머 각성(WLHammerQuake)이 망치 메시를 복제한 자식에 이 재질을 씌우고
// 세기 _Glow(0~1) · 색 _GlowColor(HDR · 1 넘으면 블룸)를 렌더러별 프로퍼티 블록으로 쓴다. 몸통 덮기 _Fill · 테두리 _RimPower · 겉껍질 _Inflate(월드 m) = 재질 값.
// 모바일: 조명 · 텍스처 없는 단일 패스 · 그림자 없음.
// #958 PD 「대검 주력 모으기에 그라데이션 색(노란색 계열)」 — _GlowColor(손잡이 쪽) → _GlowColor2(칼끝 쪽) 오브젝트 공간 축 그라데이션
// (_GradAxis xyz = 축 · w = 손잡이 끝 투영 · _GradLen = 1/길이 · 0 = 단색 = 기존과 같음 · 렌더러별 프로퍼티 블록 = WLWeaponGlowFx.Set 5인자)
Shader "WL/WeaponGlow"
{
Properties
{
[HDR] _GlowColor ("Glow Color (HDR)", Color) = (2, 2, 2, 1)
[HDR] _GlowColor2 ("Glow Color 2 (HDR · 칼끝 쪽)", Color) = (2, 2, 2, 1)
_GradAxis ("Gradient Axis (오브젝트 xyz · w = 시작 투영)", Vector) = (0, 0, 1, 0)
_GradLen ("Gradient 1/Length (0 = 단색)", Float) = 0
_Glow ("Glow (0~1 · 프로퍼티 블록)", Range(0, 1)) = 0
_Fill ("Body Fill (몸통 덮기)", Range(0, 1)) = 0.6
_RimPower ("Rim Power (테두리)", Range(0.5, 8)) = 2
_Inflate ("Shell Inflate (월드 m)", Range(0, 0.05)) = 0.004
}
SubShader
{
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Transparent" "Queue" = "Transparent" "IgnoreProjector" = "True" }
Pass
{
Name "WLWeaponGlow"
Blend SrcAlpha One
ZWrite Off
ZTest LEqual
Cull Back
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
half4 _GlowColor;
half4 _GlowColor2;
float4 _GradAxis;
float _GradLen;
half _Glow;
half _Fill;
half _RimPower;
float _Inflate;
CBUFFER_END
struct Attributes { float4 positionOS : POSITION; float3 normalOS : NORMAL; };
struct Varyings { float4 positionCS : SV_POSITION; float3 normalWS : TEXCOORD0; float3 viewWS : TEXCOORD1; float grad : TEXCOORD2; };
Varyings vert(Attributes v)
{
Varyings o;
float3 n = TransformObjectToWorldNormal(v.normalOS);
float3 p = TransformObjectToWorld(v.positionOS.xyz) + n * _Inflate;
o.positionCS = TransformWorldToHClip(p);
o.normalWS = n;
o.viewWS = GetWorldSpaceViewDir(p);
o.grad = saturate((dot(v.positionOS.xyz, _GradAxis.xyz) - _GradAxis.w) * _GradLen); // #958 손잡이 0 → 칼끝 1 (_GradLen 0 = 0 = 단색)
return o;
}
half4 frag(Varyings i) : SV_Target
{
half ndv = saturate(dot(normalize(i.normalWS), normalize(i.viewWS)));
half rim = pow(1.0h - ndv, _RimPower);
half a = saturate(_Glow) * saturate(_Fill + rim);
return half4(lerp(_GlowColor.rgb, _GlowColor2.rgb, (half)i.grad), a);
}
ENDHLSL
}
}
}