Comment puis-je stocker des valeurs positives et négatives dans une texture?
Je crée un programme dans lequel j'utilise le GPU pour faire des calculs (via des shaders de fragments) et j'ai besoin de stocker des valeurs signées dans des textures.
Ma texture est initialisée avec GL_FLOAT, comme ceci:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
Et d'après ce que je comprends d'OpenGL, les texels individuels doivent être dans la plage [0,1] lorsque GL_FLOAT est utilisé (lorsque j'ai expérimenté avec glClear, mes valeurs seraient écrêtées dans cette plage). Donc, ce que j'ai fait jusqu'à présent, c'est redimensionner mes valeurs jusqu'à la plage [-1,1] en fonction de leur plage réelle, puis la convertir en [0,1] avant de l'écrire dans la texture. Le shader suivant qui doit travailler avec les données lit la valeur du texel et la déplace vers [-1,1] avant de continuer et ainsi de suite ...
Ma question est la suivante: est-ce la bonne façon de gérer les valeurs négatives? Je suis presque sûr que les conversions répétées provoquent l'accumulation d'erreurs fp, ce qui n'est évidemment pas bon pour la précision.
Je vous remercie
Réponses
Voir aussi: Différence entre format et format interne
Le format interne (troisième paramètre de glTexImage2D
) décide de la manière dont le GPU stocke et interprète ces valeurs, et non le paramètre de typeglTexImage2D
(avant-dernier paramètre). Ce paramètre décide de la manière dont le pilote doit interpréter votre mémoire client / hôte lors du téléchargement vers la texture, que vous n'utilisez actuellement pas en utilisant nullptr
.
Vous pouvez utiliser le signé 8 bits GL_RGBA8_SNORM
ou virgule flottante 16 bits GL_RGBA16F
ou 32 bits à virgule flottante de GL_RGBA32F
taille format interne pour la texture.
En règle générale, vous devez toujours utiliser un format interne de taille pour être explicite sur ce que vous voulez et obtenez.
Voir le tableau sur: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
Ainsi, si vous n'avez besoin que d'une résolution de 8 bits et de valeurs comprises entre [-1, 1], vous pouvez utiliser:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8_SNORM, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
L'avant-dernier argument n'est en fait pas pertinent, car nous ne téléchargeons aucune donnée de texel dans la texture.