Project_WL/Assets/WL/Look/Character/WLCharacterBacklightSetting...

112 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ─────────────────────────────────────────────────────────────────────────────
// WLCharacterBacklightSettings.cs — 캐릭터 역광(림·라이트 랩·피부 투과) + 번짐(Bloom) 값 (C45 · 코드 상수 금지)
//
// 2026-09-17 PD 「캐릭터가 조금 더 돋보이게」 + 팁(차가운 역광 · SSS · Bloom).
// enabled_ = 0 → 아무 것도 덧붙이지 않는다(캐릭터 재질 배열 원래대로) · bloomEnabled = 0 → 카메라/볼륨 0 변경.
// 🔴 Debug.LogError / Debug.LogException 을 쓰지 않는다(813z 규칙).
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
namespace WL.Look.Character
{
public class WLCharacterBacklightSettings : ScriptableObject
{
[Header("스위치")]
[Tooltip("0 = 역광 패스 전체 off(재질 배열 원래대로).")]
public int enabled_ = 1;
[Tooltip("1 이면 적용 내역을 로그로 남긴다.")]
public int verboseLog = 0;
[Header("대상")]
[Tooltip("이 셰이더 이름의 재질을 가진 렌더러에만 덧붙인다(얼굴 Unlit/Transparent · 파티클 제외). 비우면 파티클 외 전부.")]
public string shaderNameFilter = "Shader Graphs/Toon";
[Tooltip("재질 이름에 이 글자가 들어 있으면 피부로 보고 피부 투과(SSS)를 켠 재질을 물린다.")]
public string[] skinMaterialHints = { "Skin" };
[Header("① 역광 림 — 메인 조명(따뜻함)과 반대인 차가운 색")]
[ColorUsage(false, true)] public Color rimColor = new Color(0.28f, 0.62f, 1f, 1f);
[Tooltip("림 밝기 배수(1 초과 = HDR · Bloom 이 집어낸다).")]
public float rimStrength = 1.45f;
[Header("①-b 화면 공간 깊이 림(기본) — 실루엣 바깥쪽에만 · 화면 픽셀 굵기 일정")]
[Tooltip("1 = 깊이 림 사용(URP 에셋의 Depth Texture 가 꺼져 있으면 자동으로 프레넬만 쓴다). 실측: 프레넬만 쓰면 머리카락 안쪽 가닥마다 줄이 생긴다.")]
public int rimUseDepth = 1;
[Tooltip("띠 굵기 = 화면 짧은 변 × 이 값(0.0045 → 1080 기준 ≈ 5 px).")]
[Range(0f, 0.02f)] public float rimWidth = 0.0045f;
[Tooltip("역광 쪽 이웃 픽셀이 이만큼(m) 더 멀면 실루엣으로 본다(작으면 머리카락 가닥에도 생긴다).")]
public float rimDepthThreshold = 0.12f;
[Tooltip("깊이 림에 섞는 프레넬 림의 양 — 가까울 때(두께감).")]
[Range(0f, 1f)] public float rimFresnelNear = 0.6f;
[Tooltip("깊이 림에 섞는 프레넬 림의 양 — 멀 때(0 = 깊이 림만 · 가닥 줄 없음).")]
[Range(0f, 1f)] public float rimFresnelFar = 0f;
[Header("①-a 프레넬 림(보조 · 깊이 텍스처가 없을 때는 이것만)")]
[Tooltip("가까울 때(rimNearDistance 이하)의 띠 굵기 — 클수록 가는 띠(0.4 = 굵게 · 0.7 = 가늘게).")]
[Range(0f, 1f)] public float rimThreshold = 0.52f;
[Tooltip("멀 때(rimFarDistance 이상)의 띠 굵기 — 작게 줘서 굵게. 게임 카메라(섬 12 m · 던전 11 m)에서 캐릭터가 ~70 px 라 가는 띠는 1 px 로 사라진다(실측).")]
[Range(0f, 1f)] public float rimThresholdFar = 0.36f;
[Tooltip("이 거리(m) 이하 = 가까움.")]
public float rimNearDistance = 3f;
[Tooltip("이 거리(m) 이상 = 멂.")]
public float rimFarDistance = 12f;
[Tooltip("띠 가장자리 부드러움(작을수록 셀 느낌).")]
[Range(0.001f, 0.5f)] public float rimSoftness = 0.05f;
[Tooltip("0 = 둘레 전부 · 1 = 가상 역광 쪽 윤곽만.")]
[Range(0f, 1f)] public float rimDirectional = 0.85f;
[Tooltip("림이 바탕을 덮는 정도(1 = 림 색 그대로 · 0 = 순수 가산). 실측: 순수 가산은 노란 머리·살색 위에서 흰 테가 돼 차가운 색이 안 보였다.")]
[Range(0f, 1f)] public float rimOpacity = 0.85f;
[Header("가상 역광 위치(카메라 기준) — 캐릭터 뒤 + 위 + 옆")]
[Tooltip("위쪽 성분(클수록 머리·어깨 윗선에 맺힌다).")]
public float backlightUp = 0.7f;
[Tooltip("옆 성분(+ = 화면 오른쪽 · − = 왼쪽). 메인 조명이 왼쪽 앞에서 오므로 오른쪽 뒤가 자연스럽다.")]
public float backlightSide = 0.8f;
[Header("② 라이트 랩 — 빛이 안쪽으로 스며드는 옅은 번짐")]
[ColorUsage(false, true)] public Color wrapColor = new Color(0.75f, 0.85f, 1f, 1f);
public float wrapStrength = 0.12f;
public float wrapPower = 1.6f;
[Header("③ 피부 투과(SSS 흉내) — 피부 재질에만")]
[ColorUsage(false, true)] public Color sssColor = new Color(1f, 0.32f, 0.22f, 1f);
public float sssStrength = 1.5f;
public float sssPower = 1.7f;
[Header("④ 번짐(Bloom) — 역광이 화사하게 번지게(전체 화면 패스 · 모바일 비용 있음)")]
[Tooltip("0 = 카메라·볼륨을 건드리지 않는다.")]
public int bloomEnabled = 1;
[Tooltip("이 씬이 떠 있을 때만 켠다(전투 맵의 기존 후처리는 그대로).")]
public string[] bloomScenes = { "Level01" };
[Tooltip("이 밝기 이상만 번진다(HDR 1 초과 = 림·반짝임만).")]
public float bloomThreshold = 1.05f;
public float bloomIntensity = 0.55f;
[Range(0f, 1f)] public float bloomScatter = 0.55f;
[Tooltip("1 = 카메라 HDR 을 켠다(림만 골라 번지게 · 끄면 흰 거품·밝은 모래도 같이 번진다).")]
public int bloomHdr = 1;
[Tooltip("1 = 1/4 해상도에서 시작(모바일 권장).")]
public int bloomQuarter = 1;
[Tooltip("블러 단계 수(작을수록 쌈).")]
public int bloomMaxIterations = 4;
// ───────────────────────────────────────── 싱글턴(Resources)
public const string ResourcePath = "WL/WLCharacterBacklightSettings";
static WLCharacterBacklightSettings s_inst;
static bool s_tried;
public static WLCharacterBacklightSettings Instance
{
get
{
if (s_inst == null && !s_tried)
{
s_tried = true;
s_inst = Resources.Load<WLCharacterBacklightSettings>(ResourcePath);
}
return s_inst;
}
}
public static void Invalidate() { s_inst = null; s_tried = false; }
}
}