首页 > 解决方案 > OpenGL 中的 GL_CLAMP 与 GL_CLAMP_TO_EDGE 有何不同?

问题描述

根据您参考的文档glTexParameteri(),对纹理的钳制有两种不同的解释。
Microsoft 的文档中,您会找到GL_CLAMP,而在Khronos 的文档中,您会找到GL_CLAMP_TO_EDGE

我认为它们在功能上是同义词,但似乎并非如此。
在我的 Ubuntu 18.04.2 上,我有以下内容。

/usr/include/GL/gl.h
#define GL_CLAMP_TO_EDGE                        0x812F
#define GL_CLAMP                                0x2900
#define GL_CLAMP_TO_BORDER                      0x812D

而在我的 Windows 10 16299 Enterprise 版本中,我有以下内容。

C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um\gl\GL.h
#define GL_CLAMP                          0x2900

它们被映射到不同的值,因此人们也会期望不同的行为。
我试图摆脱使用 GL_REPEAT 获得的伪像。请参见下图中的绿色圆圈(图片来源 - freepik.com)。

女人的脸 - freepik

GL_CLAMP确实摆脱了伪影,但是我无法找到有关各种钳位模式如何不同的足够详细信息,以及何时更喜欢一种。

我在我的 Windows 机器上编码,以后可能会将相同的应用程序移植到 GNU/Linux。

更新 1GL_CLAMP消除了大多数伪像,但不是全部,最后我为我的所有纹理添加了一个 10px 透明边框。然而,问题仍然存在。

更新 2:问题不在于 GL_CLAMP 在实现之间有何不同,而是GL_CLAMP 与 GL_CLAMP_TO_EDGE 有何不同?

标签: windowsopengltexturesrendering

解决方案


如果您深入研究 Khronos Registry的不同 GL 规范,您会发现一些解释。

在第一个规范(1.0 1994)中CLAMPREPEAT是参数的唯一选项TEXTURE_WRAP_x

规范 1.2 1998 添加CLAMP_TO_EDGE。它提供了您需要的线索:

GL 通常会进行钳制,以使纹理坐标精确地限制在 [0;1] 范围内。当使用此算法钳制纹理坐标时,纹理采样过滤器跨越纹理图像的边缘,从纹理图像中获取一半样本值,另一半从纹理边界获取样本值。有时需要在不需要边框且不使用恒定边框颜色的情况下钳制纹理。

一种新的纹理钳制算法 CLAMP_TO_EDGE 在所有 mipmap 级别上钳制纹理坐标,这样纹理过滤器就不会对边界纹素进行采样。夹紧时返回的颜色仅来自纹理图像边缘的纹素。


CLAMP选项在规范 3.0 2008 中已弃用,并在规范 3.2 Core 2009 中删除。当(且仅当)您设置核心配置文件上下文时,您仍然可以使用它。


Microsoft doc 采用 old 的原因CLAMP是 MS 提供了 OpenGL 1.1,而不需要检索指向 GL 命令的函数指针。更高的版本需要特殊的头文件(除了 gl.h)和其他特殊的东西。


推荐阅读