我正在重写一个基于opengl的gis / mapping程序。除此之外,该程序还允许您加载航海图的光栅图像,将它们固定为lon / lat坐标,并缩放和平移它们。
该程序的先前版本使用自定义平铺系统,其实质上是手动创建原始图像的mipmap,采用256x256像素平铺的形式,具有不同的两个功率的缩放级别。使用简单的四点平均算法,从缩放级别n的四个区块构造用于缩放级别n-1的区块。因此,它关闭了opengl mipmapping,相反,当需要在某个缩放级别绘制图表的某些部分时,它会使用最近匹配缩放级别的图块(即,图块处于2次幂缩放状态)级别,但程序允许任意缩放级别),然后缩放切片以匹配实际缩放级别。当然,它必须在各个级别管理所有这些磁贴的缓存。
在我看来,这种拼贴系统过于复杂。看起来我应该能够让图形硬件为我完成所有这些mipmapping工作。所以在新程序中,当我在图像中读取时,我将其切割成每个1024x1024像素的纹理。然后我将每个纹理固定到它的lon / lat坐标,然后我让opengl在我缩放和平移时处理剩下的纹理。
它有效,但问题是:我的结果比原始程序有点模糊,这对于这个应用程序很重要,因为你希望能够尽可能早地在图表上阅读文本,缩放。所以它看起来像原始程序使用的简单平均四点算法在清晰度方面比opengl +我的GPU更好。
我知道有几个glTexParameter设置来控制mipmaps如何工作的某些方面。我尝试了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简单模糊,没有选择正确的mipmap或LINEAR vs NEAREST的数量将获得清晰度I需要。
具体问题:
(1)opengl实际上是否比原始程序中的平均四点算法制作模糊mipmap似乎是正确的?
(2)在使用glTexParameter时,我是否可能忽略了一些可以使用opengl制作的mipmaps提供更清晰的结果?
(3)我是否有办法让opengl首先制作更清晰的mipmap,例如使用“立方”过滤器或以其他方式控制mipmap创建过程?或者就此而言,似乎我可以使用相同的平均四点代码来手动生成mipmap并将它们移交给opengl。但我不知道该怎么做......
答案 0 :(得分:10)
(1)似乎不太可能;我希望它只是使用一个盒子过滤器,平均有效四个点。可能它只是在不同的时刻从一个纹理切换到一个更高的分辨率 - 例如它“选择最接近匹配纹理像素大小的mipmap”,因此256x256地图将用于纹理383x383区域,而它替换的手动系统可能总是从512x512缩小,直到目标大小为256x256或更少。
(2)不是我在基础GL中知道的,但是如果你要切换到GLSL和可编程管道那么你可以使用'bias'参数来设置texture2D,如果问题是较低分辨率的地图是当你不想要它时使用。同样,GL_EXT_texture_lod_bias扩展可以在固定管道中执行相同操作。它是十年前的NVidia扩展,是所有可编程卡都能做到的,所以你很可能会拥有它。
(编辑:更彻底地阅读扩展,纹理偏差迁移到版本1.4中OpenGL的核心规范;显然我的手册页已经过时了。检查1.4 spec,第279页,你可以提供一个GL_TEXTURE_LOD_BIAS)
(3)是 - 如果您禁用GL_GENERATE_MIPMAP,那么您可以使用glTexImage2D为每个级别提供您喜欢的任何图像,这就是'level'参数所指示的。因此,如果需要,您可以提供完全不相关的mip贴图。
答案 1 :(得分:1)
要回答您的具体要点,您提到的四点过滤相当于盒式过滤。这比高阶滤镜更不模糊,但可能导致混叠模式。最好的过滤器之一是Lanczos过滤器。我建议您使用Lanczos过滤器从基础纹理计算所有mipmap级别,并在显卡上调高各向异性过滤设置。
我假设原始代码管理纹理本身,因为它设计用于查看太大而无法放入图形内存的数据集。这在过去可能是一个更大的问题,但仍然是一个问题。