动画与时序
GPU 动画的一帧是 CPU 场景更新 → 上传脏资源 → draw* / submit →(可选)读回。requestAnimationFrame 只保证尽量跟着 vsync;着色器编译、全屏 readPixels、toDataURL 都会把这一帧预算打穿。
循环仍只驱动 场景状态。绘制是 submit(scene, t),不是在 rAF 里拼 GLSL。时间基准、暂停、后台夹紧 dt 与 Canvas rAF 同一套;换掉的是提交物。
文档清单
| 文档 | 解决的问题 |
|---|---|
| rAF 与提交 | 一帧顺序;禁止热路径 compileShader;脏 buffer |
| 丢失上下文与恢复 | preventDefault、资源表、WEBGL_lose_context、device.lost |
先立三条
- 一帧只提交,不编译。
compileShader/linkProgram/createRenderPipeline放启动、热更新或恢复路径。rAF 里做等于主动掉帧。 preserveDrawingBuffer默认false。 合成后默认 drawing buffer 可被清空。readPixels发生在同一帧提交之后、合成之前,或对着 FBO。不要为了「随时截图」打开 preserve。- 丢失是产品路径。
webglcontextlost后全部 GL 对象作废;WebGPU 等device.lost。句柄当永活,白屏。细节见 01 生命周期。
适用 / 不适用
| 适用 | 不适用 |
|---|---|
| 粒子、相机、实例属性每帧变 | 图标呼吸、少量 DOM 高亮——走 SVG / CSS |
| 脏 buffer 上传 + 合批 draw | 每帧 texImage2D 整张 4K、每帧编译变体 |
| 丢失后按资源表重建再继续 rAF | 假设切后台 / 切显示器 program 还在 |
失败形态
| 症状 | 原因 |
|---|---|
| 切回标签页瞬移 | dt 未夹紧,同 Canvas |
| 首几秒卡、之后稳 | 把 shader 编译塞进了第一帧 rAF |
| 截图全黑 | 默认不 preserve,读回跨帧 |
| iOS 回来白屏 | 丢失后仍 useProgram(旧句柄) |
核对日期:2026-08-26