在着色器中访问时,OpenGL 如何决定使用 MAG_FILTER 和 MIN_Filter?

Posted

技术标签:

【中文标题】在着色器中访问时,OpenGL 如何决定使用 MAG_FILTER 和 MIN_Filter?【英文标题】:How does OpenGL decide between using MAG_FILTER and MIN_Filter when accessing in shader? 【发布时间】:2018-03-03 18:52:38 【问题描述】:

当使用 glTexParamteri(GL_Texture_2D, GL_TEXTURE_MAG_FILTER, ...) 和 glTexParamteri(GL_Texture_2D, GL_TEXTURE_MIN_FILTER, ...) 配置 OpenGL 时,OpenGL 如何决定在使用纹理(...) 访问着色器中的纹理时使用哪个过滤器?

我唯一的猜测是它正在计算像素足迹,但由于您可以在片段或顶点着色器中访问纹理,因此它无法知道在哪个基元上投影了哪个纹理。

【问题讨论】:

【参考方案1】:

我唯一的猜测是它正在计算像素足迹

是的,它就是这样做的。它将通过计算 texcoords 相对于窗口空间 xy 方向的导数来近似纹理空间中的像素足迹,并且它将通过 有限差分 在2x2 像素四边形,就像 dFdx and dFdy GLSL functions 正在工作一样。它将使用两个偏导数向量中较长的一个作为大小,并据此计算 Level-Of-Detail 值。

但由于您可以在片段或顶点着色器中访问纹理,因此无法知道在哪个图元上投影了哪个纹理。

正确,这就是为什么GLSL specification, (Version 4.60) 在8.9 纹理函数部分的开头声明以下内容的原因:

纹理查找功能在所有着色阶段都可用。但是,自动详细程度是 仅针对片段着色器计算。其他着色器的操作就像基本细节级别一样 计算为零

【讨论】:

了解 dFdx 和 dFdy 对我帮助很大,尤其是 site: 谢谢!【参考方案2】:

一些(即:大多数)GLSL 纹理访问函数说它们需要“隐式导数”。所有这些功能只能完全发挥作用:

    In the fragment shader.

    uniform control flow of the FS内。

如果您在非片段着色器中调用需要隐式导数的纹理访问函数,则它将仅从基本 mipmap 级别访问。但是,如果您在片段着色器中但在统一控制流之外,则所有此类函数都有未定义的行为。

因此,如果您不在片段着色器中,您要么想要从基本 mipmap 级别访问(在这种情况下,MAG_FILTER 适用),要么您想要使用显式提供用于进行插值的值的函数:Lod(explicitly say what mipmap level(s) you fetch from)、Grad(explicitly specify derivatives 用于确定像素足迹的位置)或任何 texelFetchtextureGather 函数(不进行插值)完全)。

【讨论】:

以上是关于在着色器中访问时,OpenGL 如何决定使用 MAG_FILTER 和 MIN_Filter?的主要内容,如果未能解决你的问题,请参考以下文章

在 vertexShader 中使用 OpenGl 未声明的标识符,我在顶点着色器中绘制三角形时遇到问题

着色器中的 OpenGL 法线变换

片段着色器中未使用纹理数据 - OpenGL

OpenGL ES 2.0 符点精度

片段着色器中的OpenGL点精灵旋转

OpenGL 计算着色器中的样本深度缓冲区