【发布时间】:2015-03-10 16:33:59
【问题描述】:
我需要一个在计算着色器中具有双精度的acos() 函数。由于GLSL中没有双精度的acos()的内置函数,我尝试自己实现。
起初,我实现了一个泰勒级数,例如 Wiki - Taylor series 中的方程,并带有预先计算的教师值。但这似乎在 1 左右不准确。最大误差约为 0.08,迭代 40 次。
我还实现了this method,它在 CPU 上运行良好,最大误差为 -2.22045e-16,但在着色器中实现它时遇到了一些麻烦。
目前,我正在使用来自here 的acos() 近似函数,其中有人在this 网站上发布了他的近似函数。我正在使用这个网站的最准确的功能,现在我得到的最大错误是-7.60454e-08,但这个错误也太高了。
我这个函数的代码是:
double myACOS(double x)
{
double part[4];
part[0] = 32768.0/2835.0*sqrt(2.0-sqrt(2.0+sqrt(2.0+sqrt(2.0+2.0*x))));
part[1] = 256.0/135.0*sqrt(2.0-sqrt(2.0+sqrt(2.0+2.0*x)));
part[2] = 8.0/135.0*sqrt(2.0-sqrt(2.0+2.0*x));
part[3] = 1.0/2835.0*sqrt(2.0-2.0*x);
return (part[0]-part[1]+part[2]-part[3]);
}
有人知道acos() 的另一种实现方法吗?它非常准确并且——如果可能的话——很容易在着色器中实现?
一些系统信息:
- 英伟达 GT 555M
- 使用 optirun 运行 OpenGL 4.3
【问题讨论】:
-
为什么需要acos?如果是为了 slerp,你可以用重复的 lerps 分而治之
-
<cmath>中有一个标准的acos -
废话,如果你需要那么多
sqrts,请使用查找表。 -
@NathanOliver cmath 在 glsl 着色器中不可用
-
@AndonM.Coleman 我会使用一个,但这只是为了证明概念。正如我所说,准确性比性能更重要。
标签: opengl glsl shader trigonometry double-precision