跳到主要内容

小地图与第二视图

小地图是 第二台相机,不是把主 drawing buffer readPixels 缩小贴角落。主视图全屏再缩,等于每帧多付一次全场景光栅,还插入 CPU–GPU 同步。两台相机共享 CPU 世界;GPU 是两份 viewProj 投到两张(或一块 scissor)目标。

1. 场景怎么切

CPU 世界(同一份文档)
├─ 主相机 viewProj → 主 FBO / 默认 FB
└─ 小地图相机 viewProj → 低分辨率 overview FBO
视口框、点击跳转:CPU 把世界 AABB 映到 mini CSS

主相机随便 pan/zoom。小地图相机只在 世界包围盒变了 时重算(地图扩边)。每帧只更新视口框几何,不要重烘概览。

export type Camera2D = { x: number; y: number; scale: number };

export type WorldAabb = { minX: number; minY: number; maxX: number; maxY: number };

export function miniCamera(world: WorldAabb, cssW: number, cssH: number): Camera2D {
const w = Math.max(1e-6, world.maxX - world.minX);
const h = Math.max(1e-6, world.maxY - world.minY);
const scale = Math.max(w / cssW, h / cssH);
const viewW = cssW * scale;
const viewH = cssH * scale;
return {
scale,
x: world.minX - (viewW - w) / 2,
y: world.minY - (viewH - h) / 2,
};
}

export function viewportOnMini(
main: Camera2D,
mini: Camera2D,
mainCssW: number,
mainCssH: number,
): { x: number; y: number; w: number; h: number } {
const a = { x: main.x, y: main.y };
const b = { x: main.x + mainCssW * main.scale, y: main.y + mainCssH * main.scale };
const p1 = { x: (a.x - mini.x) / mini.scale, y: (a.y - mini.y) / mini.scale };
const p2 = { x: (b.x - mini.x) / mini.scale, y: (b.y - mini.y) / mini.scale };
return {
x: Math.min(p1.x, p2.x),
y: Math.min(p1.y, p2.y),
w: Math.abs(p2.x - p1.x),
h: Math.abs(p2.y - p1.y),
};
}

点击:mini CSS → 世界点 → 主相机把该点放到视口中心。矩阵与 相机 同一套,禁止第二套 clientX 换算。

适用:地图/游戏概览、第二正交视图、调试用的自由相机。
不适用:用主缓冲当缩略图源;把小地图当可访问控件却不提供 DOM 替代,见 GPU 无障碍

2. 哪层必须 CPU,哪层进 GPU

归属
世界文档、两台 Camera2D、包围盒CPU
概览 FBO(低清、简化 pass:无粒子、无手柄)GPU 投影
视口框、点击热区DOM / 第二张小 canvas 上的 2D,或 GL 线框
跳转、拖框CPU 改主相机

概览 FBO 尺寸 ≈ mini CSS × dpr,不要等于主 drawingBuffer。静态层节流烘(地图未改就不画)。主 pass 与 mini pass 可以同一上下文里切 viewport/FBO,也可以第二张 <canvas> 各自 webgl2。同一元素不能再要 2d

禁止:readPixels 主缓冲再 texImage2D 缩小;toDataURL 当小地图。读回规则见 读回陷阱。框比小地图还大时夹紧绘制,不要 clip 到点不到。2D 产品对照 Canvas 小地图

3. 失败形态

症状原因
开小地图掉一半帧每帧按主场景全细节重画 mini,或读主缓冲缩小
框和主视图对不上两套世界原点,或一边忘了 letterbox
点击跳转偏一截mini CSS 当了世界,或 Y 没和主相机同约定
导出带小地图框把 chrome 画进了主 FBO
拾取点到 mini 物体命中仍用主 viewProj

权威资料

核对日期:2026-08-26