MARTINI: Real-Time RTIN Terrain Mesh | Fred Lu | Observable
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
ojs
Author
Fred Lu
@metaclass
Comments (17)
Fred Lu
Jan 12, 2023
RTIN算法适用于大小为(2k+1)×(2k+1)的网格,这就是为什么我们在右侧和底部添加1像素边界。在交互式地图上,该属性还可以帮助我们将瓷砖拼接在一起,以实现无缝地形。
Reply
Fred Lu
Jan 12, 2023
然后我们将其解码为以米为单位的高度值网格:
Reply
Fred Lu
Jan 12, 2023
让我们从Mapbox Terrain RGB 256×256光栅图块中获取高程数据示例:
Reply
Fred Lu
Jan 12, 2023
生成RTIN层次结构 RTIN算法生成一个误差图——一个误差值网格,它将通过指示是否在中间分割某个三角形(给定该三角形在该位置的高度错误值)来指导后续的网格检索。它看起来像这样:
Reply
Fred Lu
Jan 12, 2023
其想法是从最小三角形开始,计算每个三角形的近似误差,然后将该误差传播到父三角形(跟踪最大误差),重复该过程,直到我们到达顶部的两个三角形并获得完整的误差图。 我们从子三角形累积误差的方式使生成的网格共形-这意味着没有T形连接,因此网格中没有间隙。 该算法的计算复杂度为O(numPixels),只需40行代码,在我的笔记本电脑上运行大约20毫秒:
Reply
Fred Lu
Jan 12, 2023
检索网格 为了从RTIN层次结构中检索网格,我们从两个大三角形开始,当它们不能根据误差图很好地逼近底层曲面时,递归地细分它们。这本质上是在三角形的隐式二叉树中进行的深度优先搜索,需要O(numTriangles)步,从而几乎立即生成网格。 以下是100米错误的网格检索可视化:
Reply
Fred Lu
Jan 12, 2023
下面是更新笔记本顶部实际三维地形可视化网格的代码:
Reply
Fred Lu
Jan 12, 2023
注意,出于演示的目的,我们在开始时分配了最大可能的顶点/索引缓冲区,并且仅在精度变化时更新索引数组和绘图范围;在现实世界的应用程序中,方法会有所不同,因为我们不需要经常更新平铺的网格,而是只上传网格中使用的顶点和索引,从而减少GPU的负载。 这反映在实际的库中,其中网格检索例程生成仅在该网格中使用的顶点数组(避免重复顶点),以及引用它的三角形。 谢谢 感谢您的阅读!欢迎在Twitter上与我联系,提出意见和问题,查看存储库(这是一项正在进行的工作),并在我们探索3D空间时继续关注更多精彩内容! P.S.最初我把这个项目命名为MARTIN,完全忘记了还有一个与Mapbox相关的开源项目同名!在让自己难堪之后,我不得不匆忙地把这个改名为MARTINI,以挽回面子。😅
Reply
Fred Lu
Jan 12, 2023
地形夸张倍数
Reply
Fred Lu
Jan 12, 2023
每像素米
Fred Lu
Jan 13, 2023
这段代码实现了计算地图中的每个像素的米数。首先,使用解构赋值从tileCoord中获取瓦片坐标的z、x、y值。然后,使用 Math.pow(2, z) 计算瓦片总数。接着,使用2个反三角函数计算纬度。最后,通过将赤道周长乘以纬度对应的纬度系数,并除以瓦片总数和瓦片大小,来计算每个像素的米数。
Reply
Fred Lu
Jan 12, 2023
出于演示的目的,我们以三角形清晰可见的方式渲染上面的三维视图,但如果有适当的照明和阴影,地形看起来会很平滑。此外,它被夸大了1.5倍,以使其更加突出。
Reply
Fred Lu
Jan 12, 2023
MARTINI:实时RTIN地形网格 要渲染三维地形,需要一个三角形网格-一组表示曲面的三维三角形。从高度数据中获取一个最简单的方法是统一网格(每个像素两个三角形),但这需要很多三角形。为了快速渲染,我们希望通过使网格适应曲面来减少这一数量——在相对平滑的区域使用较大的三角形,在有大量细节的区域使用较小的三角形。
Jan 12, 2023
Will Evans等人在1997年提出的一种这样的方法被称为右三角不规则网络(RTIN)。RTIN网格仅由直角三角形组成,这使其精度低于基于Delaunay的TIN网格,需要更多三角形来逼近同一曲面。但RTIN有两大优势: 该算法生成了一个包含不同精度的所有近似值的层次结构-运行一次后,您可以快速检索任何给定细节级别的网格。 它速度非常快,使得客户端可以从光栅地形块进行网格划分。令人惊讶的是,我以前没有在浏览器中尝试过这样做。
Jan 12, 2023
因此,让我向您展示一个客户端地形网格生成代码,我称之为MARTINI:Mapbox的真棒右三角形不规则网络改进!
它将作为开源库存在于github.com/mapbox/martini。
拖动并缩放下面的地形可视化,然后拖动滑块以实时调整网格精度。然后我们将深入了解这是如何工作的。
Reply
Fred Lu
Jan 13, 2023
这段代码的主要作用是计算一个地形数组中每个位置的错误值。 创建一个新的浮点数数组,用于存储错误值。 计算最小三角形的数量,所有三角形的数量,以及最后一级三角形的索引。 从最小级别开始遍历所有可能的三角形。 使用三角形在隐式二叉树中的索引获取三角形坐标。 计算三角形长边中间点的错误值。 如果三角形是最小三角形,将错误值存储在数组中。 如果三角形是更大的三角形,则将错误值与子三角形的错误值取最大值存储在数组中。 返回错误值数组。
Jan 13, 2023
这段代码中的错误值或误差值是指每个位置上的地形高度值与其周围三角形中点的插值高度值之间的差值。这段代码通过遍历所有三角形并计算每个三角形中点的误差值来计算整个地形数组中每个位置的误差值。
Reply
Add comment
Subscribe to notifications
© 2026 Observable, Inc.
Terms of service
Privacy policy
Product
About
Pricing
Documentation
Release notes
Contact us
Open source
Notebook Kit
Plot
D3
Community
Explore
Forum
Bluesky
YouTube
X
0
Follow
Follow
MARTINI: Real-Time RTIN Terrain Mesh | Fred Lu | Observable