StageBlend: report renderers, not just materials — one material covers the whole stage
The log said "1 of 31 materials corrected" and that read like a one-off fix for one lamp, which prompted the reasonable question of why far more than one lamp got better. The count was right and the unit was wrong. Materials are heavily shared here: roughly 1500 renderers across live10149 draw from 31 unique materials. The single corrected one, mtl_env_live10149_blinklight000 on LightBlinkBlend, is the blink-light material for the entire stage — it appears in all 27 BlinkLight groups, about 1450 renderers: audience_light 95, mob000 570, glow_object 67, glow_ramp 58, the mirror ball flare quads 83, every wash group, and the LED panels. So the same fix that cleared the ground wash wedges is also why the small bulbs stopped rendering as black blocks, which had been sitting in LIVE_TRACKS.md as an unexplained symptom. The log now counts affected renderers alongside materials and prints the per-material tally, so the blast radius is legible without cross-referencing the BlinkLight lines by hand. Both docs are corrected in the same pass. The earlier note narrowed the claim correctly — only materials whose current shader declares the property are touched — but by leading with "only 1" it understated the result in the other direction. That is three scope misstatements about this one fix in a day, so the rule now sits next to it: report the unit that matches the question being asked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzXXkLzVC8pNA3JjyUGMbq
This commit is contained in:
@@ -145,13 +145,23 @@ namespace Gallop.Live
|
||||
private void RestoreAuthoredBlendState()
|
||||
{
|
||||
var done = new HashSet<Material>();
|
||||
var fixedMats = new Dictionary<Material, string>();
|
||||
var changed = new List<string>();
|
||||
// 材质在舞台上高度共享(live10149:约 1500 个渲染器只有 31 个材质),
|
||||
// 所以只报材质数会把影响面说小几个数量级 —— 一个 blinklight 材质就铺满整个舞台的灯。
|
||||
// 顺带记渲染器数,日志才说得清「改了 1 个材质」到底意味着什么。
|
||||
var rendererCount = new Dictionary<Material, int>();
|
||||
|
||||
foreach (var r in GetComponentsInChildren<Renderer>(true))
|
||||
{
|
||||
foreach (var mat in r.sharedMaterials)
|
||||
{
|
||||
if (mat == null || mat.shader == null || !done.Add(mat)) continue;
|
||||
if (mat == null || mat.shader == null) continue;
|
||||
|
||||
rendererCount.TryGetValue(mat, out int n);
|
||||
rendererCount[mat] = n + 1;
|
||||
|
||||
if (!done.Add(mat)) continue;
|
||||
|
||||
string before = null, after = null;
|
||||
foreach (string prop in kBlendProps)
|
||||
@@ -166,18 +176,27 @@ namespace Gallop.Live
|
||||
}
|
||||
|
||||
if (after != null)
|
||||
changed.Add($"{mat.name}[{mat.shader.name}] {before}→ {after}");
|
||||
fixedMats.Add(mat, $"{mat.name}[{mat.shader.name}] {before}→ {after}");
|
||||
}
|
||||
}
|
||||
|
||||
if (changed.Count == 0)
|
||||
if (fixedMats.Count == 0)
|
||||
{
|
||||
Debug.Log($"[StageBlend] {done.Count} 个材质的混合状态与 shader 声明一致,无需修正");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[StageBlend] {changed.Count}/{done.Count} 个材质的 _SrcBlend/_DstBlend 与 shader 声明不符," +
|
||||
$"已恢复成 shader 的默认值:\n " + string.Join("\n ", changed));
|
||||
int affected = 0;
|
||||
foreach (var kv in fixedMats)
|
||||
{
|
||||
rendererCount.TryGetValue(kv.Key, out int n);
|
||||
affected += n;
|
||||
changed.Add($"{kv.Value}({n} 个渲染器)");
|
||||
}
|
||||
|
||||
Debug.Log($"[StageBlend] {fixedMats.Count}/{done.Count} 个材质的 _SrcBlend/_DstBlend 与 shader 声明不符," +
|
||||
$"已恢复成 shader 的默认值 —— 共影响 **{affected}** 个渲染器:\n " +
|
||||
string.Join("\n ", changed));
|
||||
}
|
||||
|
||||
private static readonly string[] kBlendProps = { "_SrcBlend", "_DstBlend" };
|
||||
|
||||
@@ -127,8 +127,14 @@ pf = obj.read_typetree()["m_ParsedForm"] # m_Name, m_PropInfo.m_Props
|
||||
⚠️ **实际受害面比存档表窄得多,别照着 26 这个数推。** 只有**当前 shader 真的声明了**这两个
|
||||
属性的材质才会被读到;其余材质虽然也存着 `One/Zero`,但那只是过期条目,无人问津。
|
||||
live10149 实测(`[StageBlend]` 日志):31 个材质里**只有 1 个**被修正 ——
|
||||
`mtl_env_live10149_blinklight000` / `LightBlinkBlend`,`_DstBlend` 0 → 1,
|
||||
正是地面 wash 灯那批黑楔子。修完实机确认恢复正常。
|
||||
`mtl_env_live10149_blinklight000` / `LightBlinkBlend`,`_DstBlend` 0 → 1。
|
||||
|
||||
**但「1 个材质」严重低估了影响面 —— 材质在舞台上是高度共享的。** 那一个材质铺满
|
||||
27 个 BlinkLight 组、约 **1450 个渲染器**(观众席 95、mob000 570、glow_object 67、
|
||||
glow_ramp 58、镜面球闪片 83、全部 wash 组、各种 LED 板),实机确认修好的不只是地面 wash 灯的
|
||||
黑楔子,长期挂着的「小灯泡渲染成黑块」也一并正常了。
|
||||
**教训(第三次同一天):报数要报对单位。** 舞台上约 1500 个渲染器只有 31 个材质,
|
||||
按材质计数会把影响面说小两个数量级 —— `[StageBlend]` 日志现在同时报渲染器数。
|
||||
`StageController.RestoreAuthoredBlendState()` 在舞台初始化时把这两个属性写回 **shader 声明的
|
||||
默认值**(`Shader.GetPropertyDefaultFloatValue`),对本来就该不透明的 shader 是空操作,自限。
|
||||
改了哪些材质会逐条打进 `[StageBlend]` 日志。
|
||||
|
||||
+1
-1
@@ -249,7 +249,7 @@ Unity 的 playAutomatically 播的是默认 clip,为空就什么都不播 —
|
||||
| 现象 | 状态 |
|
||||
|---|---|
|
||||
| 舞台地板长期偏亮发白 | ✅ 2026-08-06 解决。**白的不是文档里记的那三个物件** —— 是与 `plane_000` 同位同尺度、叠在一起的 `mirror_a`(同在 `pfb_env_live10149_main000` 下,局部变换全为单位)。它用 `Cygames/MirrorAndShadow/ReceiveMirror`,`_ReflectionRate` 默认 1.0 而 `_ReflectionTex` 从没赋值,Unity 对未绑定采样器代入白贴图 = 满强度白反射。实现 `Gallop.MirrorReflection` 接上反射 RT 后恢复正常。**教训见 `CLAUDE.md`「现象描述不是 ground truth」**:整轮排查都围着文档里那三个名字转,那个「`_EnvRate` 归零无变化」的实验切的是另一批物件 |
|
||||
| 小灯泡渲染成黑块 / 光柱变实心黑墙 | 🔧 2026-08-07 **找到根因并已修**(待实机确认):Gallop 发光类 shader 的混合状态写作 `Blend [_SrcBlend] [_DstBlend]`,从材质属性读;而 live10149 **26/26 个材质**都被盖上了 URP Lit 的属性表,`_DstBlend` 是 URP Lit 不透明预设的 Zero。全库 16 个声明该属性的 shader 里 **14 个作者默认是 One/One(加法)**,于是**凡是当前 shader 真读这两个属性的**光柱/闪光/投影都被按不透明画 —— 加法下「颜色为黑=不可见」变成了「实心黑墙」。`StageController.RestoreAuthoredBlendState()` 已把这两个属性恢复成 shader 声明的默认值,**实机确认修复**。⚠ 受害面比存档表窄:live10149 实测 31 个材质里只有 1 个真被读到并修正(`mtl_env_live10149_blinklight000` / `LightBlinkBlend`,`_DstBlend` 0→1),其余材质存的是无人问津的过期条目 —— 别拿 26/26 这个数推广。**注**:`StageTransmittedLightMask`/`StageMirrorBallShine` 无颜色属性是另一回事,仍未解 |
|
||||
| 小灯泡渲染成黑块 / 光柱变实心黑墙 | 🔧 2026-08-07 **找到根因并已修**(待实机确认):Gallop 发光类 shader 的混合状态写作 `Blend [_SrcBlend] [_DstBlend]`,从材质属性读;而 live10149 **26/26 个材质**都被盖上了 URP Lit 的属性表,`_DstBlend` 是 URP Lit 不透明预设的 Zero。全库 16 个声明该属性的 shader 里 **14 个作者默认是 One/One(加法)**,于是**凡是当前 shader 真读这两个属性的**光柱/闪光/投影都被按不透明画 —— 加法下「颜色为黑=不可见」变成了「实心黑墙」。`StageController.RestoreAuthoredBlendState()` 已把这两个属性恢复成 shader 声明的默认值,**实机确认修复**。⚠ 两个方向都别照抄数字:**受害材质**比存档表窄(31 个里只有 1 个真被 shader 读到 —— `mtl_env_live10149_blinklight000` / `LightBlinkBlend`,`_DstBlend` 0→1,其余存的是无人问津的过期条目);但**受害渲染器**远比「1 个材质」多 —— 材质高度共享,那一个铺满 27 个 BlinkLight 组约 1450 个渲染器,所以「小灯泡渲染成黑块」和地面 wash 黑楔子是同一个根因,实机确认一并修好。**注**:`StageTransmittedLightMask`/`StageMirrorBallShine` 无颜色属性是另一回事,仍未解 |
|
||||
| LED 大屏黑屏 | MonitorControl (10) 未实现,见上 |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user