Dan*_*gel 8 c++ opengl shader glsl
正如我所说,我想在GLSL的计算着色器中实现我自己的双精度cos()函数,因为只有一个内置的float版本.
这是我的代码:
double faculty[41];//values are calculated at the beginning of main()
double myCOS(double x)
{
double sum,tempExp,sign;
sum = 1.0;
tempExp = 1.0;
sign = -1.0;
for(int i = 1; i <= 30; i++)
{
tempExp *= x;
if(i % 2 == 0){
sum = sum + (sign * (tempExp / faculty[i]));
sign *= -1.0;
}
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
这段代码的结果是,着色器上的总和是NaN,但在CPU上,算法运行良好.我也尝试调试此代码,并获得以下信息:
现在我的问题是:如果每个变量都是一个数字并且什么都没有被零除,那么究竟什么可能出错呢?特别是当算法在CPU上工作时?
让我猜猜:
\n\n首先,您确定问题出在循环中,并且仅使用以下操作:+, *, /。
NaN从这些操作生成的规则是:
0/0和\xc2\xb1\xe2\x88\x9e/\xc2\xb1\xe2\x88\x9e0\xc3\x97\xc2\xb1\xe2\x88\x9e和\xc2\xb1\xe2\x88\x9e\xc3\x970\xe2\x88\x9e + (\xe2\x88\x92\xe2\x88\x9e)和(\xe2\x88\x92\xe2\x88\x9e) + \xe2\x88\x9e等价减法您通过声明已正确初始化来排除0/0和的可能性。\xc2\xb1\xe2\x88\x9e/\xc2\xb1\xe2\x88\x9efaculty[]
该变量sign始终是1.0这样,所以它不能通过操作-1.0生成。NaN*
剩下的就是+操作(如果tempExp有的话)\xc2\xb1\xe2\x88\x9e。
因此,tempExp您的功能输入可能太高,并且变成\xc2\xb1\xe2\x88\x9e,这也会sum导致\xc2\xb1\xe2\x88\x9e。在下一次迭代中,您将NaN通过以下方式触发生成操作:\xe2\x88\x9e + (\xe2\x88\x92\xe2\x88\x9e)。这是因为您将加法的一侧乘以sign并且在每次迭代时符号在正负之间切换。
你试图cos(x)近似0.0. 因此,您应该使用函数的属性cos()将输入值减少到接近 的值0.0。最好在范围内[0, pi/4]。比如去掉 的倍数,通过周围计算得到in2*pi的值等等。cos()[pi/4, pi/2]sin(x)0.0