103 lines
4.1 KiB
Plaintext
103 lines
4.1 KiB
Plaintext
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLRimAdd.shader — 캐릭터 윤곽의 밝은 테(림라이트) (WL-814t · #814 · 요소 Ⓓ)
|
|
//
|
|
// ■ 왜 별도 패스인가
|
|
// 원본 `Toon.shadergraph` 에는 Fresnel 입력이 없고, 원본(`Assets/3DPixelArtEnvironment/**`)
|
|
// 수정은 금지다. 그래프 **복사본**을 만들어 Fresnel 을 더하는 대신, 같은 메시를 한 번 더
|
|
// 가산(Blend One One)으로 덧그리는 패스를 택했다 — 머티리얼/그래프를 하나도 안 건드리고
|
|
// 런타임에 켜고 끌 수 있고, 세기를 슬라이더 하나로 준다.
|
|
//
|
|
// ■ 무엇을 하나
|
|
// rim = pow(1 - saturate(dot(N, V)), _RimPower) — 시선과 수직인 가장자리에서 1.
|
|
// `_RimUpBias` 로 위쪽(레퍼런스의 무대조명) 윤곽만 더 밝게 줄 수 있다.
|
|
//
|
|
// ■ 주의
|
|
// Transparent 큐 · ZWrite Off · ZTest LEqual + Offset 으로 원본 면 위에 얹는다.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
Shader "WL/RimAdd"
|
|
{
|
|
Properties
|
|
{
|
|
[HDR] _RimColor ("Rim Color", Color) = (1, 0.85, 0.55, 1)
|
|
_RimPower ("Rim Power", Float) = 3.0
|
|
_RimStrength ("Rim Strength", Float) = 1.0
|
|
_RimUpBias ("Rim Up Bias (0=균일, 1=위쪽만)", Range(0, 1)) = 0.35
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Transparent" "Queue" = "Transparent" }
|
|
|
|
Pass
|
|
{
|
|
Name "WLRimAdd"
|
|
Tags { "LightMode" = "SRPDefaultUnlit" }
|
|
|
|
Cull Back
|
|
ZWrite Off
|
|
ZTest LEqual
|
|
Offset -1, -1
|
|
Blend One One
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#pragma multi_compile_instancing
|
|
#pragma target 3.0
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
|
|
|
CBUFFER_START(UnityPerMaterial)
|
|
float4 _RimColor;
|
|
float _RimPower;
|
|
float _RimStrength;
|
|
float _RimUpBias;
|
|
CBUFFER_END
|
|
|
|
struct Attributes
|
|
{
|
|
float4 positionOS : POSITION;
|
|
float3 normalOS : NORMAL;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float3 normalWS : TEXCOORD0;
|
|
float3 positionWS : TEXCOORD1;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
Varyings vert(Attributes input)
|
|
{
|
|
Varyings o = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, o);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
|
o.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
o.positionCS = TransformWorldToHClip(o.positionWS);
|
|
o.normalWS = TransformObjectToWorldNormal(input.normalOS);
|
|
return o;
|
|
}
|
|
|
|
half4 frag(Varyings input) : SV_Target
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
float3 n = normalize(input.normalWS);
|
|
float3 v = normalize(GetWorldSpaceViewDir(input.positionWS));
|
|
float rim = 1.0 - saturate(dot(n, v));
|
|
rim = pow(saturate(rim), max(_RimPower, 0.01));
|
|
// 위쪽 윤곽 가중(무대 조명 느낌)
|
|
float up = saturate(n.y * 0.5 + 0.5);
|
|
rim *= lerp(1.0, up, saturate(_RimUpBias));
|
|
return half4(_RimColor.rgb * (rim * _RimStrength), 0.0);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
}
|
|
|
|
Fallback Off
|
|
}
|