Question

Prenez cette fonction pour obtenir du temps comme un double utilisant 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);
}

L'envoyer à un shader nécessite une conversion pour flotter. La mantissa est débordée et est tronquée sur le chemin du shader.

Exemple:

Comme un double = 1330579093642.441895

Comme un flotteur = 1330579111936.000000

La valeur flottante est coincée à un seul nombre pendant une longue période en raison de la troncature.

Il semble également que même la valeur des secondes dans res.tv_sec est trop grande pour un flotteur, il est également tronqué sur le chemin du GPU.

Essayer de mesurer le temps depuis le lancement de l'application et je rencontre le même problème assez rapidement.

Alors, quelle est la meilleure façon d'obtenir une valeur de temps d'exécution dans un shader? Quelque chose de cross-plateforme dans le monde Linux (So iOS, Android, Linux).

Était-ce utile?

La solution

Vous êtes à court de précision de point flottante 32 bits dans votre mantissa. Le shader ne sera pas mieux en mesure de gérer ce manque de précision, car à moins que vous n'utilisiez GL 4.x avec un support à double précision, les shaders ne peuvent gérer que des flotteurs 32 bits.

Si vous exécutez une application si longtemps que les millisecondes débordent la précision du point flottant (qui nécessiterait ~ 107 Des millisecondes, soit environ 2,7 heures), alors vous devez trouver un moyen de gérer gracieusement cette situation. Exactement comment vous faites cela dépend exactement de ce que votre shader utilise cette valeur de temps.

La plupart des shaders n'ont pas besoin d'un moment réel en millisecondes. La grande majorité des processus de shader qui ont besoin d'un temps (ou quelque chose comme un temps) sont cycliques. Dans ce cas, vous pouvez simplement leur transmettre une valeur indiquant jusqu'où ils sont à travers un cycle particulier. Cette valeur, sur la plage [0, 1), est 0 lors du début du cycle, 0,5 au milieu, et atteint 1 à la fin.

Si votre processus de shader ne peut pas être paramétré, s'il a besoin d'un temps absolu, alors votre prochain pari est de passer deux Paramètres à virgule flottante. Fondamentalement, vous devez garder vos bits de débordement. Cela compliquera tous vos mathématiques impliquant le temps sur le GPU, car vous devez utiliser deux valeurs et savoir comment les greffer ensemble pour effectuer des mises à jour dans le temps. Encore une fois, la façon dont vous faites cela dépend de ce que vous faites dans votre shader.

Alternativement, vous pouvez envoyer votre temps dans des entiers non signés 32 bits, si votre matériel prend en charge GL 3.x +. Cela vous donnera quelques autres morceaux de précision, donc il tiendra le problème plus longtemps. Si vous envoyez votre temps comme dixièmes de millisecondes, vous devriez pouvoir obtenir environ 5 jours environ pour qu'il déborde. Encore une fois, cela compliquera tous vos mathématiques GPU, car vous ne pouvez pas simplement effectuer une conversion intra-float.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top