来自OpenGL文档:
dFdxFine和dFdyFine根据当前片段及其近邻的p值使用局部差分计算导数。
dFdxCoarse和dFdyCoarse根据当前片段邻居的p值使用局部差分计算导数,可能(但不一定)包含当前片段的值。也就是说,在给定的区域内,与dFdxFine和dFdyFine函数相比,实现可以在更少的唯一位置上计算导数。
它们之间的区别是什么?我什么时候应该关心?
我知道两者都是计算值对窗口坐标的导数,但我不明白计算它们的方法。
我猜它们都是在硬件上实现的,但是你能发布一个dFdx伪代码实现吗?
来自GLSL规范:
通常考虑片段或样本的2x2平方,并计算独立的dFdxFine每行和独立的dFdyFine每列,而仅计算单个 dfdx粗和单个dFdyCoarse表示整个2x2正方形。
基本上计算导数的方法是通过数值微分。为了简单起见,假设我们正在渲染到一个单采样的帧缓冲区,并假设我们想要计算dFdx(a)
。然后,通常相邻片段的2x2正方形将同时着色(即在同一工作组内):
a00 a10
a01 a11
从概念上讲,所有的着色器调用将计算它们的值a
,将其写入共享内存,并发出屏障。在势垒之后,导数可以近似为:
dFdxFine(a) = (a10 - a00)/dx at xy = 00, 10
dFdxFine(a) = (a11 - a01)/dx at xy = 01, 11
对于粗导数,规范明确允许只计算整个2x2像素块的一个导数。因此,一个符合标准的实现也可以计算:
dFdxCoarse(a) = (a10 - a00)/dx at xy = 00, 10, 01, 11
两者之间是否存在性能差异取决于硬件。如果它们在你的硬件上返回不同的结果,那么"粗糙"版本应该更快。通常你不应该关心这些函数。只需使用dFdx
和dFdy
变体,它们使用实现默认变体(精细或粗糙)。