[性能] 方案 G:着色器与 GL 状态微调(discard / texStorage / uniform 上传)—— 需要实机测量才能定夺 #20
Labels
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Blocks
#16 [性能] 渲染主循环掉到 20 tps:零视口剔除(88.6% 白画)+ 图集页切换导致单帧最高 3077 次 draw call
troytt/diablo2-web
Reference: troytt/diablo2-web#20
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
拆自 #16 的方案 G。这些都是必须靠实机测量才能判断的微优化,静态分析给不出结论,所以单独挂一条。
三个候选
1. 片元着色器里的
discard当前片元着色器用
discard丢弃全透明像素。已知discard会让 GPU 无法使用 early-Z 等快路径,但在这个项目里:discard可能反而省了混合带宽;这两个方向都说得通,必须测。 需要在目标机型上对比「
discard版」与「纯 alpha blend 版」的帧耗时。2. 纹理创建改用
texStorage2D(不可变存储)比
texImage2D系列分配更高效,驱动可以提前定下完整的分配计划。收益不大但代价也极低,属于顺手就能做的。注意:现在的图集页是 2048 宽、高度各异的单层纹理,改成不可变存储后就不能再 resize,需要确认没有别处依赖可变尺寸。3. flush 里的 uniform 上传
相机相关的几个 uniform 每帧只变一次,但现在每次 flush 都传。A→C 之后 flush 一帧通常只有 1 次,所以这条现在几乎没有收益了 —— 只有在超出纹理单元预算而断批的少数关卡(实测 365 关里没有,最多 10 个页 < 16 个单元)才会多传。建议连带确认后直接划掉,除非以后批次数重新上去。
为什么现在做不了
cloudtop 上没有真实 GPU,headless 环境测出来的帧耗时没有参考价值。这条需要:
scripts/browser/checks/加一个稳定的帧耗时采集口径(连续 120 帧的 p50/p95);建议优先级
P2。先把 #F(模拟与渲染解耦)做完,把"渲染耗时"和"模拟 tps"彻底分开,这些微优化的测量才有意义 —— 否则测出来的差异会被 rAF 耦合污染。
方案 G(着色器与 GL 状态微调)修复完成并验证通过
fix/issue-2011e2e42731f4a8bedcb7c88a9a37ba7ac6cd1af5texStorage2D): 在 WebGL2 环境下将所有纹理(图集、白色基底、调色板、单通道索引图集)升级为gl.texStorage2D分配不可变显存布局,结合gl.texSubImage2D上传像素,消除了动态重分配开销,并保留对不支持环境的安全 fallback;SpriteRenderer中缓存相机、视口尺寸与缩放倍率,flush()中仅在参数发生变化时发起 GL Uniform 调用,彻底消除每帧多批次和连续静止帧的冗余 Uniform 驱动开销;alphaDiscard开关,在保证原版像素级透明判定(默认开启)的同时支持关闭discard走纯 Alpha 混合模式,避免移动端 GPU early-Z / tile 渲染惩罚;tests/renderer-tuning.test.ts,扩展scripts/verify-renderer-lifecycle.ts(65 项校验全绿),npx tsc --noEmit0 报错,全量测试套件全绿。