当前位置: 首页 > news >正文

【Virtual Globe 渲染技术笔记】8 顶点变换精度

顶点变换精度

考虑一个简单的场景:原点处一个点,以及两个三角形,都位于平面 x = 0,间距 1 m(图 8.1(a)(a)(a))。
当相机拉近时,我们期望它们看起来共面(图 8.1(b)(b)(b))。
如果把它们平移到 x = 6 378 137 m(地球赤道半径),再拉近,就会出现抖动(jitter):点和三角形不再共面,而是在视图中“蹦跳”(图 8.1(c)(c)(c))。
抖动源于 32 位浮点数对大数值(如 6 378 137)精度不足。由于 WGS84 坐标通常也是这种量级,抖动成为虚拟地球必须解决的问题。
在这里插入图片描述

请添加图片描述

8.1 抖动解释

8.1.1 浮点舍入误差
  • 32 位单精度约 7 位十进制有效数字;64 位双精度约 16 位。
  • 大数值之间的可表示间隔变大,如 17 000 000 m 附近,相邻数相差 2 m。
  • 大、小数相加时,小数会丢失低位精度,误差累积。
8.1.2 抖动的根本原因

以点 (6 378 137, 0, 0) 为例,当相机距其 800 m 时,视图矩阵 V 与投影矩阵 P 的乘积 MVP 第四列会出现极大数值。
MVP=(2.171.770.00−13844652.950.76−0.943.53−4867968.95−0.600.730.323810548.18−0.600.730.323810548.19)\mathbf{MVP} = \begin{pmatrix} 2.17 & 1.77 & 0.00 & -13844652.95 \\ 0.76 & -0.94 & 3.53 & -4867968.95 \\ -0.60 & 0.73 & 0.32 & 3810548.18 \\ -0.60 & 0.73 & 0.32 & 3810548.19 \end{pmatrix}MVP=2.170.760.600.601.770.940.730.730.003.530.320.3213844652.954867968.953810548.183810548.19
CPU 用 64 位计算 MVP,但传入顶点着色器时转为 32 位,导致舍入误差。顶点着色器再用 32 位 MVP 乘以顶点坐标,误差放大,最终使裁剪坐标出现抖动。
抖动视距相关

  • 拉近时,像素对应世界空间尺寸小,误差>1 像素,可见;
  • 拉远时,像素覆盖大区域,误差<1 像素,不可见。

8.1.3 坐标缩放为何无效

把坐标整体缩小 637837 倍,虽让数值靠近 1,但所需精度也同步缩小;32 位浮点间距仍无法满足厘米级要求,抖动依旧。


8.2 相对于中心(RTC)

思路:把几何体顶点转成以自身包围盒中心为原点的小坐标,再在 CPU 用 64 位重新计算 MV 的平移列。

  1. 计算包围盒中心 centerWGS84
  2. CPU 用 64 位求 centerEye = MV * centerWGS84
  3. 构造 MV_RTC,把 MV 第四列改为 centerEye
  4. 传入顶点着色器的顶点坐标为 p_local = p_WGS84 - centerWGS84

优点:

  • 顶点坐标、矩阵平移值都很小,32 位足够;
  • 代码仅几行,CPU 开销低。

缺点:

  • 适用于尺寸 ≤ 131 km(1 cm 精度) 的对象;
  • 大型对象需拆分为多个中心,增加 Draw Call。

8.3 CPU 相对于眼(CPU RTE)

思路:所有顶点以相机眼为原点,CPU 每帧用 64 位计算:

p_RTE = p_WGS84 - eyeWGS84

然后以 32 位写入动态顶点缓冲

实现:

  • MV 平移列清零得 MV_RTE
  • 每帧更新全部顶点(静态对象也“动”了);
  • 其他属性仍可用静态缓冲。

优点:

  • 精度最高,无尺寸限制;
  • 所有对象共享同一 MV_RTE,批处理友好。

缺点:

  • 每帧 CPU 需遍历所有顶点,显存/总线负担大;
  • 静态对象失去静态缓冲优势。

8.4 GPU 相对于眼(GPU RTE)

思路:把 64 位坐标编码为两个 32 位浮点(high/low),在顶点着色器里完成 p_RTE = p_high - eye_high + p_low - eye_low,避免 CPU 每帧重算。

8.4.1 精度与实现
  • Ohlarik 编码

    • high:39 位整数 + 16 位步进;
    • low:7 位小数。
      误差 < 1.35 cm,足够虚拟地球。
  • DSFUN90 编码(Knuth):

    • high = float§;
    • low = p - float§。
      精度接近真 64 位,但顶点着色器指令更多(8 减 4 加)。
8.4.2 精度 LOD(Precision LOD)
  • 远视角:仅使用 high(RTW(Reative to World) 方式),节省一半顶点内存;
  • 近视角:同时用 high+low(DSFUN90),提供全精度;
  • 可动态创建 low 缓冲,按需节省显存。

8.5 推荐方案

场景推荐算法
通用、静态几何GPU RTE DSFUN90(简单、无抖动)
小模型/建筑 (<131 km)RTC(内存省一半)
高度动态几何CPU RTE(CPU 已频繁更新,额外开销小)
大静态几何GPU RTE DSFUN90(避免 RTC 拆分)
混合策略远 RTC + 近 GPU RTE(或 Precision LOD)

Patrick 的反思:
早期 STK 用 CPU RTE;2008 年为利用 GPU 并行,改 GPU RTE。
曾尝试 RTC/GPU RTE 混合,因拆分逻辑复杂,最终倾向统一 GPU RTE,以代码简洁优先。


结论

  • 抖动根源:32 位浮点在大坐标、近距离下精度不足;
  • 解决手段:把顶点或矩阵“变小”——RTC、CPU RTE、GPU RTE 均围绕这一点;
  • 选择依据:对象尺寸、动态性、内存预算、开发复杂度。
http://www.lryc.cn/news/623424.html

相关文章:

  • p5.js 3D 形状 “预制工厂“——buildGeometry ()
  • 积鼎科技CFD VirtualFlow:引领国产多相流仿真技术,赋能工业智造
  • 6.Ansible自动化之-管理变量和事实
  • 使用vscode的task.json来自动执行make命令,而不直接使用终端
  • 智能化管理:开启海洋牧场新时代
  • Excel 表格数据自动填充
  • C++算法竞赛:位运算
  • Android 组件封装实践:从解耦到架构演进
  • 工作中使用到的 TRPS 【Temporal Residual Pattern Similarity】和 K-sigma 算法
  • 知识点汇集-web
  • Spring 源码学习(十一)—— webmvc 配置
  • 项目发布上线清单
  • 如何在Windows系统中更改用户名(中文转英文全流程)
  • LeetCode 837.新 21 点:动态规划+滑动窗口
  • 【运维进阶】实施任务控制
  • C语言---第一个C语言程序
  • 12.web api 3
  • 网格布局 CSS Grid
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day6
  • k8s集群搭建一主多从的jenkins集群
  • 锂电池SOH预测 | Matlab基于KPCA-PLO-Transformer-LSTM的的锂电池健康状态估计(锂电池SOH预测),附锂电池最新文章汇集
  • 网络原理与编程实战:从 TCP/IP 到 HTTP/HTTPS
  • 《详解 C++ Date 类的设计与实现:从运算符重载到功能测试》
  • KingbaseES:一体化架构与多层防护,支撑业务的持续稳定运行与扩展
  • Manus AI 与多语言手写识别技术剖析
  • 整体设计 之“凝聚式中心点”原型 --整除:智能合约和DBMS的深层联合 之1
  • 第三十九天(WebPack构建打包Mode映射DevTool源码泄漏识别还原)
  • 大模型提示词(Prompt)终极指南:从原理到实战,让AI输出质量提升300%
  • 朝花夕拾(四) --------python中的os库全指南
  • 《算法导论》第 27 章 - 多线程算法