着色器时间均匀-clock_gettime被截断 [英] Shader Time Uniform - clock_gettime being truncated

查看:113
本文介绍了着色器时间均匀-clock_gettime被截断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用clock_gettime将此函数的时间增加一倍:

Take this function getting time as a double using 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);
}

将其发送到着色器需要转换为浮点型。尾数溢出,并且在通往着色器的途中被截断。

Sending it to a shader requires conversion to float. The mantissa is being overflowed and is truncated on the way to the shader.

示例:

= 1330579093642.441895

As a double = 1330579093642.441895

作为浮点数= 1330579111936.000000

As a float = 1330579111936.000000

浮点值长期停留在单个数字上由于时间的缩短。

The float value gets stuck at a single number for a long period of time due to the truncation.

似乎即使res.tv_sec中的秒值对于浮动也是很大的,在通往GPU的途中也被截断了。

It also seems even the value of seconds in res.tv_sec is to large for a float, it is also being truncated on the way to the GPU.

试图衡量自应用程序启动以来的时间,我很快遇到了同样的问题。

Trying to measure time since application launch and I run into the same problem rather quickly.

那么最好的方法是获取着色器的运行时间值? linux世界中的某种跨平台(因此IOS,Android,Linux)。

So what is the best way to get a running time value into a shader? Something cross platform in the linux world (so IOS, Android, Linux).

推荐答案

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

You have run out of 32-bit floating point precision in your mantissa. The shader will be no better able to deal with this lack of precision, because unless you're using GL 4.x with double-precision support, shaders can only handle 32-bit floats too.

如果运行应用程序的时间过长,以至于毫秒数溢出浮点精度(这需要〜10 7 毫秒,或大约2.7小时左右),那么您必须找到一个优雅地处理这种情况的方法。确切的操作方式取决于您的着色器使用此时间值的确切时间。

If you are running an application so long that milliseconds overflow floating point precision (which would require ~107 milliseconds, or about 2.7 hours or so), then you have to find a way for it to gracefully handle this situation. Exactly how you do that depends on exactly what your shader is using this time value for.

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

Most shaders don't need an actual time in milliseconds. The vast majority of shader processes that need a time (or something like a time) are cyclical. In which case you can simply pass them a value saying how far they are through a particular cycle. This value, on the range [0, 1), is 0 when at the beginning of the cycle, 0.5 in the middle, and reaches 1 at the end.

如果您的着色器进程无法参数化,如果确实需要绝对时间,那么您的下一个选择是传递两个浮点参数。基本上,您需要保留溢出位。这将使您在GPU上涉及时间的所有数学复杂化,因为您必须使用两个值并且知道如何将它们嫁接在一起以进行时间更新。同样,如何执行此操作取决于您在着色器中的操作。

If your shader process cannot be parametrized, if it does need an absolute time, then your next bet is to pass two floating-point parameters. Basically, you need to keep your overflow bits. This will complicate all of your math involving the time on the GPU, since you have to use two values and know how to graft them together to do time updates. Again, how you do this depends on what you're doing in your shader.

或者,如果您的硬件支持,则可以32位无符号整数发送时间GL 3.x +。这将为您提供更多的精度,因此可以解决更长的时间。如果您将时间发送为十分之一毫秒,那么在溢出之前,您应该能够获得大约5天左右的时间。同样,这将使您所有GPU的运算复杂化,因为您不能只进行从整数到浮点的转换。

Alternatively, you could send your time in 32-bit unsigned integers, if your hardware supports GL 3.x+. This will give you a few more bits of precision, so it will hold off the problem for longer. If you send your time as tenths of a millisecond, then you should be able to get about 5 days or so worth of time before it overflows. Again, this will complicate all of your GPU math, since you can't just do an int-to-float conversion.

这篇关于着色器时间均匀-clock_gettime被截断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆