← ALL NOTES
METHOD·2026.09·5 MIN READ
3D 场景中触屏放大镜的局部渲染设计
3d-visualization3d-design
问题

在 3D 场景里做"手指按住时局部放大"的放大镜,最直觉的做法是截取当前画面,再把这张截图用 CSS 放大显示在手指上方。

这个方法在普通 2D 界面里没问题,但放到有透视关系的 3D 场景里,会产生一个根本问题:截图放大只是在放大已经渲染好的像素,并没有重新计算相机投影。近大远小的关系不会随着"视点变近"重新生成,因此放大后的内容更像被拉伸,而不是从更近的位置重新看一遍场景。

我之前在一个测量复制 demo 里遇到过这个问题。触屏端长按并拖动测量项的端点或数字标签时,需要在手指上方显示一个圆形放大镜,把局部场景放大约 1.3 倍,帮助用户判断端点最终落在哪里。

这次的功能范围也提前做了限制:放大镜只重新渲染 Three.js 场景中的模型、线段和端点,不包含数字标签等 HTML 浮层。后者是独立 DOM,如果也要进入放大镜,需要重新复制并映射到另一套局部坐标系,成本明显更高,而当前任务并不依赖它。

局部重新渲染

最终没有采用截图缩放,而是使用相机的 setViewOffset(),让同一个 Three.js 场景以同一套相机参数重新渲染触摸点附近的一小块区域。

拖拽过程中,每一帧大致做四件事:

  1. 以当前触摸点为中心,计算主画布中的局部裁剪区域;
  2. 把这块区域传给 setViewOffset(),并更新投影矩阵;
  3. 使用同一个 scene 和 camera,把这块局部画面渲染到一个约 140 x 140px 的独立小画布;
  4. 渲染完成后立即清除 View Offset,并恢复投影矩阵,避免影响主画面的下一帧。

小画布外层再用圆形容器裁切,加白色描边、阴影和中心准星,并整体放在触摸点上方,避开手指遮挡。

这里最关键的是:放大镜里的内容不是主画面的像素副本,而是同一个 3D 场景经过同一套相机投影重新计算后的局部结果。 因此模型边缘、端点和空间关系仍然保持原来的透视逻辑。

宽高比必须一致

第一版虽然方向是对的,但实际效果仍然出现了明显失真。

当时裁剪区域直接按"主画布宽度 ÷ 1.3、主画布高度 ÷ 1.3"计算。主画布是竖屏长方形,因此裁出来的区域也保持了长方形比例;但放大镜的渲染目标是 140 x 140px 的正方形。

结果就是:一个长方形视口被硬塞进正方形渲染目标,端点和纹理被拉伸,拖拽中的端点甚至会糊成一整块纯色圆形。

修正方式很简单:裁剪区域也改成正方形,用主画布宽高中较小的一边作为基准,再按放大倍率计算裁剪尺寸。这样裁剪视口和渲染目标的宽高比一致,模型边缘、端点和纹理细节都恢复正常。

这个问题说明,局部渲染不仅要关心"放大多少",还要保证:源视口的宽高比 = 目标渲染区域的宽高比。

否则即使相机投影本身没有问题,最后一步仍然会因为二维映射关系不一致而变形。

只在触屏路径创建

这个放大镜只服务于触屏拖拽,因此没有放进通用输入逻辑里。

触屏操作进入长按拖拽后才创建和显示对应的放大镜资源;鼠标路径不会调用这套逻辑,桌面端也不会额外创建对应 DOM 和 WebGL 渲染目标。

这里的判断不是"每帧检查当前是不是桌面端",而是在输入路径一开始就把功能隔开。对于只服务于某一种输入方式的交互,这样可以减少无关状态和额外资源。

功能范围

数字标签没有进入放大镜,是一个提前确定的范围取舍。

Three.js 场景内容可以直接通过相机重新渲染,但 HTML 标签位于另一层 DOM 中。如果也要放大,需要额外处理标签复制、局部坐标映射、遮挡和同步更新。

当前用户真正需要确认的是端点与模型的位置关系,而不是读取标签文字,因此没有为了视觉上的"全部都被放大"增加这一层复杂度。

这个范围是在实现前就和需求方确认的。对这类跨 WebGL 与 DOM 的功能来说,先明确哪些内容必须进入效果范围,比做到中途再因为实现成本过高而缩减范围更稳妥。

经验总结
  1. 3D 局部放大优先重新渲染,而不是放大截图。 如果用户需要的是"看得更近",就应该重新走相机投影,而不是二次缩放已经生成的像素。
  2. 局部视口和目标容器必须保持同一宽高比。 投影正确并不代表最终显示一定正确,二维映射关系仍然会影响结果。
  3. 只在需要的输入路径创建功能。 触屏专用交互没有必要长期存在于桌面端的资源和状态里。
  4. 跨 WebGL / DOM 的效果先明确范围。 是否把 HTML 标签也纳入放大镜,应根据真实任务价值决定,而不是追求视觉上的绝对完整。
关于原型验证

这次技术方案主要由 Claude Code 提供,我负责确认它是否符合实际设计目标,以及在真机上验证最终效果。

真正暴露问题的不是方向选择,而是具体比例。第一版已经用了正确的局部渲染方案,但裁剪框和目标画布宽高比不一致,依然导致明显失真。

这类 3D UI 问题很适合用可运行原型验证:技术路径可以先判断是否合理,但尺寸、比例和实际触屏视觉效果,仍然需要让它真正跑起来再确认。

CONTINUE READING
从 Figma 组件属性到代码 Props2026.09Figma 设计系统的工程化落地2026.09