mipmapped 纹理是如何采样的?
How are mipmapped textures sampled?
我的问题专门针对 Metal,因为我不知道另一个 API.
的答案是否会改变
到目前为止我相信我的理解是这样的:
已预先计算了一个 mipmapped 纹理 "levels of detail",其中通过以某种有意义的方式对原始纹理进行下采样来创建较低级别的细节。
Mipmap 级别是按细节级别降序排列的,其中级别 0
是原始纹理,更高级别是它的二次幂缩减。
大多数 GPU 实现三线性过滤,它为每个样本选择两个相邻的 mipmap 级别,使用双线性过滤从每个级别采样,然后线性混合这些样本。
我不太明白这些 mipmap 级别是如何 selected 的。在 Metal 标准库的 documentation 中,我看到可以获取样本,无论是否指定 lod_options
类型的实例。我假设这个论点改变了 mipmap 级别 selected 的方式,显然有三种 lod_options
用于 2D 纹理:
bias(float value)
level(float lod)
gradient2d(float2 dPdx, float2 dPdy)
不幸的是,文档没有解释这些选项的作用。我可以猜测 bias()
会偏向一些自动选择的细节级别,但是偏向 value
是什么意思?它的运作规模是多少?同样,lod
of level()
是如何转化为离散的 mipmap 级别的?并且,在 gradient2d()
使用纹理坐标梯度的假设下操作,它如何使用该梯度到 select mipmap 级别?
更重要的是,如果我省略 lod_options
,那么 mipmap 级别 select 是如何编辑的?这是否因正在执行的函数类型而异?
而且,如果 sample()
函数的默认 no-lod-options-specified 操作是做类似 gradient2D()
的事情(至少在片段着色器中),它是否利用简单的屏幕-space 导数,还是直接与光栅化器和内插纹理坐标一起计算精确的梯度?
最后,这种行为在不同设备之间的一致性如何?我读到的一篇旧文章(在 DirectX 9 中是旧的)提到了复杂的特定于设备的 mipmap selection,但我不知道 mipmap selection 是否在较新的体系结构上得到了更好的定义。
这是一个相对较大的主题,您最好在引入三线性过滤的 https://computergraphics.stackexchange.com/ but, very briefly, Lance Williams' paper "Pyramidal Parametrics" 和 term "MIP mapping" 上询问,有一个建议来自 Paul Heckbert(见第三页,第 1 列),我认为在某些系统中在一定程度上可能仍在使用。
实际上,计算 MIP 贴图级别的方法通常基于这样的假设:您的屏幕像素是一个小圆圈,并且可以将该圆圈映射回纹理以获得大致椭圆形。您估计以最高分辨率地图的纹素表示的长轴的长度。然后这会告诉您应该对哪些 MIP 贴图进行采样。例如,如果长度为 6,即介于 2^2 和 2^3 之间,则您希望在 MIP 贴图级别 2 和 3 之间进行混合。
我的问题专门针对 Metal,因为我不知道另一个 API.
的答案是否会改变到目前为止我相信我的理解是这样的:
已预先计算了一个 mipmapped 纹理 "levels of detail",其中通过以某种有意义的方式对原始纹理进行下采样来创建较低级别的细节。
Mipmap 级别是按细节级别降序排列的,其中级别
0
是原始纹理,更高级别是它的二次幂缩减。大多数 GPU 实现三线性过滤,它为每个样本选择两个相邻的 mipmap 级别,使用双线性过滤从每个级别采样,然后线性混合这些样本。
我不太明白这些 mipmap 级别是如何 selected 的。在 Metal 标准库的 documentation 中,我看到可以获取样本,无论是否指定 lod_options
类型的实例。我假设这个论点改变了 mipmap 级别 selected 的方式,显然有三种 lod_options
用于 2D 纹理:
bias(float value)
level(float lod)
gradient2d(float2 dPdx, float2 dPdy)
不幸的是,文档没有解释这些选项的作用。我可以猜测 bias()
会偏向一些自动选择的细节级别,但是偏向 value
是什么意思?它的运作规模是多少?同样,lod
of level()
是如何转化为离散的 mipmap 级别的?并且,在 gradient2d()
使用纹理坐标梯度的假设下操作,它如何使用该梯度到 select mipmap 级别?
更重要的是,如果我省略 lod_options
,那么 mipmap 级别 select 是如何编辑的?这是否因正在执行的函数类型而异?
而且,如果 sample()
函数的默认 no-lod-options-specified 操作是做类似 gradient2D()
的事情(至少在片段着色器中),它是否利用简单的屏幕-space 导数,还是直接与光栅化器和内插纹理坐标一起计算精确的梯度?
最后,这种行为在不同设备之间的一致性如何?我读到的一篇旧文章(在 DirectX 9 中是旧的)提到了复杂的特定于设备的 mipmap selection,但我不知道 mipmap selection 是否在较新的体系结构上得到了更好的定义。
这是一个相对较大的主题,您最好在引入三线性过滤的 https://computergraphics.stackexchange.com/ but, very briefly, Lance Williams' paper "Pyramidal Parametrics" 和 term "MIP mapping" 上询问,有一个建议来自 Paul Heckbert(见第三页,第 1 列),我认为在某些系统中在一定程度上可能仍在使用。
实际上,计算 MIP 贴图级别的方法通常基于这样的假设:您的屏幕像素是一个小圆圈,并且可以将该圆圈映射回纹理以获得大致椭圆形。您估计以最高分辨率地图的纹素表示的长轴的长度。然后这会告诉您应该对哪些 MIP 贴图进行采样。例如,如果长度为 6,即介于 2^2 和 2^3 之间,则您希望在 MIP 贴图级别 2 和 3 之间进行混合。