正如我所说,我想在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上工作时?
我想阅读斯坦福兔子的未重建数据.点数据存储为多个范围图像,必须将其转换为组合成一个大点云,如README中所写:
These data files were obtained with a Cyberware 3030MS optical
triangulation scanner. They are stored as range images in the "ply"
format. The ".conf" file contains the transformations required to
bring each range image into a single coordinate system.
Run Code Online (Sandbox Code Playgroud)
这是.conf文件:
camera -0.0172 -0.0936 -0.734 -0.0461723 0.970603 -0.235889 0.0124573
bmesh bun000.ply 0 0 0 0 0 0 1
bmesh bun045.ply -0.0520211 -0.000383981 -0.0109223 0.00548449 -0.294635 -0.0038555 0.955586
bmesh bun090.ply 2.20761e-05 -3.34606e-05 -7.20881e-05 0.000335889 -0.708202 …Run Code Online (Sandbox Code Playgroud) 我需要acos()一个计算着色器中具有双精度的函数.由于acos()GLSL中没有内置函数具有双精度,我试图实现自己的.
起初,我实施了一个泰勒系列,如维基 - 泰勒系列中的方程式,具有预先计算的教师价值.但这似乎在1左右不准确.最大误差约为0.08,有40次迭代.
我也实现了这种在CPU上工作得很好的方法,最大误差为-2.22045e-16,但是我在着色器中实现这个有一些麻烦.
目前,我正在使用此处的acos()近似函数,其中有人在此站点上发布了他的近似函数.我正在使用这个网站最准确的功能,现在我得到的最大误差为-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]);
}
Run Code Online (Sandbox Code Playgroud)
有没有人知道另一种实现方法acos()是非常准确的 - 如果可能 - 很容易在着色器中实现?
一些系统信息:
我想使用Qt 5.4来创建一个窗口,并使用普通的OpenGL函数在该窗口中渲染一些东西.在过去的几天里,我读了很多关于Qt类以及如何初始化OpenGL等等.我认为,我必须处理的主要类是QOpenGLWindow或QOpenGLWidget,但也有QSurface和其他一些类.现在我非常不确定接下来要做什么以及我应该使用哪个类来使用普通的OpenGL函数.有人可以更清楚地向我解释我要设置Qt GUI,我可以使用普通的OpenGL吗?
我的其他一些问题是:
编辑:我和一位同事讨论了这个问题,我们唯一的结论是使用Offscreen-Rendering.有谁知道另一种解决方案?
我需要测量计算着色器的时间.但当然这不是微不足道的.从OpenGL Wiki -我得到的性能,在着色器调用之前和之后使用glFinish()是有用的.但他们也说使用它并不好.是否有可能测量着色器的时间?反正有可能测量计算着色器的时间吗?
我的代码看起来像这样:
renderloop()
{
//(1)
//(2)
if(updateFunction) //this is done just one time at the beginning
{
//update Texture with a compute shader
//...
glDispatchCompute();
glMemoryBarrier(GL_ALL_BARRIER_BITS);
}
//(3)
//(1)
//use the texture to do some marching cubes rendering
}
Run Code Online (Sandbox Code Playgroud)
我想我必须插入glFinish()位置(1)并启动计时器(2)并将其停在(3).但我不确定它是否真的有效并且会产生正确的计时结果,因为在参考中他们谈论的是渲染而计算着色器不能渲染,不是吗?
还存在OpenGL Timer_Query,但我不确定它是如何工作的,也不知道它是否对我有用.这些东西对我来说是新的,我不确定我是否完全理解它.
这里的答案说,几乎不可能精确地测量代码的一部分.最好的方法是测量帧渲染时间,但我只需要帧渲染时间的计算着色器部分用于我的目的.
您认为最好的替代方案是什么?只测量整个帧渲染时间并使用它?或者您是否使用其他测量方法获得了更好的体验?
我想nth_element在一个类中使用我自己的排序函数(它应该可以访问对象的数据).目前,我正在做以下事情:
class Foo
{
public:
glm::vec3 *points;
int nmbPoints;
bool idxPointCompareX(int a, int b);
void bar();
}
bool Foo::idxPointCompareX(int a, int b)
{return points[a].x < points[b].x;)
void Foo::bar()
{
stl::vector<int> idxPointList;
for(int i = 0; i < nmbPoints; i++) idxPointList.push_back(i);
stl::nth_element(idxPointList.first(),idxPointList.first()+nmbPoints/2,idxPointList.end(), idxPointCompareX);
}
Run Code Online (Sandbox Code Playgroud)
当然,这不起作用,我得到错误:"必须调用非静态成员函数的引用".之后,我看了一下参考非静态成员函数必须调用,如何std::function用成员函数初始化?以及其他一些问题.我理解为什么这不起作用,但我不确定如何解决这个问题.
有人可以帮助我并告诉我如何解决这个问题吗?
opengl ×4
c++ ×3
glsl ×2
shader ×2
3d ×1
boost ×1
nth-element ×1
performance ×1
point-clouds ×1
qt ×1
quaternions ×1
stl ×1
trigonometry ×1