2012-03-01 43 views
2

把这个功能让时间的双重使用clock_gettime:着色时间统一 - clock_gettime被截断

// return current time in milliseconds 
static double time_get_ms(void) 
{ 
    struct timespec res; 

#ifdef ANDROID 
    clock_gettime(CLOCK_REALTIME_HR, &res); 
#else 
    clock_gettime(CLOCK_REALTIME, &res); 
#endif 
    return (double)(1000.0*res.tv_sec + res.tv_nsec/1e6); 
} 

其发送到着色器需要转换为浮动。尾数正在溢出,并在到着色器的路上被截断。

实施例:

作为双= 1330579093642.441895

作为浮子= 1330579111936.000000

的浮点值被卡住在用于长时间的单个数字,由于截断。

它似乎甚至res.tv_sec秒的值是一个大的浮点数,它也被截断到GPU的路上。

尝试测量应用程序启动以来的时间,并且我很快遇到了同样的问题。

那么,什么是获得运行时间值到着色器的最佳方式?在Linux世界中有一些跨平台的东西(如IOS,Android,Linux)。

回答

4

您的尾数已经用完了32位浮点精度。着色器无法更好地处理这种精度不足的问题,因为除非您使用双精度支持的GL 4.x,否则着色器也只能处理32位浮点数。

如果你运行一个应用程序的时间超过浮点精度(这将需要约10毫秒或约2.7小时左右),那么你必须找到一种方法来适当地处理这个问题情况。你究竟是怎么做的,取决于你的着色器使用这个时间值。

大多数着色器不需要以毫秒为单位的实际时间。绝大多数需要一定时间(或类似时间)的着色器过程是周期性的。在这种情况下,您可以简单地向他们传递一个值,说明他们在特定的周期中有多远。该值在[0,1)范围内,在循环开始时为0,中间为0.5,结束时为1。

如果你的着色器进程不能被参数化,如果它确实需要一个绝对时间,那么你的下一个赌注是通过两个浮点参数。基本上,你需要保持你的溢出位。这会使涉及GPU时间的所有数学复杂化,因为您必须使用两个值并知道如何将它们移植到一起才能进行时间​​更新。同样,你如何做这取决于你在着色器中做什么。

或者,如果您的硬件支持GL 3.x +,则可以使用32位无符号整数发送时间。这会给你更多的精度,所以它会延长问题的时间。如果你的时间只有十分之一毫秒,那么你应该能够在它溢出之前花费大约5天左右的时间。同样,这会使所有的GPU数学复杂化,因为你不能只进行一个int-to-float转换。