519 lines
27 KiB
C#
519 lines
27 KiB
C#
// WL-814x2 — 🔴 **Play 모드에서만** 재는 색 측정/촬영 하니스
|
||
// 편집 모드 렌더는 스킨 메시가 갱신되지 않아 무의미하다(814x 에서 실측).
|
||
// run_script --file AgentScripts/WL814x2_Play.cs --entry WL814x2.Run (Play 중에 부른다)
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using UnityEngine;
|
||
using WL.Look.Arena;
|
||
using WL.Look.Character;
|
||
|
||
public static class WL814x3
|
||
{
|
||
public const string RAW = "Screenshots_WL/WL814x/3rd/raw/";
|
||
const int W = 1080, H = 1920;
|
||
static readonly StringBuilder sb = new StringBuilder();
|
||
static void L(string s) { sb.AppendLine(s); }
|
||
|
||
static GameObject s_root;
|
||
static Renderer[] s_rends;
|
||
static Material[][] s_orig;
|
||
static Camera s_cam;
|
||
static Vector3 s_camPos, s_center, s_pos;
|
||
static Quaternion s_rot, s_camRot;
|
||
static Animator s_an;
|
||
static float s_camSize, s_ts;
|
||
|
||
static void Setup()
|
||
{
|
||
s_root = GameObject.Find("PC_LH_M05");
|
||
if (s_root == null)
|
||
foreach (var g in UnityEngine.Object.FindObjectsByType<Animator>(FindObjectsSortMode.None))
|
||
if (g.name.Contains("LH_M05")) { s_root = g.gameObject; break; }
|
||
// 🔴 아레나에는 캐릭터를 걷게 하는 리그가 있다 — 샷마다 위치/포즈가 달라지면 색 비교가 무의미하다.
|
||
s_ts = Time.timeScale; Time.timeScale = 0f;
|
||
s_an = s_root.GetComponentInChildren<Animator>();
|
||
if (s_an != null) { s_an.speed = 0f; try { s_an.Play("idle", 0, 0.25f); s_an.Update(0f); } catch { } }
|
||
|
||
s_cam = Camera.main ?? UnityEngine.Object.FindObjectsByType<Camera>(FindObjectsSortMode.None).First(c => c.orthographic);
|
||
s_camPos = s_cam.transform.position; s_camSize = s_cam.orthographicSize; s_camRot = s_cam.transform.rotation;
|
||
s_root.transform.rotation = Quaternion.Euler(0, s_cam.transform.eulerAngles.y + 180f, 0);
|
||
s_pos = s_root.transform.position; s_rot = s_root.transform.rotation;
|
||
|
||
s_rends = s_root.GetComponentsInChildren<Renderer>(true).Where(r => r.enabled && r.gameObject.activeInHierarchy).ToArray();
|
||
s_orig = s_rends.Select(r => r.sharedMaterials).ToArray();
|
||
var b = new Bounds(s_root.transform.position, Vector3.zero);
|
||
foreach (var r in s_rends) b.Encapsulate(r.bounds);
|
||
s_center = b.center;
|
||
L("renderers " + string.Join(",", s_rends.Select(r => r.name)) + " · center " + s_center.ToString("F2") + " · h " + b.size.y.ToString("F3"));
|
||
foreach (var r in s_rends)
|
||
{
|
||
var m = r.sharedMaterial;
|
||
L(" " + r.name + " mat=" + m.name + " shader=" + m.shader.name
|
||
+ " base=" + (m.HasProperty("_BaseMap") && m.GetTexture("_BaseMap") ? m.GetTexture("_BaseMap").name : "-")
|
||
+ " diff=" + (m.HasProperty("_DiffuseColor") ? m.GetColor("_DiffuseColor").ToString("F3") : "-")
|
||
+ " shadow=" + (m.HasProperty("_ShadowDiffuseColor") ? m.GetColor("_ShadowDiffuseColor").ToString("F4") : "-")
|
||
+ " shades=" + (m.HasProperty("_Shades") ? m.GetFloat("_Shades").ToString("F0") : "-")
|
||
+ " minDark=" + (m.HasProperty("_MinimumDarkness") ? m.GetFloat("_MinimumDarkness").ToString("F2") : "-"));
|
||
}
|
||
var rc = WLReferenceLookSettings.Instance;
|
||
L("ReferenceLook: rimOn=" + rc.rimOn + " moodOn=" + rc.moodOn + " mood=" + rc.moodStrength.ToString("F2")
|
||
+ " contrast=" + rc.contrastOn + " minDark=" + rc.minimumDarkness.ToString("F2")
|
||
+ " shadowScale=" + rc.shadowColorScale.ToString("F2") + " shadowTintAmt=" + rc.shadowTintAmount.ToString("F2")
|
||
+ " shadowTint=" + rc.shadowTint.ToString("F3") + " charShades=" + rc.charShades
|
||
+ " key=" + rc.keyLightColor.ToString("F2") + "×" + rc.keyLightIntensity.ToString("F2") + " amb=" + rc.ambientColor.ToString("F2"));
|
||
}
|
||
|
||
static void Teardown()
|
||
{
|
||
for (int i = 0; i < s_rends.Length; i++) { s_rends[i].sharedMaterials = s_orig[i]; s_rends[i].enabled = true; }
|
||
s_cam.transform.SetPositionAndRotation(s_camPos, s_camRot); s_cam.orthographicSize = s_camSize;
|
||
Time.timeScale = s_ts;
|
||
}
|
||
|
||
static int[] s_layers; static int s_cull; static CameraClearFlags s_clear; static Color s_bg; static bool s_post, s_postSaved;
|
||
/// <summary>캐릭터만 남기고 배경·그림자·포스트를 모두 끈 렌더 상태(마스크·덩어리지도 전용).</summary>
|
||
static void Isolate(bool on)
|
||
{
|
||
var ts = s_root.GetComponentsInChildren<Transform>(true);
|
||
var ucd = s_cam.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
|
||
if (on)
|
||
{
|
||
s_layers = ts.Select(t => t.gameObject.layer).ToArray();
|
||
foreach (var t in ts) t.gameObject.layer = 31;
|
||
s_cull = s_cam.cullingMask; s_clear = s_cam.clearFlags; s_bg = s_cam.backgroundColor;
|
||
s_cam.cullingMask = 1 << 31; s_cam.clearFlags = CameraClearFlags.SolidColor; s_cam.backgroundColor = Color.black;
|
||
if (ucd != null) { s_post = ucd.renderPostProcessing; s_postSaved = true; ucd.renderPostProcessing = false; }
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ts.Length && i < s_layers.Length; i++) ts[i].gameObject.layer = s_layers[i];
|
||
s_cam.cullingMask = s_cull; s_cam.clearFlags = s_clear; s_cam.backgroundColor = s_bg;
|
||
if (ucd != null && s_postSaved) { ucd.renderPostProcessing = s_post; s_postSaved = false; }
|
||
}
|
||
}
|
||
class Shot { public Color32[] px; }
|
||
|
||
static Shot Render(float ortho)
|
||
{
|
||
// 매 렌더마다 같은 위치·같은 포즈로 고정한다
|
||
s_root.transform.SetPositionAndRotation(s_pos, s_rot);
|
||
if (s_an != null) { s_an.speed = 0f; try { s_an.Play("idle", 0, 0.25f); s_an.Update(0f); } catch { } }
|
||
// 🔴 카메라도 매 프레임 따라다니는 스크립트가 있다 — 회전까지 고정해야 프레이밍이 같다.
|
||
s_cam.orthographicSize = ortho;
|
||
s_cam.transform.SetPositionAndRotation(s_center - (s_camRot * Vector3.forward) * 30f, s_camRot);
|
||
var rt = new RenderTexture(W, H, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||
rt.antiAliasing = 1; rt.filterMode = FilterMode.Point; rt.Create();
|
||
var prev = s_cam.targetTexture; s_cam.targetTexture = rt; s_cam.Render(); s_cam.targetTexture = prev;
|
||
var pa = RenderTexture.active; RenderTexture.active = rt;
|
||
var t = new Texture2D(W, H, TextureFormat.RGBA32, false); t.ReadPixels(new Rect(0, 0, W, H), 0, 0); t.Apply();
|
||
RenderTexture.active = pa;
|
||
var s = new Shot { px = t.GetPixels32() };
|
||
UnityEngine.Object.Destroy(t); rt.Release(); UnityEngine.Object.Destroy(rt);
|
||
return s;
|
||
}
|
||
|
||
static void Save(Shot s, string name)
|
||
{
|
||
var t = new Texture2D(W, H, TextureFormat.RGBA32, false); t.SetPixels32(s.px); t.Apply();
|
||
Directory.CreateDirectory(RAW); File.WriteAllBytes(RAW + name + ".png", t.EncodeToPNG());
|
||
UnityEngine.Object.Destroy(t);
|
||
}
|
||
|
||
static void Shoot(string name, float ortho) { Render(ortho); Save(Render(ortho), name); }
|
||
|
||
static void SaveMask(string name, float ortho, params Renderer[] on)
|
||
{
|
||
Isolate(true);
|
||
foreach (var r in s_rends) r.enabled = on.Contains(r);
|
||
var a = Render(ortho);
|
||
foreach (var r in s_rends) r.enabled = true;
|
||
Isolate(false);
|
||
var t = new Texture2D(W, H, TextureFormat.RGBA32, false);
|
||
var px = new Color32[W * H]; int n = 0;
|
||
for (int i = 0; i < px.Length; i++)
|
||
{
|
||
int d = a.px[i].r + a.px[i].g + a.px[i].b;
|
||
bool hit = d > 12; if (hit) n++;
|
||
px[i] = hit ? new Color32(255, 255, 255, 255) : new Color32(0, 0, 0, 255);
|
||
}
|
||
t.SetPixels32(px); t.Apply();
|
||
Directory.CreateDirectory(RAW); File.WriteAllBytes(RAW + "mask_" + name + ".png", t.EncodeToPNG());
|
||
UnityEngine.Object.Destroy(t);
|
||
L("mask " + name + " @" + ortho.ToString("F2") + " = " + n + " px");
|
||
}
|
||
|
||
/// <summary>덩어리(팔레트 칸) 지도 — 빛 0. 부위별 색을 재기 위한 마스크.</summary>
|
||
static void ShootIdMap(string name, float ortho)
|
||
{
|
||
var pal = UnityEditor.AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/WL/Look/Character/Textures/WLPalette_FINAL.png");
|
||
int S = pal.width, G = S / 8;
|
||
var t = new Texture2D(S, S, TextureFormat.RGBA32, false) { filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp };
|
||
var px = new Color32[S * S];
|
||
for (int i = 0; i < px.Length; i++) px[i] = new Color32(0, 0, 0, 255);
|
||
for (int j = 0; j < G * G; j++)
|
||
{
|
||
int gx = j % G, gy = j / G;
|
||
var c = new Color32((byte)(9 + j * 15), (byte)(240 - j * 11), (byte)(40 + j * 7), 255);
|
||
for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) px[(gy * 8 + y) * S + gx * 8 + x] = c;
|
||
}
|
||
t.SetPixels32(px); t.Apply();
|
||
Isolate(true);
|
||
var sh = Shader.Find("Unlit/Texture");
|
||
var keep = new List<Renderer>();
|
||
for (int i = 0; i < s_rends.Length; i++)
|
||
{
|
||
if (s_rends[i].name == "Face") { s_rends[i].enabled = false; keep.Add(s_rends[i]); continue; }
|
||
var m = new Material(sh); m.SetTexture("_MainTex", t);
|
||
s_rends[i].sharedMaterials = Enumerable.Repeat(m, s_orig[i].Length).ToArray();
|
||
}
|
||
Shoot(name, ortho);
|
||
foreach (var r in keep) r.enabled = true;
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
Isolate(false);
|
||
UnityEngine.Object.Destroy(t);
|
||
// 팔레트 칸 색도 적어 둔다(인덱스 → 팔레트 RGB)
|
||
var cols = pal.GetPixels32();
|
||
for (int j = 0; j < G * G; j++)
|
||
{
|
||
int gx = j % G, gy = j / G;
|
||
var c = cols[(gy * 8 + 4) * S + gx * 8 + 4];
|
||
L(string.Format("PAL {0,2} id={1},{2},{3} rgb={4},{5},{6}", j, 9 + j * 15, 240 - j * 11, 40 + j * 7, c.r, c.g, c.b));
|
||
}
|
||
}
|
||
|
||
/// <summary>ToonP 머티리얼의 그림자색만 바꾼 임시 복제본으로 교체.</summary>
|
||
static void SetShadow(Color shadow, float shades)
|
||
{
|
||
for (int i = 0; i < s_rends.Length; i++)
|
||
{
|
||
var mats = (Material[])s_orig[i].Clone();
|
||
for (int m = 0; m < mats.Length; m++)
|
||
{
|
||
if (mats[m] == null || mats[m].shader == null || mats[m].shader.name != "Shader Graphs/Toon") continue;
|
||
var c = new Material(mats[m]) { name = "TMP_" + mats[m].name };
|
||
c.SetColor("_ShadowDiffuseColor", shadow);
|
||
if (shades > 0) c.SetFloat("_Shades", shades);
|
||
mats[m] = c;
|
||
}
|
||
s_rends[i].sharedMaterials = mats;
|
||
}
|
||
}
|
||
static void ResetMats() { for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i]; }
|
||
|
||
static void Look(float mood, float shadowTintAmount, int rim)
|
||
{
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg);
|
||
o.mood = mood > 0f; o.moodStrength = mood;
|
||
o.shadowTintAmount = shadowTintAmount;
|
||
o.rim = rim != 0;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
}
|
||
|
||
public static string Run()
|
||
{
|
||
sb.Length = 0;
|
||
try
|
||
{
|
||
Setup();
|
||
SaveMask("all", 0.95f, s_rends);
|
||
foreach (var r in s_rends) SaveMask(r.name, 0.95f, r);
|
||
SaveMask("all10", 10f, s_rends);
|
||
foreach (var r in s_rends) SaveMask(r.name + "10", 10f, r);
|
||
ShootIdMap("idmap", 0.95f);
|
||
ShootIdMap("idmap10", 10f);
|
||
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
float mood0 = cfg.moodStrength, tint0 = cfg.shadowTintAmount;
|
||
|
||
Action<string, Color, float, float, float, int> V = (name, shadow, shades, mood, tintAmt, rim) =>
|
||
{
|
||
ResetMats();
|
||
WLReferenceLook.Restore();
|
||
if (shadow.a >= 0f && shadow != Color.clear) SetShadow(shadow, shades);
|
||
Look(mood, tintAmt, rim);
|
||
Shoot(name, 0.95f);
|
||
Shoot(name + "_g", 10f);
|
||
L("shot " + name + " shadow=" + shadow.ToString("F3") + " shades=" + shades + " mood=" + mood.ToString("F2") + " tintAmt=" + tintAmt.ToString("F2") + " · " + WLReferenceLook.LastLog);
|
||
};
|
||
|
||
var purple = new Color(0.2164f, 0.2092f, 0.3713f, 0f);
|
||
V("a_now", purple, 3f, mood0, tint0, 0);
|
||
V("b_neutral", new Color(0.45f, 0.45f, 0.45f, 0f), 3f, mood0, tint0, 0);
|
||
V("c_neutral_notint", new Color(0.45f, 0.45f, 0.45f, 0f), 3f, mood0, 0f, 0);
|
||
V("d_neutral_notint_mood0", new Color(0.45f, 0.45f, 0.45f, 0f), 3f, 0f, 0f, 0);
|
||
V("e_warm_notint", new Color(0.52f, 0.45f, 0.40f, 0f), 3f, mood0, 0f, 0);
|
||
V("f_neutral_notint_s7", new Color(0.45f, 0.45f, 0.45f, 0f), 7f, mood0, 0f, 0);
|
||
V("g_dark_notint", new Color(0.32f, 0.32f, 0.34f, 0f), 3f, mood0, 0f, 0);
|
||
|
||
ResetMats(); WLReferenceLook.Restore(); Look(mood0, tint0, 0);
|
||
L("DONE");
|
||
}
|
||
catch (Exception e) { L("EXCEPTION " + e); }
|
||
finally { try { Teardown(); } catch { } Directory.CreateDirectory("AgentScripts"); File.WriteAllText("AgentScripts/WL814x3_PLAY.txt", sb.ToString(), new UTF8Encoding(true)); }
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>아레나 씬을 연다(Play 진입 전 · 편집 모드에서 1회).</summary>
|
||
public static string Open()
|
||
{
|
||
UnityEditor.SceneManagement.EditorSceneManager.OpenScene("Assets/WL/Look/Arena/Scenes/WL_ArenaProto.unity", UnityEditor.SceneManagement.OpenSceneMode.Single);
|
||
return "opened " + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
|
||
}
|
||
|
||
/// <summary>무드(포스트 그레이딩·앰비언트·키라이트)가 화면 색을 얼마나 틀어놓는지 — 에셋 수정 0(런타임 프로파일 인스턴스).</summary>
|
||
public static string Mood()
|
||
{
|
||
sb.Length = 0;
|
||
try
|
||
{
|
||
Setup();
|
||
SaveMask("all", 0.95f, s_rends);
|
||
foreach (var r in s_rends) SaveMask(r.name, 0.95f, r);
|
||
SaveMask("all10", 10f, s_rends);
|
||
ShootIdMap("idmap", 0.95f);
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
|
||
Action<string, float, bool, bool> V = (name, mood, killWB, killSMH) =>
|
||
{
|
||
WLReferenceLook.Restore();
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg);
|
||
o.rim = false; o.mood = mood > 0f; o.moodStrength = mood;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
var vgo = GameObject.Find("WL814t_ReferenceLook_Volume");
|
||
// killWB = 포스트 그레이딩 Volume 의 weight 만 0 으로 (조명 무드는 그대로 둔다)
|
||
if (vgo != null && killWB) vgo.GetComponent<UnityEngine.Rendering.Volume>().weight = 0f;
|
||
Shoot(name, 0.95f); Shoot(name + "_g", 10f);
|
||
L("mood shot " + name + " mood=" + mood.ToString("F2") + " killWB=" + killWB + " killSMH=" + killSMH);
|
||
};
|
||
V("m30", 0.30f, false, false);
|
||
V("m15", 0.15f, false, false);
|
||
V("m00", 0.00f, false, false);
|
||
V("n_novol30", 0.30f, true, false);
|
||
V("n_novol15", 0.15f, true, false);
|
||
WLReferenceLook.Restore();
|
||
var o2 = WLReferenceLook.Opt.FromSettings(cfg); o2.rim = false;
|
||
WLReferenceLook.Apply(o2, cfg);
|
||
L("DONE");
|
||
}
|
||
catch (Exception e) { L("EXCEPTION " + e); }
|
||
finally { try { Teardown(); } catch { } File.WriteAllText("AgentScripts/WL814x3_MOOD.txt", sb.ToString(), new UTF8Encoding(true)); }
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>🔴 캐릭터 전용 광원 색조 상쇄 — _DiffuseColor 에 휘도보존 역이득을 넣는다.
|
||
/// 씬·조명·814t 설정·ProjectSettings 는 하나도 안 건드린다.</summary>
|
||
public static string SetTint()
|
||
{
|
||
var g = new Color(0.994f, 1.024f, 0.894f, 1f);
|
||
var sb2 = new StringBuilder();
|
||
foreach (var n in new[] { "M05_ToonP", "Skin_ToonP", "Hair05_ToonP" })
|
||
{
|
||
var p = "Assets/WL/Look/Character/Materials/" + n + ".mat";
|
||
var m = UnityEditor.AssetDatabase.LoadAssetAtPath<Material>(p);
|
||
if (m == null) { sb2.AppendLine("!! " + p); continue; }
|
||
m.SetColor("_DiffuseColor", g);
|
||
UnityEditor.EditorUtility.SetDirty(m);
|
||
sb2.AppendLine(n + " _DiffuseColor = " + g.ToString("F3"));
|
||
}
|
||
UnityEditor.AssetDatabase.SaveAssets();
|
||
return sb2.ToString();
|
||
}
|
||
|
||
/// <summary>3차 — 앰비언트/키라이트 색조 3+1안. 🔴 SO·씬·에셋은 안 건드린다(런타임 RenderSettings·Light.color 만).</summary>
|
||
public static string Amb()
|
||
{
|
||
sb.Length = 0;
|
||
try
|
||
{
|
||
Setup();
|
||
SaveMask("all", 0.95f, s_rends);
|
||
foreach (var r in s_rends) SaveMask(r.name, 0.95f, r);
|
||
SaveMask("all10", 10f, s_rends);
|
||
ShootIdMap("idmap", 0.95f);
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
var lights = UnityEngine.Object.FindObjectsByType<Light>(FindObjectsSortMode.None)
|
||
.Where(l => l.type == LightType.Directional).ToArray();
|
||
|
||
// 측정은 «보정 없는» 상태에서 — _DiffuseColor 를 흰색으로 되돌린 임시 복제본
|
||
Action white = () =>
|
||
{
|
||
for (int i = 0; i < s_rends.Length; i++)
|
||
{
|
||
var mats = (Material[])s_orig[i].Clone();
|
||
for (int m = 0; m < mats.Length; m++)
|
||
{
|
||
if (mats[m] == null || mats[m].shader == null || mats[m].shader.name != "Shader Graphs/Toon") continue;
|
||
var c = new Material(mats[m]) { name = "TMP_w" };
|
||
c.SetColor("_DiffuseColor", Color.white);
|
||
mats[m] = c;
|
||
}
|
||
s_rends[i].sharedMaterials = mats;
|
||
}
|
||
};
|
||
|
||
Action<string, Color, Color> V = (name, amb, key) =>
|
||
{
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
WLReferenceLook.Restore();
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg); o.rim = false;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
if (amb.a > 0f) RenderSettings.ambientLight = new Color(amb.r, amb.g, amb.b, 1f);
|
||
if (key.a > 0f) foreach (var l in lights) l.color = new Color(key.r, key.g, key.b, 1f);
|
||
white();
|
||
Shoot(name, 0.95f);
|
||
Shoot(name + "_g", 10f);
|
||
L(string.Format("amb shot {0} ambient={1} key={2}", name, RenderSettings.ambientLight.ToString("F3"),
|
||
lights.Length > 0 ? lights[0].color.ToString("F3") : "-"));
|
||
};
|
||
|
||
Color no = new Color(0, 0, 0, 0);
|
||
// 현재 무드가 만드는 앰비언트 = lerp(원래, (0.28,0.17,0.40), 0.30) → 그대로 두면 v0
|
||
V("v0_purple", no, no);
|
||
V("v1_gray", new Color(0.229f, 0.229f, 0.229f, 1f), no);
|
||
V("v2_cool", new Color(0.205f, 0.228f, 0.262f, 1f), no);
|
||
V("v3_warm", new Color(0.262f, 0.226f, 0.193f, 1f), no);
|
||
V("v4_gray_keysoft", new Color(0.229f, 0.229f, 0.229f, 1f), new Color(1f, 0.95f, 0.90f, 1f));
|
||
V("v5_gray_keywhite", new Color(0.229f, 0.229f, 0.229f, 1f), new Color(1f, 1f, 1f, 1f));
|
||
|
||
// 배경 포함 넓은 구도(게임 실제 카메라 위치·직교 10) — 배경이 얼마나 바뀌는지
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
Action<string, Color, Color> WIDE = (name, amb, key) =>
|
||
{
|
||
WLReferenceLook.Restore();
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg); o.rim = false;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
if (amb.a > 0f) RenderSettings.ambientLight = new Color(amb.r, amb.g, amb.b, 1f);
|
||
if (key.a > 0f) foreach (var l in lights) l.color = new Color(key.r, key.g, key.b, 1f);
|
||
s_cam.orthographicSize = 10f;
|
||
s_cam.transform.SetPositionAndRotation(s_camPos, s_camRot);
|
||
var rt = new RenderTexture(W, H, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||
rt.antiAliasing = 1; rt.filterMode = FilterMode.Point; rt.Create();
|
||
var pv = s_cam.targetTexture; s_cam.targetTexture = rt; s_cam.Render(); s_cam.Render(); s_cam.targetTexture = pv;
|
||
var pa = RenderTexture.active; RenderTexture.active = rt;
|
||
var t = new Texture2D(W, H, TextureFormat.RGBA32, false); t.ReadPixels(new Rect(0, 0, W, H), 0, 0); t.Apply();
|
||
RenderTexture.active = pa;
|
||
Directory.CreateDirectory(RAW); File.WriteAllBytes(RAW + name + ".png", t.EncodeToPNG());
|
||
UnityEngine.Object.Destroy(t); rt.Release(); UnityEngine.Object.Destroy(rt);
|
||
L("wide " + name);
|
||
};
|
||
WIDE("w0_purple", no, no);
|
||
WIDE("w1_gray", new Color(0.229f, 0.229f, 0.229f, 1f), no);
|
||
WIDE("w4_gray_keysoft", new Color(0.229f, 0.229f, 0.229f, 1f), new Color(1f, 0.95f, 0.90f, 1f));
|
||
WIDE("w5_gray_keywhite", new Color(0.229f, 0.229f, 0.229f, 1f), new Color(1f, 1f, 1f, 1f));
|
||
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
WLReferenceLook.Restore();
|
||
var o2 = WLReferenceLook.Opt.FromSettings(cfg); o2.rim = false; WLReferenceLook.Apply(o2, cfg);
|
||
L("DONE");
|
||
}
|
||
catch (Exception e) { L("EXCEPTION " + e); }
|
||
finally { try { Teardown(); } catch { } File.WriteAllText("AgentScripts/WL814x3_AMB.txt", sb.ToString(), new UTF8Encoding(true)); }
|
||
return sb.ToString();
|
||
}
|
||
|
||
|
||
/// <summary>3차 채택값 쓰기 — 앰비언트 중성화(814t SO) + 캐릭터 _DiffuseColor 흰색 복귀.</summary>
|
||
public static string Adopt()
|
||
{
|
||
var sb2 = new StringBuilder();
|
||
var rc = UnityEditor.AssetDatabase.LoadAssetAtPath<WLReferenceLookSettings>("Assets/WL/Look/Arena/Resources/WL/WLReferenceLookSettings.asset");
|
||
sb2.AppendLine("ambientColor " + rc.ambientColor.ToString("F3") + " → 중성 (0.229,0.229,0.229)");
|
||
rc.ambientColor = new Color(0.229f, 0.229f, 0.229f, 1f);
|
||
UnityEditor.EditorUtility.SetDirty(rc);
|
||
foreach (var n in new[] { "M05_ToonP", "Skin_ToonP", "Hair05_ToonP" })
|
||
{
|
||
var m = UnityEditor.AssetDatabase.LoadAssetAtPath<Material>("Assets/WL/Look/Character/Materials/" + n + ".mat");
|
||
var dc = new Color(0.993f, 1.028f, 0.874f, 1f);
|
||
m.SetColor("_DiffuseColor", dc);
|
||
UnityEditor.EditorUtility.SetDirty(m);
|
||
sb2.AppendLine(n + " _DiffuseColor → " + dc.ToString("F3"));
|
||
}
|
||
UnityEditor.AssetDatabase.ImportAsset("Assets/WL/Look/Character/Textures/WLPalette_FINAL.png", UnityEditor.ImportAssetOptions.ForceUpdate);
|
||
UnityEditor.AssetDatabase.SaveAssets();
|
||
return sb2.ToString();
|
||
}
|
||
|
||
/// <summary>최종 = 실제 배선된 머티리얼 그대로(보정 포함) 근접·게임크기·넓은 구도.</summary>
|
||
public static string Final()
|
||
{
|
||
sb.Length = 0;
|
||
try
|
||
{
|
||
Setup();
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
L("ambient(SO)=" + cfg.ambientColor.ToString("F3") + " diffuse=" + s_rends[0].sharedMaterial.GetColor("_DiffuseColor").ToString("F3"));
|
||
WLReferenceLook.Restore();
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg); o.rim = false;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
Shoot("f_final", 0.95f);
|
||
Shoot("f_final_g", 10f);
|
||
s_cam.orthographicSize = 10f;
|
||
s_cam.transform.SetPositionAndRotation(s_camPos, s_camRot);
|
||
var rt = new RenderTexture(W, H, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
|
||
rt.antiAliasing = 1; rt.filterMode = FilterMode.Point; rt.Create();
|
||
var pv = s_cam.targetTexture; s_cam.targetTexture = rt; s_cam.Render(); s_cam.Render(); s_cam.targetTexture = pv;
|
||
var pa = RenderTexture.active; RenderTexture.active = rt;
|
||
var t = new Texture2D(W, H, TextureFormat.RGBA32, false); t.ReadPixels(new Rect(0, 0, W, H), 0, 0); t.Apply();
|
||
RenderTexture.active = pa;
|
||
Directory.CreateDirectory(RAW); File.WriteAllBytes(RAW + "f_wide.png", t.EncodeToPNG());
|
||
UnityEngine.Object.Destroy(t); rt.Release(); UnityEngine.Object.Destroy(rt);
|
||
L("DONE");
|
||
}
|
||
catch (Exception e) { L("EXCEPTION " + e); }
|
||
finally { try { Teardown(); } catch { } File.WriteAllText("AgentScripts/WL814x3_FINAL.txt", sb.ToString(), new UTF8Encoding(true)); }
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>어두운 면(피부)의 잔여 색조 — 그림자 알베도 색을 바꿔 비교(에셋 무수정·임시 복제본).</summary>
|
||
public static string Shad()
|
||
{
|
||
sb.Length = 0;
|
||
try
|
||
{
|
||
Setup();
|
||
SaveMask("all", 0.95f, s_rends);
|
||
foreach (var r in s_rends) SaveMask(r.name, 0.95f, r);
|
||
ShootIdMap("idmap", 0.95f);
|
||
var cfg = WLReferenceLookSettings.Instance;
|
||
Action<string, Color> V = (name, sh) =>
|
||
{
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
WLReferenceLook.Restore();
|
||
if (sh.a > 0f)
|
||
for (int i = 0; i < s_rends.Length; i++)
|
||
{
|
||
var mats = (Material[])s_orig[i].Clone();
|
||
for (int m = 0; m < mats.Length; m++)
|
||
{
|
||
if (mats[m] == null || mats[m].shader == null || mats[m].shader.name != "Shader Graphs/Toon") continue;
|
||
var c = new Material(mats[m]) { name = "TMP_s" };
|
||
c.SetColor("_ShadowDiffuseColor", new Color(sh.r, sh.g, sh.b, 0f));
|
||
mats[m] = c;
|
||
}
|
||
s_rends[i].sharedMaterials = mats;
|
||
}
|
||
var o = WLReferenceLook.Opt.FromSettings(cfg); o.rim = false;
|
||
WLReferenceLook.Apply(o, cfg);
|
||
Shoot(name, 0.95f); Shoot(name + "_g", 10f);
|
||
L("shadow shot " + name + " = " + sh.ToString("F3"));
|
||
};
|
||
V("s0_now", new Color(0, 0, 0, 0));
|
||
V("s1_gray", new Color(0.38f, 0.38f, 0.38f, 1f));
|
||
V("s2_warm", new Color(0.42f, 0.38f, 0.32f, 1f));
|
||
V("s3_graylight", new Color(0.50f, 0.50f, 0.50f, 1f));
|
||
V("s4_warmlight", new Color(0.55f, 0.50f, 0.42f, 1f));
|
||
for (int i = 0; i < s_rends.Length; i++) s_rends[i].sharedMaterials = s_orig[i];
|
||
WLReferenceLook.Restore();
|
||
var o2 = WLReferenceLook.Opt.FromSettings(cfg); o2.rim = false; WLReferenceLook.Apply(o2, cfg);
|
||
L("DONE");
|
||
}
|
||
catch (Exception e) { L("EXCEPTION " + e); }
|
||
finally { try { Teardown(); } catch { } File.WriteAllText("AgentScripts/WL814x3_SHAD.txt", sb.ToString(), new UTF8Encoding(true)); }
|
||
return sb.ToString();
|
||
}
|
||
}
|