120 lines
6.8 KiB
C#
120 lines
6.8 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
||
// WLPaletteSettings.cs — 팔레트 양자화 + Bayer 디더 값의 SOT (C45) · WL-814j · #814
|
||
//
|
||
// 값의 SOT = Assets/WL/Look/Palette/Resources/WL/WLPaletteSettings.asset
|
||
// → Resources.Load<WLPaletteSettings>("WL/WLPaletteSettings") 1회 로드 후 캐시(기존 WL 설정 SO 관례).
|
||
//
|
||
// 🔴 C8 — enabled = 0 (또는 RuntimeDisabled = true) 이면 렌더러 피처가 꺼지고 패스도 0건이다 = 원본 100 %.
|
||
// 🔴 코드 상수 0 — 레벨·디더 강도·모드 범위까지 전부 이 에셋에서 바꾼다.
|
||
// ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
using UnityEngine;
|
||
|
||
namespace WL.Look.Palette
|
||
{
|
||
/// <summary>팔레트 양자화 방식.</summary>
|
||
public enum WLPaletteMode
|
||
{
|
||
/// <summary>R/G/B 각 levels 단계로 반올림(levels^3 색 상한). 기본.</summary>
|
||
ChannelLevels = 0,
|
||
/// <summary>N×1 팔레트 텍스처에서 최근접 색을 찾는다(배선만 · 텍스처 미설정이면 ChannelLevels 로 되돌아간다).</summary>
|
||
PaletteTexture = 1,
|
||
}
|
||
|
||
/// <summary>팔레트 양자화 + 디더 후처리 값. 전부 여기서만 바꾼다.</summary>
|
||
[CreateAssetMenu(fileName = "WLPaletteSettings", menuName = "WL/Palette Dither Settings", order = 814)]
|
||
public sealed class WLPaletteSettings : ScriptableObject
|
||
{
|
||
public const string ResourcesPath = "WL/WLPaletteSettings";
|
||
|
||
static WLPaletteSettings s_cached;
|
||
static bool s_lookupDone;
|
||
|
||
/// <summary>Resources 에서 1회 로드 후 캐시. 없으면 null(= 기능 off).</summary>
|
||
public static WLPaletteSettings Instance
|
||
{
|
||
get
|
||
{
|
||
if (!s_lookupDone)
|
||
{
|
||
s_lookupDone = true;
|
||
s_cached = Resources.Load<WLPaletteSettings>(ResourcesPath);
|
||
}
|
||
return s_cached;
|
||
}
|
||
}
|
||
|
||
/// <summary>진단·A/B 전용 런타임 스위치(WLPixelCameraSettings 선례). 에셋을 안 건드리고 이 기능만 끈다.</summary>
|
||
public static bool RuntimeDisabled;
|
||
|
||
/// <summary>이 기능이 살아 있는가(에셋 존재 + enabled + !RuntimeDisabled).</summary>
|
||
public static bool Enabled
|
||
{
|
||
get { var i = Instance; return i != null && i.enabled_ && !RuntimeDisabled; }
|
||
}
|
||
|
||
/// <summary>테스트용: 캐시를 비워 다음 접근 때 다시 Resources.Load 한다.</summary>
|
||
public static void ClearCache() { s_cached = null; s_lookupDone = false; }
|
||
|
||
// ───────────────────────────────────────── 마스터
|
||
[Header("마스터 (C8)")]
|
||
[Tooltip("0 이면 렌더러 피처를 켜지 않고 패스도 넣지 않는다 = 저해상도 RT 가 원본 그대로.")]
|
||
public bool enabled_ = true;
|
||
|
||
[Tooltip("1 이면 on/off·대상 카메라 전환마다 Console 에 1줄 남긴다. LogError 는 쓰지 않는다(813z).")]
|
||
public bool verboseLog = false;
|
||
|
||
// ───────────────────────────────────────── 켜지는 조건
|
||
[Header("켜지는 조건 (LookModeHub 구독)")]
|
||
[Tooltip("이 값 이상의 룩 모드(도트 1~3)에서만 켠다. 기본 모드 0 · 로비 강등 0 에서는 꺼진다.")]
|
||
[Range(0, 8)] public int minCameraMode = 1;
|
||
|
||
[Tooltip("814b 리그가 조립돼 있을 때만 켠다(대상 = 저해상도 게임 카메라). 0 이면 리그 없이도 켜려고 시도한다 = 권장하지 않음.")]
|
||
public bool requirePixelRig = true;
|
||
|
||
// ───────────────────────────────────────── 양자화
|
||
[Header("① 팔레트 양자화")]
|
||
[Tooltip("ChannelLevels = R/G/B 각 levels 단계(기본) · PaletteTexture = N×1 텍스처 최근접(배선만).")]
|
||
public WLPaletteMode mode = WLPaletteMode.ChannelLevels;
|
||
|
||
[Tooltip("채널당 단계 수. 6 = 216색 상한(권장) · 4 = 64색(더 도트답게) · 8 = 512색(약하게).")]
|
||
[Range(2, 32)] public int levels = 6;
|
||
|
||
[Tooltip("PaletteTexture 모드에서 쓸 N×1 RGBA 텍스처(Point · 압축 없음 권장). 비어 있으면 ChannelLevels 로 돈다.")]
|
||
public Texture2D paletteTex;
|
||
|
||
[Tooltip("팔레트 텍스처에서 실제로 읽을 색 개수(0 = 텍스처 가로 크기 그대로 · 셰이더 상한 64).")]
|
||
[Range(0, 64)] public int paletteCount = 0;
|
||
|
||
// ───────────────────────────────────────── 디더
|
||
[Header("② Bayer 순서 디더링")]
|
||
[Tooltip("디더 강도. 0 = 끔 · 0.6 = 권장 기본 · 1 = 양자화 1단계를 꽉 채운다.")]
|
||
[Range(0f, 1.5f)] public float ditherStrength = 0.6f;
|
||
|
||
[Tooltip("디더 행렬 크기. 4 = 4×4(기본 · 도트 느낌) · 8 = 8×8(더 곱다).")]
|
||
public bool dither8x8 = false;
|
||
|
||
// ───────────────────────────────────────── 선택 옵션(기본 무보정)
|
||
[Header("③ 선택 옵션 (기본값 = 무보정)")]
|
||
[Tooltip("채도. 1 = 그대로 · 1보다 크면 색이 진해진다.")]
|
||
[Range(0f, 2f)] public float saturation = 1f;
|
||
|
||
[Tooltip("명도 대비(0.5 기준). 1 = 그대로.")]
|
||
[Range(0.2f, 2f)] public float contrast = 1f;
|
||
|
||
[Tooltip("색조 보정색. 흰색 = 무보정. PD 참고 이미지(밤·보라/파랑)를 근사하려면 보랏빛을 넣고 아래 강도를 올린다.")]
|
||
public Color tintColor = Color.white;
|
||
|
||
[Tooltip("색조 보정 강도. 0 = 무보정(기본).")]
|
||
[Range(0f, 1f)] public float tintStrength = 0f;
|
||
|
||
// ───────────────────────────────────────── 렌더 순서
|
||
[Header("④ 렌더 순서")]
|
||
[Tooltip("1 = AfterRenderingPostProcessing(기본 · 외곽선·포스트 뒤라 전부 같이 양자화된다) · 0 = AfterRenderingTransparents.")]
|
||
public bool afterPostProcessing = true;
|
||
|
||
[Tooltip("1 = 선형 색을 sRGB 로 바꿔서 양자화한다(프로젝트가 Linear 이므로 기본 1). 0 이면 렌더 색 그대로 나눈다.")]
|
||
public bool quantizeInGammaSpace = true;
|
||
}
|
||
}
|