简单来说,textureGrad()是什么?

Mak*_*gan 6 opengl graphics glsl

我在此阅读了khronos Wiki

但是我真的不明白它在说什么。TextureGrad到底做什么?

我认为它会采样多个mipmap级别,并使用为其提供的显式导数向量来计算一些颜色混合。但我不确定。

der*_*ass 12

对纹理进行采样时,需要特定的纹理坐标才能对纹理数据进行采样。为了简单起见,我将假设2D纹理,因此纹理坐标是2D向量(s,t)。(说明与其他维度类似)。

如果要对三角形进行纹理映射,通常使用两种策略之一来获取纹理坐标:

  1. 纹理坐标是模型的一部分。每个顶点都包含2D纹理坐标作为顶点属性。在栅格化期间,这些纹理坐标将在图元上进行插值。
  2. 您指定一个数学映射。例如,您可以定义一些将3D对象坐标映射到某些2D纹理坐标的函数。例如,您可以定义一些投影,然后将纹理投影到表面上,就像真实的投影仪将图像投影到某些真实对象上一样。

无论哪种情况,光栅化时生成的每个片段通常都具有不同的纹理坐标,因此屏幕上的每个绘制像素将获得纹理的不同部分。

关键是:每个片段都具有2D像素坐标(x,y)和2D纹理坐标(s,t),因此我们可以将这种关系基本上解释为数学函数:

(s,t) = T(x,y)
Run Code Online (Sandbox Code Playgroud)

由于这是2D像素位置向量中的向量函数,因此(x,y)我们还可以沿x方向(向右)和y方向(向上)构建偏导数,以告诉使用沿这些方向的纹理坐标的变化率

dTdxdTdytextureGrad是正义的。

那么GPU需要做什么呢?

当您要实际过滤纹理时(与简单点采样相反),您需要知道纹理空间中的像素足迹。每个单个片段代表屏幕上一个像素的面积,您将使用纹理中的单个颜色值来代表整个像素(撇开多重采样)。现在,像素覆盖区表示像素在纹理空间中将具有的实际面积。我们可以通过不是针对像素中心而是针对4个像素角插值texcoords来计算它。生成的texcoords将在纹理空间中形成梯形。

缩小纹理时,多个纹理像素将映射到同一像素(因此,像素足迹在纹理空间中很大)。放大时,每个像素将仅代表相应纹理像素的一小部分(因此占用空间很小)。

纹理足迹告诉您:

  • 如果纹理被缩小或放大(GL在每种情况下具有不同的滤镜设置)
  • 每个像素将映射多少个纹理像素,因此哪个mipmap级别合适
  • 像素覆盖区有多少各向异性。屏幕上的每个像素和纹理空间中的每个纹理像素基本上是一个正方形,但是像素覆盖区可能会明显偏离正方形,并且可能比宽度或过渡距离高得多(尤其是在透视失真较大的情况下)。经典的双线性或三线性纹理滤镜始终使用正方形滤镜足迹,但各向异性纹理滤镜将使用此信息实际生成与实际像素足迹更紧密匹配的滤镜足迹(以避免混入不应确实属于像素)。

代替计算所有像素角的纹理坐标,我们将使用片段中心的偏导数作为像素足迹的近似值。

下图显示了几何关系:

纹理空间中像素足迹的示意图

这表示纹理空间中四个相邻像素(2x2)的覆盖区,因此均匀网格为纹理像素,而四个梯形则代表4个像素覆盖区。现在计算实际导数将暗示我们具有或多或少的T(x,y)上述明确公式。GPU通常使用另一种近似值:仅查看每个2x2像素块中相邻片段(无论如何将要计算)的实际texcoords,并通过有限差分来近似占用空间-只是减去相邻片段的实际texcoords彼此。结果在图中显示为点划线的平行四边形。

在硬件中,这已实现为始终在同一扭曲/波前/ SIMD-Group中并行阴影2x2像素四边形。所述GLSL衍生物功能喜欢dFdxdFdy简单地通过减去邻近片段的实际值的工作。并且标准texture函数只是内部在纹理坐标参数上使用此机制。该textureGrad函数绕过它,并允许您指定自己的值,这意味着您可以控制GPU在进行实际的过滤/ mipmap级别选择时所采用的像素尺寸。