【问题标题】:OpenGL/GLSL - implementation of texture filteringOpenGL/GLSL - 纹理过滤的实现
【发布时间】:2012-03-22 02:28:10
【问题描述】:

我想自己在 GLSL 着色器中实现纹理过滤(min 和 magfilter)(因为我想使用 image_load_and_store 而不是采样器,而且我想以特殊方式处理未定义的像素),我正在寻找用于讨论过滤过程的文章。

我可以回忆起如何从我曾经写过的光线追踪器中实现纹理过滤 - 我认为你需要考虑每个像素的 UV 梯度,并根据这些梯度的长度以某种方式缩放你的采样光栅......但我在那里使用一个 49 个样本的圆形内核,我认为这太重了。

我认为我可以使用 dFdx() 和 dFdy() 获得 UV 渐变 - 但我想知道 openGL 使用哪种内核进行过滤并以相同的方式在我的 glsl 着色器中实现它。

还有 - 如何区分是否需要应用 minfilter 或 magfilter?过滤过程有什么不同吗?

最后但同样重要的是:如果是缩小过滤,如何根据 UV 梯度选择合适的 mipmap 级别?

【问题讨论】:

  • 出于好奇,你为什么要这么做?
  • 通常,纹理过滤和采样是使用硬件执行的。这肯定会很困难,更不用说在着色器中实现性能密集型了。
  • 这是图形研究,因此我们正在模拟未来可能由硬件支持的功能。我这样做有两个原因:首先,我需要使用 image_load_and_store(我实际上不知道我是否可以使用与我也用作 ImageStore 目标的采样器相同的纹理?)第二个原因是我想用以特殊方式获取值“NaN”(如果其中一个纹素为 NaN,则常规过滤只会使整个像素变为 NaN)

标签: opengl filtering glsl


【解决方案1】:

Codeproject 上有一篇文章在 GLSL 中实现了不同的过滤器(其中包括双线性过滤器):link

【讨论】:

  • 这已经很好了,谢谢。但是它只讨论了矩形放大(这是相当微不足道的),所以它没有考虑 uv 渐变和 mipMapping...
  • Mipmaps 通常使用类似于0.5*log2(fwidth()) 的函数自动计算(它bit 更复杂,例如有一个可配置的偏差)。如果你绘制一个更小的四边形,硬件通常会自动选择一个更小的 mipmap,并且没有你需要做的“特殊过滤”。 Mipmap 通常也只是进行框过滤。虽然存在一些复杂的缩小过滤器,但在这方面比你我更好的人似乎同意几乎没有任何明显的改进(但很可能会响起)。
  • 嘿,这是个好信息。因此,要在着色器中正确执行此操作,我将获得 mipmap 级别 floor(0.5*log2(fwidth()))ceiling(0.5*log2(fwidth())),在每个中获取 4 个最接近的纹素并将它们双线性插值,然后根据 (0.5*log2(fwidth())-floor(0.5*log2(fwidth()))) 在两个值之间混合?跨度>
  • 如果您使用 LINEAR_MIP_LINEAR 进行过滤,硬件或多或少会执行此操作,给定或取一两个常数。但这确实有点毫无意义,因为这已经自动运行了。在着色器中过滤可能看起来更好的唯一地方实际上是放大。虽然对我来说,着色器线性 mag 过滤器看起来 100% 相同,虽然立方体更好,但它仍然没有比内置硬件过滤器好多少,以证明巨大的开销是合理的。
  • 这不是毫无意义的,因为我使用的是图像而不是采样器(不支持过滤),而且我以特定方式处理 NaN 值。
猜你喜欢
  • 2015-05-10
  • 2015-03-20
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多