呈现高度精细的 "zoomed out" 数据
Rendering highly granular and "zoomed out" data
网上有一张gif,有人用某种CAD在里面画了多张矢量图。在第一帧,他们放大了一个小点,以不同的比例显示了一张全新的不同矢量图,然后他们进一步放大了另一个小点,显示了另一张详细的图片,重复了几次。 here is the link to the gif
或者另一个类似的例子:假设你有一个时间序列,每个样本的粒度为毫秒,你缩小以显示多年的数据。
我的问题是:当大量数据最终混叠成单个像素时,最终如何呈现如此精细的数据。
您是否必须遍历整个数据集才能渲染该像素(即在时间序列的情况下:遍历百万条记录以将它们平均成一行,或者在 CAD 的情况下渲染整个矢量图并将其模糊成小点) ,或者可以应用某些细节级别的优化,这样您就不必这样做了?
如果是这样,它们是如何工作的,在哪里可以了解它?
首先,你可以使用缓存。使用瓷砖,就像在制图中所做的那样。您仍然需要遍历所有要点,但之后您将能够 zoom-in/zoom-out 相当快。
但是如果你没有额外的缓存内存(实际上没有那么多,比数据本身少得多),或者没有时间检查所有的点你可以使用概率方法。
它可以像每隔一个点(或每 10 个点或任何适合你的东西)偷看一样简单。它为 一些数据 产生了不错的结果。同样在制图学中,它对海岸线很有效,但对房屋或行政边界不太适用——任何有很多直线的东西。
或者您可以采用更硬核的概率方法:随机查看一些点,例如,如果有 100 个数据点命中 pixel one
而只有 50 个命中 pixel two
,那么你可以或多或少安全地假设,如果你继续偷看点,仍然 pixel one
被击中的可能性是 pixel two
的两倍。所以你可以放弃并用两倍 重 颜色绘制 pixel one
。
还要考虑您可以并希望在一个像素中放入多少数据。如果你用黑白绘制一个像素,那么只有 256 种颜色。而且你不需要更精确。或者,如果您要绘制全彩色像素,那么您仍然需要问自己:有人会注意到 rgb(123,12,54)
和 rgb(123,11,54)
之间的区别吗?
这是游戏开发中一个众所周知的问题。在下文中,我假设您使用的是场景图,一种基于节点的对象树。
典型的解决方案涉及这些技术的组合:
- 细节级别(LOD):同一模型的多个分辨率,显示或隐藏,以便任何时候只有一个“可见”。何时隐藏和显示通常由相机和物体之间的距离决定,但您也可以将物体的比例作为一个因素。现代 3d/CAD 软件有时会为您提供自动“简化”模型,可用作低分辨率 LOD 模型。
在最低级别,您甚至可以只使用对象的边界
盒子。检查边界框是否在视图中仅需大约 1-7 点检查,具体取决于您的检查方式。您可以将对象父子关系用于传递边界框。
裁剪:如果视口中根本没有渲染多边形,则无需渲染。在您发布的 GIF 中,当相机放大新场景时,较大模型留下的是背景中的单个多边形。
世界坐标的重新缩放:当你放大时,顶点的坐标变成零以下的浮点数。如果您希望所有坐标都尽可能精确,并且现代 CPU 只能处理 64 位精度的浮点数(并且通常只使用 32 位以获得更好的性能),那么重置可见对象的缩放比例是个好主意。我的意思是,当你的相机放大到前一个视图的 1/1000 时,你可以将较大的物体放大 1000 倍,同时调整相机位置和焦距。任何新连接的小模型都将使用其原始比例,从而保持其精度。
此过渡对查看者来说是不可见的,但允许您保持在明确定义的 3d 坐标内,同时能够无限放大。
在更高的层次上:当你放大某个东西并且相机离一个物体越来越近时,看起来世界相对于视图变大了。虽然通常相机 space 正在移动并且世界会乘以相机的矩阵,但通过更改世界坐标而不是相机可以实现相同的效果。
网上有一张gif,有人用某种CAD在里面画了多张矢量图。在第一帧,他们放大了一个小点,以不同的比例显示了一张全新的不同矢量图,然后他们进一步放大了另一个小点,显示了另一张详细的图片,重复了几次。 here is the link to the gif
或者另一个类似的例子:假设你有一个时间序列,每个样本的粒度为毫秒,你缩小以显示多年的数据。
我的问题是:当大量数据最终混叠成单个像素时,最终如何呈现如此精细的数据。
您是否必须遍历整个数据集才能渲染该像素(即在时间序列的情况下:遍历百万条记录以将它们平均成一行,或者在 CAD 的情况下渲染整个矢量图并将其模糊成小点) ,或者可以应用某些细节级别的优化,这样您就不必这样做了?
如果是这样,它们是如何工作的,在哪里可以了解它?
首先,你可以使用缓存。使用瓷砖,就像在制图中所做的那样。您仍然需要遍历所有要点,但之后您将能够 zoom-in/zoom-out 相当快。
但是如果你没有额外的缓存内存(实际上没有那么多,比数据本身少得多),或者没有时间检查所有的点你可以使用概率方法。
它可以像每隔一个点(或每 10 个点或任何适合你的东西)偷看一样简单。它为 一些数据 产生了不错的结果。同样在制图学中,它对海岸线很有效,但对房屋或行政边界不太适用——任何有很多直线的东西。
或者您可以采用更硬核的概率方法:随机查看一些点,例如,如果有 100 个数据点命中 pixel one
而只有 50 个命中 pixel two
,那么你可以或多或少安全地假设,如果你继续偷看点,仍然 pixel one
被击中的可能性是 pixel two
的两倍。所以你可以放弃并用两倍 重 颜色绘制 pixel one
。
还要考虑您可以并希望在一个像素中放入多少数据。如果你用黑白绘制一个像素,那么只有 256 种颜色。而且你不需要更精确。或者,如果您要绘制全彩色像素,那么您仍然需要问自己:有人会注意到 rgb(123,12,54)
和 rgb(123,11,54)
之间的区别吗?
这是游戏开发中一个众所周知的问题。在下文中,我假设您使用的是场景图,一种基于节点的对象树。
典型的解决方案涉及这些技术的组合:
- 细节级别(LOD):同一模型的多个分辨率,显示或隐藏,以便任何时候只有一个“可见”。何时隐藏和显示通常由相机和物体之间的距离决定,但您也可以将物体的比例作为一个因素。现代 3d/CAD 软件有时会为您提供自动“简化”模型,可用作低分辨率 LOD 模型。
在最低级别,您甚至可以只使用对象的边界 盒子。检查边界框是否在视图中仅需大约 1-7 点检查,具体取决于您的检查方式。您可以将对象父子关系用于传递边界框。
裁剪:如果视口中根本没有渲染多边形,则无需渲染。在您发布的 GIF 中,当相机放大新场景时,较大模型留下的是背景中的单个多边形。
世界坐标的重新缩放:当你放大时,顶点的坐标变成零以下的浮点数。如果您希望所有坐标都尽可能精确,并且现代 CPU 只能处理 64 位精度的浮点数(并且通常只使用 32 位以获得更好的性能),那么重置可见对象的缩放比例是个好主意。我的意思是,当你的相机放大到前一个视图的 1/1000 时,你可以将较大的物体放大 1000 倍,同时调整相机位置和焦距。任何新连接的小模型都将使用其原始比例,从而保持其精度。 此过渡对查看者来说是不可见的,但允许您保持在明确定义的 3d 坐标内,同时能够无限放大。
在更高的层次上:当你放大某个东西并且相机离一个物体越来越近时,看起来世界相对于视图变大了。虽然通常相机 space 正在移动并且世界会乘以相机的矩阵,但通过更改世界坐标而不是相机可以实现相同的效果。