OpenGL:启用多重采样会在高缩放级别为多边形绘制混乱的边缘

Posted

技术标签:

【中文标题】OpenGL:启用多重采样会在高缩放级别为多边形绘制混乱的边缘【英文标题】:OpenGL: Enabling multisampling draws messed up edges for polygons at high zoom levels 【发布时间】:2010-01-04 22:38:52 【问题描述】:

当我使用以下代码时:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 6);

然后我启用多重采样,我注意到我的程序不再关心最大 mip 级别。

编辑:它也会渲染最后的 miplevel,这就是问题所在,我不希望它们被渲染。

编辑3: 我测试并确认它根本不会忘记 mip 限制,所以它确实遵循我的 GL_TEXTURE_MAX_LEVEL 设置。 ...所以问题与 mipmap 无关,我猜...

Edit2:截图,这是世界地图被放大了很多,使用低角度使效果显示最差的方式,地图下方还有渲染的水平面,所以没有从地图纹理以外的任何地方获取黑色像素的可能性:

alt text http://img511.imageshack.us/img511/6635/multisamplingtexturelim.png

Edit4:所有这些图片都应该看起来像右上角的图片(只是边缘更平滑,具体取决于多重采样)。但显然我的代码中有一些可怕的错误。我必须使用 mipmap,mipmap 不是问题,它们工作得很好。

我做错了什么,或者我该如何解决?

【问题讨论】:

究竟如何启用多重采样? 通过nvidia控制面板,强制启用每个应用程序 需要更多信息。它如何“不在乎”?纹理在该级别之上消失(如果未提供)?你启用了 GL_GENERATE_MIPMAP 吗?如果可以,请包含更多代码或完整的测试用例。 它还渲染了更多的纹理miplevels,换句话说:它对MAX_LEVEL一点也不关心 不,我没有启用 GL_GENERATE_MIPMAP,应该吗?我正在使用 gluBuild2DMipmaps() 【参考方案1】:

好的。所以问题毕竟不是 TEXTURE_MAX_LEVEL 。有趣的是,一个简单的测试如何帮助解决这个问题。

我有两种关于 LOD 选择不同的理论,而这两种理论似乎都被纯色测试所反驳。

然后进入第三种理论。如果我正确理解你的场景,你有一个使用纹理图集的模型,我们观察到的是一些应该从图集的特定项目中获取的多边形实际上是从不同的项目中获取的。是这样吗?

这可以通过多重采样片段通常在像素中间进行采样这一事实来解释。即使该中心不在生成样本的三角形内。说明见this page底部。

解决此问题的常用方法称为centroid sampling(此页面也有很好的问题说明)。它强制采样带回三角形内的采样点。

现在有个坏消息:我不知道有任何方法可以在可编程管道之外打开质心过滤,而且您没有使用它。您是否认为要切换以访问该功能?

编辑添加:

此外,不使用纹理图集也是解决此问题的一种方法。它如此可见的原因是因为您开始使用“out-of-triangle”采样模式从图集的另一部分获取。

【讨论】:

如果我不使用纹理图集,我将不得不按顺序绑定超过 200000 个纹理(1000-4000 个唯一的)。这将对某些卡(可能对任何卡)造成巨大的延迟。我还不能使用质心采样,因为我对着色器一无所知,所以我会忘记这个平滑多边形边缘的事情......除非有其他方法可以平滑多边形? 嗯,超级采样,而不是多重采样,可以完成这项工作。但它的渲染成本通常使它不切实际(做 4 倍的像素数学)。【参考方案2】:

还要检查您为 MIN_FILTER 设置了什么:

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ... );

尝试不同的设置(列表为here)。

但是,如果您对 gluBuild2DMipmaps 的结果不满意,我建议您查看替代方案:

glGenerateMipmap/glGenerateMipmapEXT(是的,它可以在没有 FBO 的情况下使用) SGIS_generate_mipmap 扩展(广泛支持)

尤其是后者是高度可定制的。没有提到的是,这个扩展是通过将GL_GENERATE_MIPMAP 设置为 true 来启动的。它是自动的,因此如果数据发生变化,您无需重新计算。

【讨论】:

我的 min_filter 应该是 GL_LINEAR_MIPMAP_LINEAR。为什么 GL_GENERATE_MIPMAP 对我来说还不够?为什么要为此使用外部库?我看不出 gluBuild2DMipmaps() 和 GL_GENERATE_MIPMAP 之间有什么区别,只是速度而已。【参考方案3】:

如果您希望您的渲染始终拥有它,您应该通过您的应用程序而不是 nvidia 控制面板enable multi-sampling。这甚至可以解决您的问题。

至于GL_TEXTURE_MAX_LEVEL 设置在使用控制面板多重采样时被忽略,这听起来像是驱动程序错误/功能。这很奇怪,因为此功能可用于限制您在纹理中实际加载的内容(所谓的纹理完整性标准)。如果您根本不加载最低的 mipmap 级别怎么办?渲染了什么?

编辑:从您展示的图片来看,它看起来并没有真正忽略设置。一方面,MAX_LEVEL=0 与 MAX_LEVEL=6 不同。现在,考虑到纹理中的噪音,我什至不明白为什么你的 MAX_LEVEL=6/MS off 看起来那么干净。根据 MA​​X_LEVEL=16/MS 关闭图片,它应该有噪声。此时,我建议在您的漫反射纹理的每个 mip 级别中放置不同的纯色(而不是依赖 GL 来构建您的 mip),以准确查看您获得的 mip 级别。

【讨论】:

我通过 gluBuild2DMipmaps() 函数生成 miplevels。我可以看到它渲染了我不想要的 miplevel,因为由于像素混合,最后一个 miplevel 中的颜色会发生变化。 好吧,尝试手动加载 mipmap,不要全部加载。没有办法告诉 gluBuild2DMipmaps 不加载关卡,所以不要用它来进行调试。您甚至不必真正加载 mipmap。只需使用 GL_TEXTURE_MAX_LEVEL=0 当我使用 GL_TEXTURE_MAX_LEVEL=0 时,我仍然看到难看的纹理,现在不仅有黑色像素,而且还有白色/黑色像素,虽然只是在低角度,但从上到下看起来是直的普通的。如果不进行多重采样,纹理就会正确渲染。 一些图片怎么样? “丑”并不意味着什么。 哼,但这并不能解释。如果它在第 6 级时是同质的,那么它将在较小的 mip 处保持同质。你试过加载纯色 mips 吗?

以上是关于OpenGL:启用多重采样会在高缩放级别为多边形绘制混乱的边缘的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL4 多重采样抗锯齿和渲染到纹理

在 GLFW 窗口中启用多重采样不会提高抗锯齿的质量

在 OpenGL Win32 上激活多重采样

激活多重采样(Windows)时如何防止空的OpenGL窗口?

为啥在使用 FBO 进行多重采样时,OpenGL 会使我的场景变亮?

◮OpenGL-抗锯齿