diff --git a/Assets/WL/Combat/Stage/Barrier/StageBarrierVisual.cs b/Assets/WL/Combat/Stage/Barrier/StageBarrierVisual.cs
index 3b501d3ca..88fc59adc 100644
--- a/Assets/WL/Combat/Stage/Barrier/StageBarrierVisual.cs
+++ b/Assets/WL/Combat/Stage/Barrier/StageBarrierVisual.cs
@@ -153,7 +153,7 @@ namespace WL.Combat.Stage
///
public static int HideImmediate()
{
- int n = s_live.Count;
+ int n = s_live.Count + SweepOrphans();
s_showing = false;
if (n == 0 && s_t <= 0f) return 0;
ApplyPhase(0f);
@@ -162,6 +162,31 @@ namespace WL.Combat.Stage
return n;
}
+ ///
+ /// 2026-09-16 Lead 실측 — 섬에서 보인 울타리·바위 13개는 이번 세션의 장벽이 아니었다(`HasActive=false · Shows=0`).
+ /// 루트가 HideAndDontSave 라 **에디터 Play 종료·도메인 리로드 뒤에도 살아남고**, 정적 참조(s_root)만 끊겨 고아가 된 것.
+ /// 이름이 같은 루트 중 현재 s_root 가 아닌 것을 전부 지운다(Play 시작 시·섬 진입 시·즉시 숨김 때).
+ ///
+ public static int SweepOrphans()
+ {
+ int n = 0;
+ var all = Resources.FindObjectsOfTypeAll();
+ for (int i = 0; i < all.Length; i++)
+ {
+ var t = all[i];
+ if (t == null || t.parent != null || t.name != "[WL815c] StageBarrierVisual") continue;
+ if (s_root != null && t == s_root) continue;
+ if (Application.isPlaying) Object.Destroy(t.gameObject); else Object.DestroyImmediate(t.gameObject);
+ n++;
+ }
+ OrphansSwept += n;
+ return n;
+ }
+ public static int OrphansSwept;
+
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
+ static void SweepOnBoot() { s_root = null; SweepOrphans(); }
+
/// 연출 진행. StageBarrier.Tick 이 부른다.
internal static void Tick(WLStageBarrierSettings cfg)
{
diff --git a/Assets/WL/Look/Farm/WLDemoTerrain.cs b/Assets/WL/Look/Farm/WLDemoTerrain.cs
index db2897cd1..d9d486990 100644
--- a/Assets/WL/Look/Farm/WLDemoTerrain.cs
+++ b/Assets/WL/Look/Farm/WLDemoTerrain.cs
@@ -478,7 +478,8 @@ namespace WL.Look.Farm
// 🔴 2026-09-16 PD 「상인 생성 때 맵이 잠시 사라진 것처럼 보임」 — 같은 값을 다시 대입해도 Terrain 이 내부 상태를 다시 만들어 한 프레임 비는 것을 막는다(바뀔 때만 대입).
if (_terrain.terrainData != _data) _terrain.terrainData = _data;
- if (_terrain.materialTemplate != cfg.demoTerrainMaterial) _terrain.materialTemplate = cfg.demoTerrainMaterial; // 데모 Terrain.mat 그대로(값 무수정)
+ var tmat = Tuned(cfg.demoTerrainMaterial); // 데모 Terrain.mat 그대로(값 무수정) · 구름 강도만 섬 크기에 맞춘 런타임 복사본
+ if (_terrain.materialTemplate != tmat) _terrain.materialTemplate = tmat;
if (_terrain.drawInstanced) _terrain.drawInstanced = false; // Demo.unity 1228 m_DrawInstanced 0 · 그 외 Terrain 값은 데모 = 컴포넌트 기본값
if (_terrain.allowAutoConnect) _terrain.allowAutoConnect = false;
}
@@ -537,7 +538,26 @@ namespace WL.Look.Farm
if (mesh == null) { why = label + " 메시 없음(scatter[" + d.scatterIndex + "])"; return null; }
if (demoMat == null) { why = label + " 데모 재질 비어 있음"; return null; }
if (d.scale <= 0f) { why = label + " scale ≤ 0"; return null; }
- return new DemoEntry { Mesh = mesh, Material = demoMat, Probability = d.probability, Scale = d.scale, NormalOffset = d.normalOffset };
+ return new DemoEntry { Mesh = mesh, Material = Tuned(demoMat), Probability = d.probability, Scale = d.scale, NormalOffset = d.normalOffset };
+ }
+
+ // ─────────────────────────────────────────────────────────────────
+ // 2026-09-16 PD 「풀이 얼룩덜룩」 실측(A/B): 데모 원값 `_Cloud_Strength 1.0` 은 200 m 지형에 맞춘 값이라 32 m 섬은 절반이 통째로 50 % 어둡게 덮여
+ // 얼룩처럼 보였다. 원본 재질은 손대지 않고 **런타임 복사본**에 `demoCloudStrength` 만 덮어쓴다(0 이하 = 원본 그대로).
+ // ─────────────────────────────────────────────────────────────────
+ readonly Dictionary _tuned = new Dictionary();
+ Material Tuned(Material src)
+ {
+ if (src == null) return null;
+ if (cfg == null || cfg.demoCloudStrength <= 0f || !src.HasProperty("_Cloud_Strength")) return src;
+ Material m;
+ if (!_tuned.TryGetValue(src, out m) || m == null)
+ {
+ m = new Material(src) { name = src.name + "(WL cloud " + cfg.demoCloudStrength.ToString("F2") + ")", hideFlags = HideFlags.DontSave };
+ _tuned[src] = m;
+ }
+ if (!Mathf.Approximately(m.GetFloat("_Cloud_Strength"), cfg.demoCloudStrength)) m.SetFloat("_Cloud_Strength", cfg.demoCloudStrength);
+ return m;
}
}
}
diff --git a/Assets/WL/Look/Farm/WLIslandLookSettings.cs b/Assets/WL/Look/Farm/WLIslandLookSettings.cs
index 2f0274e0d..3aee9e568 100644
--- a/Assets/WL/Look/Farm/WLIslandLookSettings.cs
+++ b/Assets/WL/Look/Farm/WLIslandLookSettings.cs
@@ -400,6 +400,10 @@ namespace WL.Look.Farm
"타일 윗면 렌더러는 숨긴다(콜라이더 유지 = 걷기·밭·수확 그대로). 0 = 지금 구조 100 % 복귀.")]
public int demoTerrainEnabled = 1;
+ [Tooltip("데모 지형·풀·꽃 재질의 구름 그림자 강도를 이 값으로 덮어쓴 런타임 복사본을 쓴다(원본 무수정). " +
+ "2026-09-16 PD 「풀이 얼룩덜룩」 A/B 실측: 데모 원값 1.0 은 200 m 지형용이라 32 m 섬이 통째로 어두워졌다 → 0.3. 0 이하 = 원본 그대로.")]
+ public float demoCloudStrength = 0.3f;
+
[Tooltip("높이맵 해상도(2ⁿ+1 · 33~4097). 129 = 한 변 128 m 일 때 1 m 간격, 작은 섬이면 더 촘촘해진다.")]
public int terrainHeightRes = 129;