ddx(hlsl)实际做什么?


17

我有点困惑。官方文档(http://msdn.microsoft.com/zh-cn/library/windows/desktop/bb509588(v=vs.85).aspx)表示ddx(input)是输入方面的偏导数到“屏幕空间的x坐标”。

我的演算很好,但是如何分辨输入来自什么呢?如果我给它传递一个函数,很好,我可以想象它会做什么,但是数字的导数始终为零...?

只是缩放吗?就像,它将在此距离缩放到其大小的十分之一,因此返回十分之一?但这并不需要输入...

有人可以快速解释一下实际情况吗?


2
ddxddy做自己无法做的魔术。他们可以访问栅格化管道中无法从像素着色器中获取的其他信息。我不确定他们使用哪个公式。我被认为是他们使用一种估算技术,但我不确定。
肖恩·米德迪奇

那很奇怪,但仍然如此。ddx(5)实际代表什么?如果显示.1,我该怎么解释?还是-6?
理查德·拉斯特

1
ddx(5)是没有意义的。将其与输入值一起使用,这将为您提供该值相对于块中相邻像素的导数。同样,我不知道它计算值的精确度,但是要求非输入的派生可能只是未定义的行为并产生垃圾。有关我无法提供的更多信息,请参见fgiesen.wordpress.com/2011/07/10/…
肖恩·米德迪奇

我不确定,但是很可能是HLSL编译器实际上在对传递给ddx / ddy的表达式进行完全符号区分。blogs.msdn.com/b/chuckw/archive/2011/03/08/... research.microsoft.com/pubs/146019/...
Ziriax

它有什么作用?显然,只有一点点合理的事情。
MickLH '16

Answers:


32

在内部,GPU永远不会一次运行一个像素着色器的一个实例。在最细粒度的情况下,它们始终使用SIMD架构同时运行32-64像素。在此范围内,像素进一步组织为2x2的四边形,因此SIMD向量中的每组4个连续像素对应于屏幕上的2x2像素块。

通过取四边形像素之间的差异来计算导数。例如,ddx将从右侧的值中减去四边形左侧像素中的值,并ddy从顶部的像素中减去底部的像素。然后可以将差异作为对四边形中所有四个像素的导数返回。

由于像素着色器在SIMD中运行,因此可以确保四边形中的所有像素的相应值同时位于同一寄存器中。因此,无论您输入ddx或的表达式或值如何ddy,都将在四边形的所有四个像素中求值,然后如上所述将不同像素的值相减。

因此,采用恒定值的导数将得到零(正如您对微积分所期望的那样,对吗?),因为在所有四个像素中它都是相同的恒定值。

还要注意,有“粗”和“细”导数,ddx_coarse/ ddy_coarseddx_fine/ ddy_fine这里给出区别的解释。仅普通ddx/ ddy是粗略版本的别名。

顺便说一句,此功能存在的原因是GPU内部必须采用纹理坐标的导数才能进行mipmap选择和各向异性过滤。由于硬件仍然需要该功能(您可以在着色器中使用任意表达式来表达纹理坐标),因此很容易将其直接提供给着色器程序员。


+1; 当对纹理应用微扰效果时,我发现这很有用;受扰动的texcoords会产生一些颜色失真,但是将tex2Dgrad与原始(不受扰动的)texcoords的派生词一起使用时,不会产生失真的结果。
Maximus Minimus

好吧,经过一番思考,我想我已经弄清楚了我的困惑。在我看来,它ddx就像传统编程语言中的所有其他功能一样工作。您评估输入,将其转换为浮点数或其他任何值,然后对其进行外部函数(ddx)。但这是不同的-它接受输入字符串,在多个位置对其进行评估,计算一个导数,然后报告结果。那是对的吗?
理查德·拉斯特

1
@RichardRast对。您可以认为是ddx对传递给它的表达式进行操作,而不是对value进行操作
内森·里德

但请看,这很奇怪,应该在文档中显示。在编程生涯中,我再也没有别的时间可以这么做了。
理查德·拉斯特

内森·里德(Nathan Reed)提到,GPU使用这些功能进行mipmap选择。您还可以使用它们来强制GPU选择所需的Mipmap级别,或防止工件因错误的Mip级别选择而导致错误。Shader X3的第163和164页介绍了该过程。
JamesHoux 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.