64

我正在尝试了解 GLSL 中的dFdx()dFdy()功能。

我理解以下内容:

  1. 导数是变化率
  2. 具有两个参数的函数的偏导数是指在保持其中一个参数不变的情况下对函数进行微分。
  3. dFdx()dFdy()找到当前片段和相邻片段之间值变化的速率。

我不明白变化率是指什么。是片段坐标的变化率吗?

有没有可能你可以在片段着色器的两次调用之间找到任意变量的变化率?着色器调用是否从相邻调用“读取”变量?对于一个(简单的)示例:

// invocation for fragment 1
float x = 1.0;
float d = dFdx(x);

// invocation for fragment next to fragment 1 along the x axis.
float x = 2.0;
float d = dFdx(x);

d分别是-1.0和1.0吗?

4

1 回答 1

134

要了解这些指令是如何工作的,有助于了解 GPU 的基本执行架构以及片段程序如何映射到该架构。

GPU 在同一个程序上以“锁步”方式运行一堆线程,每个线程都有自己的一组寄存器。因此它获取一条指令,然后执行该指令 N 次,每个正在运行的线程执行一次。为了处理条件分支等,它们还为当前运行的线程组提供了一个“活动掩码”。掩码中不活动的线程实际上不会运行(因此它们的寄存器不会改变)。每当有条件分支或连接(分支目标)时,线程掩码就会相应地更改。

现在,当运行片段程序时,要运行的片段被排列成“四边形”——2x2 4 像素的正方形,它们总是在一个线程组中一起运行。组中的每个线程都知道自己的像素坐标,并且可以通过翻转 x(或 y)坐标的最低位轻松找到四边形中相邻像素的坐标。

当 GPU 执行 DDX 或 DDY 指令时,它会查看相邻像素的线程寄存器并与当前像素的值相减 - 减去较高坐标的值(最低位 1 ) 从低位(最低位 0)开始。

如果您使用dFdxdFdy在条件分支中,这会产生影响——如果四元组中的一个线程处于活动状态而另一个不处于活动状态,GPU 仍将查看非活动线程的寄存器,其中可能有任何旧值,所以结果可以是任何东西。

于 2013-05-03T23:05:16.153 回答