4

我正在重写一个基于 opengl 的 gis/mapping 程序。除其他外,该程序允许您加载海图的光栅图像,将它们固定到 lon/lat 坐标并在它们上缩放和平移。

该程序的先前版本使用自定义平铺系统,实质上它手动创建原始图像的 mipmap,以 256x256 像素的平铺形式在各种二次方缩放级别。缩放级别 n - 1 的图块由缩放级别 n 的四个图块构成,使用简单的四点平均算法。因此,它关闭了 opengl mipmapping,而是当需要以某个缩放级别绘制图表的某些部分时,它使用最接近匹配缩放级别的图块(即图块处于二次方缩放级别,但程序允许任意缩放级别)然后缩放图块以匹配实际缩放级别。当然,它必须在各个级别管理所有这些切片的缓存。

在我看来,这个平铺系统过于复杂。看起来我应该能够让图形硬件为我完成所有这些 mipmapping 工作。所以在新程序中,当我读入一张图片时,我将它切成每个 1024x1024 像素的纹理。然后我将每个纹理固定到它的 lon/lat 坐标,然后在我缩放和平移时让 opengl 处理其余部分。

它有效,但问题是:我的结果比原始程序有点模糊,这对这个应用程序很重要,因为您希望能够尽早阅读图表上的文本,放大。因此,就清晰度而言,原始程序使用的简单四点平均算法似乎比 opengl + 我的 GPU 提供了更好的结果。

我知道有几个 glTexParameter 设置可以控制 mipmap 如何工作的某些方面。我尝试了 GL_TEXTURE_MAX_LEVEL(从 0 到 10 的任意值)与 GL_TEXTURE_MIN_FILTER 的各种设置的各种组合。当我将 GL_TEXTURE_MAX_LEVEL 设置为 0(无 mipmap)时,我当然会得到“锐利”的结果,但它们也是锐利,从某种意义上说,像素只是在这里和那里被丢弃,所以在中间变焦时数字是不可读的。当我将 GL_TEXTURE_MAX_LEVEL 设置为更高的值时,当您将图像拉远时(例如,当整个图表适合屏幕时),图像看起来非常好,但是当您放大到中间缩放时,您会注意到模糊,尤其是在查看时图表上的文字。(即,如果不是因为文本,您可能会认为“哇,opengl 在平滑缩放我的图像方面做得很好。”但是对于文本,您会认为“为什么这张图表失焦了?”)

我的理解是,基本上你告诉opengl生成mipmap,然后当你放大它时选择合适的mipmap来使用,并且有一些有限的选项可以在两个最接近的mipmap级别之间进行插值,或者使用最接近的像素或平均附近的像素。但是,正如我所说,在图表上相同的缩放级别(即,文本很小但不是微不足道的缩放级别,例如相当于“7 点”或“ 8 点”大小),与之前基于图块的版本相同。

我的结论是,opengl 创建的 mipmap 比之前使用平均四点算法创建的程序更模糊,并且无论选择正确的 mipmap 或 LINEAR vs NEAREST 都不会获得我需要的清晰度。

具体问题

(1) opengl 实际上比原始程序中的平均四点算法制作更模糊的 mipmap 似乎正确吗?

(2) 在使用 glTexParameter 时,我是否可能忽略了一些可以使用 opengl 正在制作的 mipmaps 提供更清晰结果的东西?

(3)有什么方法可以让opengl首先制作更清晰的mipmap,例如通过使用“立方”过滤器或以其他方式控制mipmap创建过程?或者就此而言,我似乎可以使用相同的平均四点代码来手动生成 mipmap 并将它们交给 opengl。但是我不知道该怎么做...

4

2 回答 2

11

(1) 似乎不太可能;我希望它只是使用一个盒子过滤器,平均四点有效。可能它只是在不同的时刻从一种纹理切换到更高分辨率的纹理——例如它“选择最接近纹理像素大小的 mipmap”,因此 256x256 贴图将用于纹理 383x383 区域,而它取代的手动系统可能总是从 512x512 缩小到目标尺寸为 256x256 或更小。

(2) 不是我在基本 GL 中所知道的,但是如果您要切换到 GLSL 和可编程管道,那么如果问题是使用较低分辨率的贴图时,您可以使用纹理 2D 的 'bias' 参数你不希望它成为。同样,GL_EXT_texture_lod_bias扩展可以在固定管道中做同样的事情。这是十年前的 NVidia 扩展,是所有可编程卡都可以做的事情,所以很有可能你会拥有它。

(编辑:更彻底地阅读扩展,纹理偏差在 1.4 版中迁移到 OpenGL 的核心规范中;显然我的手册页非常过时。检查1.4 规范,第 279 页,您可以提供 GL_TEXTURE_LOD_BIAS)

(3) 是的——如果你禁用 GL_GENERATE_MIPMAP,那么你可以使用 glTexImage2D 为每个比例级别提供你喜欢的任何图像,这就是“级别”参数所指示的。因此,如果需要,您可以提供完全不相关的 mip 贴图。

于 2011-05-13T08:56:36.260 回答
1

为了回答您的具体观点,您提到的四点过滤相当于框过滤。这比高阶过滤器不那么模糊,但会导致混叠模式。最好的过滤器之一是 Lanczos 过滤器。我建议您使用 Lanczos 过滤器从基础纹理计算所有 mipmap 级别,并在显卡上提高各向异性过滤设置。

我假设原始代码本身管理纹理,因为它旨在查看太大而无法放入图形内存的数据集。这在过去可能是一个更大的问题,但仍然是一个问题。

于 2011-10-20T20:24:18.690 回答