Skip to content

[Bug]: 三渲二出帧的第 0 帧是纯黑剪影,而所有闸都放它过去 #918

Description

@johnnyzhang-eng

现象

2026-08-29,生产任务 878(待机,12 帧)。逐帧量交付产物:

f00  不透明占比 0.101  主体平均亮度   0.0   ← 纯黑剪影
f01  不透明占比 0.101  主体平均亮度 148.0
f02  不透明占比 0.100  主体平均亮度 148.0
…
f11  不透明占比 0.101  主体平均亮度 145.8

第 0 帧是一个没有贴图的纯黑人形,其余 11 帧正常。

为什么没有任何一道闸拦住

出帧循环有两道自检,两道都放它过去:

  • coverage() 只数 alphadata[i+3] > 8),不看颜色。纯黑剪影的不透明像素占比与正常帧一模一样——实测 0.101 对 0.101。
  • grab() 只判空 blob。纯黑帧是一张体积正常的 PNG。

服务端的 min_coverage 同口径,同样拦不住。所以它一路当成正常产物交付。

根因

BakeStage.load()placeCam() 之后直接返回,渲第一帧之前没有任何 warm-up

const object = await new FBXLoader().loadAsync(url)

loadAsync 在 FBX 解析完就 resolve,而内嵌贴图的解码/上传 GPU 是另一条异步路,没人等它。于是第 0 帧渲出来时着色器与贴图都还没就绪。

(补一条口径更正:此前排查另一批产物时,我把首帧全黑归因为"探针每帧只渲一次、生产渲三次所以不会有"。生产这次证伪了这个说法——三次渲染都发生在同一个 tick 内,贴图仍可能没解码完。)

修法

两道一起:

  1. load() 末尾加 warmUp()——优先 renderer.compileAsync(scene, camera)(three r152+ 起有,本仓 r185),它会把着色器编译与贴图上传都做完;没有该方法时退回同步 compile() + 一次渲染。
  2. 出帧循环加一道亮度闸:主体平均亮度低于 20 判纯黑并当场失败。覆盖率那道只看 alpha,必须有一道看颜色的补上——否则同类问题(材质丢失、着色器编译失败)照样溜过去。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions