Project_WL/AgentScripts/WL816j2_Build.cs

158 lines
8.6 KiB
C#
Raw Permalink 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.

// WL-816j2 — ① 띠 텍스처·머티리얼·물 머티리얼 E 를 만든다 (에디트 모드)
// 🔴 원본 셰이더/FI/씬 0줄. 전부 새 에셋(`Assets/WL/Look/Farm/**`)이다.
using System.Text;
using UnityEngine;
using UnityEditor;
public static class WL816j2_Build
{
const string MatDir = "Assets/WL/Look/Farm/Materials/";
const string TexDir = "Assets/WL/Look/Farm/Textures/";
const string TexPath = TexDir + "WL_ShoreFoam.png";
const string FoamMat = MatDir + "Farm_ShoreFoam.mat";
const string R_FoamScale = "Vector1_11671d7a4cdb4d059a6c69e39f3f7b3f";
const string R_FoamSpeed = "Vector1_3089b6a325a44c1686907af4ee3b0776";
const string R_FoamDistance = "Vector1_101dc4546b684d40bc2ff2fc59ab43d5";
const string R_FoamEdge = "Vector1_34f757bec6b8422b9aef3b9d97117a6e";
const string C_Light = "Color_1ec6cccf8ead489ebb917674f7e8b3b1";
const string C_Foam = "Color_e1f155248d144786a62fc1585ca21e9a";
const string C_FoamShadow = "Color_2323d69962e04c499c5d5f0925432b55";
public static void Run()
{
var sb = new StringBuilder();
// ── ① 거품 띠 텍스처 (가로 = 해안을 따라 · 세로 v0 = 물가, v1 = 바깥) ──
System.IO.Directory.CreateDirectory(TexDir);
const int W = 512, H = 128;
var tex = new Texture2D(W, H, TextureFormat.RGBA32, false);
var px = new Color32[W * H];
for (int y = 0; y < H; y++)
{
float v = y / (float)(H - 1);
float t = 1f - v; // 물가에서 1, 바깥에서 0
for (int x = 0; x < W; x++)
{
float n = Fbm(x, y, W); // 0~1 · 가로로 이어진다
// 🔴 Mathf.SmoothStep(a,b,t) 는 「a~b 사이 보간」이지 GLSL smoothstep 이 아니다(816j2 에서 이걸로 한 번 틀렸다).
float k = Mathf.Clamp01((t - 0.18f) / 0.30f + (n - 0.5f) * 1.0f);
float a = k * k * (3f - 2f * k); // 물가 = 1 · 바깥으로 가며 거품이 부서진다
px[y * W + x] = new Color32(255, 255, 255, (byte)Mathf.RoundToInt(Mathf.Clamp01(a) * 255f));
}
}
tex.SetPixels32(px); tex.Apply();
System.IO.File.WriteAllBytes(TexPath, tex.EncodeToPNG());
Object.DestroyImmediate(tex);
AssetDatabase.ImportAsset(TexPath, ImportAssetOptions.ForceUpdate);
var imp = AssetImporter.GetAtPath(TexPath) as TextureImporter;
if (imp != null)
{
imp.textureType = TextureImporterType.Default;
imp.alphaIsTransparency = true;
imp.alphaSource = TextureImporterAlphaSource.FromInput;
imp.wrapModeU = TextureWrapMode.Repeat;
imp.wrapModeV = TextureWrapMode.Clamp;
imp.filterMode = FilterMode.Bilinear;
imp.mipmapEnabled = true;
imp.maxTextureSize = 512;
imp.SaveAndReimport();
}
sb.AppendLine("띠 텍스처 = " + TexPath + " (" + W + "×" + H + " · U 반복 / V 고정 · mip on)");
// ── ② 띠 머티리얼 (URP Unlit · 반투명 · ZWrite off · 물보다 뒤에) ──
var sh = Shader.Find("Universal Render Pipeline/Unlit");
if (sh == null) { Debug.LogError("[816j2] URP Unlit 셰이더 없음"); return; }
var fm = AssetDatabase.LoadAssetAtPath<Material>(FoamMat);
if (fm == null) { fm = new Material(sh); AssetDatabase.CreateAsset(fm, FoamMat); }
fm.shader = sh;
fm.SetTexture("_BaseMap", AssetDatabase.LoadAssetAtPath<Texture2D>(TexPath));
fm.SetColor("_BaseColor", new Color(1f, 1f, 1f, 0.92f));
fm.SetFloat("_Surface", 1f); // Transparent
fm.SetFloat("_Blend", 0f); // Alpha
fm.SetFloat("_AlphaClip", 0f);
fm.SetFloat("_SrcBlend", (float)UnityEngine.Rendering.BlendMode.SrcAlpha);
fm.SetFloat("_DstBlend", (float)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
fm.SetFloat("_ZWrite", 0f);
fm.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Off);
fm.SetFloat("_QueueOffset", 50f); // 물(3000)보다 뒤
fm.SetFloat("_QueueControl", 0f); // 0 = 사용자 지정(URP 가 자동으로 되돌리지 못하게)
fm.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
fm.DisableKeyword("_ALPHATEST_ON");
fm.DisableKeyword("_ALPHAPREMULTIPLY_ON");
fm.renderQueue = 3050; // 물(3000)보다 뒤에 그린다
EditorUtility.SetDirty(fm);
sb.AppendLine("띠 머티리얼 = " + FoamMat + " · shader " + fm.shader.name + " · queue " + fm.renderQueue);
// ── ③ 물 머티리얼 E = D 복사본 + 무늬 선 약화 + 깊이 거품 낮춤 ──
string dst = MatDir + "Farm_Water_WL_E.mat";
if (AssetDatabase.LoadAssetAtPath<Material>(dst) == null)
{ AssetDatabase.CopyAsset(MatDir + "Farm_Water_WL_D.mat", dst); AssetDatabase.ImportAsset(dst); }
var e = AssetDatabase.LoadAssetAtPath<Material>(dst);
// ⓐ 무늬를 1칸 2.5 m → **1.0 m** 로 더 잘게(「금 간 유리」 → 잔물결) · 흐름 0.8 m/s 유지
const float cellM = 1.0f;
float size = 1000f / (cellM * 6f);
e.SetFloat("Vector1_07238257334b4a149e675e2451801030", size); // Size
e.SetFloat("Vector1_99cc56b5c6fd474082f07f00a6df94f9", 0.3085f / size); // Strength
e.SetFloat("Vector1_8e22a98f75c94b218c49e6c4805e799d", 0.8f * size / 1000f); // Speed
e.SetFloat("Vector1_ad7e0fcd37f44d68b68de6f06bb43b96", 0.8f * size / 1000f); // NoiseSpeed
// ⓑ 선 세기 — 밝은 쪽(LightColor)은 물색 가까이, 어두운 쪽(FoamShadowColor)은 흰색으로 없앤다
e.SetColor(C_Light, new Color(0.42f, 0.72f, 0.845f, 1f));
e.SetColor(C_FoamShadow, Color.white);
// ⓒ 깊이 기반 거품은 **끈다** — 둘레 띠가 대신한다(둘 다 켜면 분홍 얼룩이 된다)
e.SetColor(C_Foam, e.GetColor("Color_9af4ad59934f40d1ae6565e6ab22c45e")); // = WaterColor
e.SetFloat(R_FoamDistance, 2.2f);
e.SetFloat(R_FoamEdge, 4f);
EditorUtility.SetDirty(e);
sb.AppendLine("물 E = " + dst + " · Size " + size.ToString("F2") + "(무늬 1칸 " + cellM + " m)"
+ " · LightColor " + e.GetColor(C_Light) + " · FoamShadowColor 흰색"
+ " · FoamColor = 물색(깊이 거품 off) · FoamDistance " + e.GetFloat(R_FoamDistance) + " · FoamEdge " + e.GetFloat(R_FoamEdge));
// ── ④ SO ──
var cfg = AssetDatabase.LoadAssetAtPath<WL.Look.Farm.WLIslandLookSettings>(
"Assets/WL/Look/Farm/Resources/WL/WLIslandLookSettings.asset");
var so = new SerializedObject(cfg);
so.FindProperty("waterTo").objectReferenceValue = e;
so.FindProperty("shoreFoamMaterial").objectReferenceValue = fm;
so.FindProperty("shoreFoamEnabled").intValue = 1;
so.ApplyModifiedPropertiesWithoutUndo();
EditorUtility.SetDirty(cfg);
AssetDatabase.SaveAssets();
sb.AppendLine("SO waterTo = " + cfg.waterTo.name + " · shoreFoamMaterial = " + cfg.shoreFoamMaterial.name
+ " · 폭 " + cfg.shoreFoamWidth + " m · 격자 " + cfg.shoreFoamCell + " m");
System.IO.File.WriteAllText("AgentScripts/WL816j2_BUILD.txt", sb.ToString());
Debug.Log("[816j2 build]\n" + sb);
}
// 가로로 이어지는(타일링) 값 노이즈 fbm
static float Fbm(int x, int y, int W)
{
float s = 0f, amp = 0.5f; int period = 32;
for (int o = 0; o < 3; o++)
{
s += amp * Value(x, y, W, period);
amp *= 0.5f; period *= 2;
}
return Mathf.Clamp01(s + 0.25f);
}
static float Value(int x, int y, int W, int period)
{
float fx = x / (float)period, fy = y / (float)period;
int x0 = Mathf.FloorToInt(fx), y0 = Mathf.FloorToInt(fy);
float tx = fx - x0, ty = fy - y0;
tx = tx * tx * (3f - 2f * tx); ty = ty * ty * (3f - 2f * ty);
int wrap = Mathf.Max(1, W / period);
float a = H2(Mod(x0, wrap), y0), b = H2(Mod(x0 + 1, wrap), y0);
float c = H2(Mod(x0, wrap), y0 + 1), d = H2(Mod(x0 + 1, wrap), y0 + 1);
return Mathf.Lerp(Mathf.Lerp(a, b, tx), Mathf.Lerp(c, d, tx), ty);
}
static int Mod(int a, int m) { int r = a % m; return r < 0 ? r + m : r; }
static float H2(int x, int y)
{
uint h = (uint)(x * 374761393 + y * 668265263 + 1442695040);
h = (h ^ (h >> 13)) * 1274126177u;
return ((h ^ (h >> 16)) & 0xFFFFFF) / (float)0xFFFFFF;
}
}