Comment générer un nombre aléatoire dans HLSL?
Je demande parce que je veux essayer le tracé de rayons gpu . Vous devez générer des directions aléatoires dans un pixel shader. Je veux donc randFloat()
, où le résultat est un nombre aléatoire entre -1 et +1.
Aussi, quel est le problème avec l' instruction de bruit hlsl ? Les documents indiquent qu'il a été supprimé de HLSL 2.0 et versions ultérieures. Pourquoi ?
J'ai lu une approche où vous remplissez une texture avec des valeurs aléatoires, puis avez une coordonnée de texture dans chaque sommet qui a un index dans cette texture. Mais c'est par sommet , j'ai besoin d'une instruction que je peux appeler dans le pixel shader. De plus, cette approche nécessite de "réamorcer" les texcoords par sommet si vous voulez des valeurs différentes pour chaque trame, et cela nécessite une mise à jour du tampon de sommet chaque trame (ce qui peut être coûteux!)
Avec des détails, comment pouvez-vous générer à moindre coût un nombre aléatoire sur le GPU?
Réponses:
Les nombres pseudo aléatoires dans un pixel shader ne sont pas faciles à obtenir. Un générateur de nombres pseudo aléatoires sur le CPU aura un état dans lequel il lit et écrit à la fois, à chaque appel à la fonction. Vous ne pouvez pas faire cela dans un pixel shader.
Voici quelques options:
Utilisez un nuanceur de calcul au lieu d'un nuanceur de pixels - ils prennent en charge l'accès en lecture-écriture à un tampon, de sorte que vous pouvez implémenter n'importe quel PRNG standard.
Échantillon d'une ou plusieurs textures contenant des données aléatoires, basées sur un paramètre comme la position de l'espace à l'écran. Vous pouvez également faire quelques calculs sur la position avant de l'utiliser pour rechercher la texture, ce qui devrait vous permettre de réutiliser la texture si les calculs impliquent une constante de shader aléatoire par appel.
Trouvez une fonction mathématique de la position de l'espace à l'écran, qui donne des résultats «assez aléatoires».
Une recherche rapide sur Google a trouvé cette page avec ces fonctions:
la source
Voici comment je génère des nombres pseudo-aléatoires pour mes effets de particules avec un shader de calcul. Je ne sais pas à quel point ce code est vraiment aléatoire, mais il fonctionne assez bien pour mes besoins.
La clé pour donner à chaque noyau GPU sa propre séquence aléatoire est de fournir au shader de calcul une graine aléatoire initiale à partir du CPU. Chaque noyau utilise ensuite cette graine pour faire tourner le générateur de nombres en utilisant son identifiant de thread comme nombre. À partir de là, chaque thread doit avoir sa propre graine unique pour générer des valeurs uniques.
la source