OpenGL-Texture Filtering(纹理过滤)

有没有人在啊,想请分析下,OpenGL-Texture Filtering(纹理过滤)
最新回答
把酒不离食

2024-11-05 04:21:46

周一到周五,每天一篇,北京时间早上7点准时更新~跟着我们一起一天天进步和成长吧

在处理纹理贴图时,纹理上的像素与屏幕上的像素通常不会有直接的一一对应关系。为了使纹理贴图效果与屏幕显示匹配,需要通过纹理坐标进行采样。然而,由于纹理图像在应用到几何表面时,总是会被拉伸或缩小,这导致纹理坐标可能无法精确对应到像素上。特别是3D物体带有方向信息时,纹理可能在不同维度上被拉伸和缩小。这就引入了纹理过滤的概念,即如何在拉伸或缩小纹理时计算颜色片段。

为了实现非整数纹理坐标到像素的颜色采样,我们使用了`texture()`函数,它接收浮点数纹理坐标。该函数将坐标范围从0.0到1.0映射到纹理上,不过,不是所有0.0到1.0之间的值都能直接对应到一个纹理像素,某些坐标可能落在像素之间。此外,纹理坐标可以超出0.0到1.0的范围。接下来的章节将详细介绍OpenGL如何通过这些浮点数坐标采样纹理图片,生成像素值。

纹理过滤是计算拉伸或缩小纹理上的颜色片段的过程。拉伸纹理称为放大,而缩小纹理称为缩小。通过设置采样器参数,OpenGL允许我们为放大和缩小条件设置值的构造方法,这些条件称为滤镜。放大滤镜的参数名为`GL_TEXTURE_MAG_FILTER`,缩小滤镜的参数名为`GL_TEXTURE_MIN_FILTER`。当前可选择的基本滤镜有两个:`GL_NEAREST`和`GL_LINEAR`,分别对应最近邻过滤和线性过滤。确保为`GL_TEXTURE_MIN_FILTER`选择这两种滤镜之一,因为默认滤镜设置在没有mipmap时无效。

最近邻过滤是最简单、最快的过滤方法,其特点是将纹理坐标直接映射到纹理像素上,并使用落点的像素颜色作为片段颜色。在信号处理中称为点采样。然而,当纹理被拉伸时,这种过滤方式会产生较大的像素块,如图5.7左侧示例所示。你可以通过以下函数设置放大和缩小滤镜:

线性过滤需要更多的计算,但通常值得额外的开销。现代硬件上,线性过滤的成本接近于零。线性过滤通过应用纹理坐标周围纹理像素的加权平均值(线性插值)来进行,而不是取最近的纹理像素。要使采样出来的颜色与纹理颜色完全匹配,纹理坐标需要正好位于纹理像素的中心。线性过滤在纹理被拉伸时会产生模糊的图形,但这种模糊往往能带来更真实、更自然的外观,而不是最近邻过滤方式产生的尖锐块状效果。如图5.7右侧示例所示,你可以通过以下代码设置线性过滤:

通过比较图5.7的左右两幅图片,我们可以看到应用最近邻过滤后,图像呈现出明显的块状和锯齿效应,尤其是在对比度高的区域。相比之下,使用线性过滤的图像则更加平滑(尽管可能略显模糊)。

总结,我们的课程中使用`texture`系列函数,考虑到某些旧版本和OpenGL ES 2.0不支持整型数据,整型的`texelFetch`函数不具备通用性。然而,随着硬件的发展,未来可能支持整型数据的版本,这句“假命题”可能会发生变化。谁知道呢?

今天的翻译就到这里,明天再见,拜拜~

想要第一时间获取最新内容,可以关注东汉书院和图形之心公众号

期待在东汉书院与你相遇,一起学习进步!