来自OpenGL文档:
dFdxFine和dFdyFine根据当前片段及其直接邻居的p值,使用局部差分计算导数。
dFdxCoarse和dFdyCoarse使用基于当前片段的邻居的p值的本地差分来计算导数,并且可能但不一定包括当前片段的值。也就是说,在给定区域内,实现可以在比相应的dFdxFine和dFdyFine函数允许的更少的唯一位置计算导数。
它们之间有什么区别?我应该什么时候关心?
据我所知,两者都计算了相对于窗口坐标的值的导数,但我不明白用于计算它们的方法。
我猜他们都是用硬件实现的,但是你可以发布一个dFdx伪代码实现吗?
答案 0 :(得分:6)
来自GLSL规范:
通常考虑2x2平方的片段或样本,并且每行计算独立的 dFdxFine 并且每列计算独立的 dFdyFine ,同时仅计算单个 dFdxCoarse 和单个 整个2x2广场的 dFdyCoarse 。
基本上计算导数的方式是通过数值微分。为简单起见,假设我们渲染为单采样帧缓冲区,并假设我们想要计算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
变体,它们使用实现默认变体(精细或粗略)。