Skip to content

Fix disappearing 3D faces at extreme zoom via projected raster sizing - #1516

Draft
skyrimHuang wants to merge 6 commits into
mainfrom
bugfix/skyrimHuang_3D
Draft

Fix disappearing 3D faces at extreme zoom via projected raster sizing#1516
skyrimHuang wants to merge 6 commits into
mainfrom
bugfix/skyrimHuang_3D

Conversation

@skyrimHuang

@skyrimHuang skyrimHuang commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

背景

在极致 zoom 或强透视变换下,3D 场景中的叶层会出现"小方块消失"——某些
face 在渲染时缺失,露出背景或底色。原 PR 用 clamp(raster ≤ 4096)
试图规避这一现象,但只是治标:被 clamp 的纹理 UV 会错位,且 clamp 触发时说明
raster 尺寸已经严重失控。

根本原因

Render3DContext::rasterLayerlocalBounds × contentScale 计算 raster
尺寸,存在两个根源问题:

  1. 缺少可视区域裁剪。叶层实际投影到 compositor viewport 内的可能只是
    一小部分,却按完整 localBounds 分配纹理,导致 zoom 越大浪费越大。
  2. 光栅密度没有对齐叶层自身 3D 变换。密度只乘 contentScale,忽略了
    叶层 3D 变换(尤其透视)对"local 单位 → 屏幕像素"的实际缩放:透视缩小的叶层
    被过采样产生远超视口的纹理(实测 200000×100000+),最终 Surface::Make
    失败返回 null,fragment 无 image → 消失。

方案

将 raster 尺寸从"local × contentScale"改为"投影到 viewport 后的实际覆盖范围":

  1. 齐次多边形裁剪Matrix3DUtils::ComputeVisibleFootprints):把
    localBounds 4 个角通过 3×3 homography 正向投影到 compositor 齐次空间
    (X, Y, W),在未除 W的状态下用 Sutherland-Hodgman 对 5 个平面依次
    裁剪(近相机平面 W > 0 + viewport 4 边)。剩余的多边形顶点分别映射回
    local 空间和 compositor 空间,得到成对的 localFootprint / destFootprint
  2. destFootprint 决定 raster 尺寸——它天然被 viewport 限制,不再失控。
  3. 密度 = destFootprint.size / localFootprint.size——两个都是 clip 后的
    AABB,比值稳定,即使投影贴近近相机平面也不会奇异。
  4. 移除 4096 clamp:根源解决后不再需要 clamp 兜底。

对于走 3D compositor 路径以外的场景(例如 non-preserve3D 或 fallback 到 2D 的
BackgroundBlur 变体),输出保持完全一致;受影响的仅为 6 个真正调用 3D
compositor 的 sub-baseline(见"截图基准"一节)。

变更范围

  • 修改 src/core/Matrix3DUtils.{h,cpp}:新增 ComputeVisibleFootprints
  • 修改 src/layers/compositing3d/Render3DContext.{h,cpp}:重写 raster 尺寸
    与密度的派生逻辑,抽出 ComputeRasterInfo 私有 static 方法
  • src/layers/compositing3d/Context3DCompositor.* 侧改动,UV 映射的
    texSize / localBounds 语义保持一致

截图基准

6 个 sub-baseline 输出改变(3 个 mac 后端一致),需要 /accept-baseline

  • BackgroundBlurTest/BackgroundBlur3DLayer_Nested3D
  • BackgroundBlurTest/BackgroundBlur3DLayer_NestedOffscreen
  • BackgroundBlurTest/BackgroundBlur3DLayer_Preserve3D
  • Hello2DTest/Layer3DTree
  • LayerTest/Contour3DWithDropShadow
  • LayerTest/Matrix_3D_2D_3D_Preserve3D

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Hparty Hparty left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个方向治的是"纹理超限"的标,建议再往下挖一层根因,光栅尺寸本身不合理才是本:

  1. 缺少可视区域裁剪rasterLayer 目前按 localBounds × contentScale 全量光栅化,而叶层实际可见的只是它投影进 compositor 目标的那一小部分。实测 zoom≈783 时,一个 1556×1556 的叶层,可见区域只有 23.6×16.7 个 local 单位——也就是说绝大部分光栅内容从来不上屏。可以看一下 #1432 之前的录制路径是怎么做这个裁剪的(提示:Matrix3DUtils::InverseMapRect),那套语义是验证过的。

  2. 光栅密度没有对齐叶层自身的变换。现在密度只乘了 contentScale(画布 zoom),没考虑叶层 3D 变换(含透视)对"local 单位 → 屏幕像素"的缩放:透视缩小的叶层会按 zoom 全密度光栅化,产生比视口还大的纹理(实测 18472×13099);反过来透视放大的叶层会欠采样变糊。可以想想怎么从叶层的实际投影推导出正确的光栅密度。

这两个根因解决后,光栅尺寸约等于叶层在 compositor 上的投影(≤ 视口),结构上碰不到 GPU 纹理上限,4096 钳制自然就不需要了。另外留一个延伸问题给你分析:compositor 目标本身(Context3DCompositor 按 renderRect 分配)在极端 zoom 下同样可以超限(实测 8313×6294),这层要怎么处理也一起想想。

有不确定的地方欢迎随时找我讨论。

@skyrimHuang
skyrimHuang marked this pull request as draft July 29, 2026 12:36
beiaoHuang and others added 4 commits July 31, 2026 17:07
…e leaf transform to avoid oversized textures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… computation to align with tgfx conventions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ity derivation keep leaf textures within viewport scale.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sity stays finite near the camera plane.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@skyrimHuang
skyrimHuang force-pushed the bugfix/skyrimHuang_3D branch from 6452c89 to ae4def3 Compare July 31, 2026 11:44
@skyrimHuang skyrimHuang changed the title Cap leaf raster scale in 3D contexts to prevent surface dimensions from exceeding GPU texture limits. Fix disappearing 3D faces at extreme zoom via projected raster sizing Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants