Existe-t-il un moyen de générer des primitives dans un shader de géométrie sans aucune géométrie d'entrée?

17

Il y a quelques années, j'ai essayé d'implémenter ce Gem GPU dans OpenGL pour générer un terrain procédural 3D à l'aide de Marching Cubes . L'article suggère d'implémenter Marching Cubes dans un shader de géométrie pour une efficacité maximale. Cela signifie que je dois exécuter le shader une fois pour chaque voxel du domaine, et cela générera la géométrie entière dans cette cellule.

Un problème sur lequel je suis tombé était de savoir comment faire fonctionner le shader de géométrie sans avoir quoi que ce soit à rendre en dehors de ce shader. Ma solution (qui semblait plutôt hacky) était de rendre un point dans chaque cellule, de le jeter avec le shader de géométrie et d'émettre mes triangles à la place. Je n'ai jamais trouvé de solution appropriée et cette solution de contournement est restée dans le code final.

Alors, est-il possible de dire à OpenGL de commencer une passe de rendu à partir du shader de géométrie sans aucune géométrie d'entrée? Ou devrai-je toujours envoyer des points fictifs au GPU pour faire fonctionner les choses.

Martin Ender
la source

Réponses:

15

Non, il n'y a pas vraiment de moyen de le faire.

Une invocation de shaders de géométrie nécessite une primitive d'entrée et génère 0 ou plusieurs primitives de sortie. Sans primitive d'entrée, il n'y a pas vraiment de moyen d' invoquer le shader de géométrie . Bien sûr, vous pouvez étirer les limites du nombre maximal de primitives de sortie du shader de géométrie pour chaque primitive d'entrée (je ne connais pas les limites pratiques pour le moment, elles devraient être de l'ordre de milliers peut-être). Donc , vous pourriez peut - être générer 1024 triangles pour chaque point, mais vous devez toujours avoir un peu primitives d'entrée.

Ce dont vous n'avez pas besoin cependant, c'est d'une notion réelle de la géométrie. Vous n'avez pas vraiment besoin de rendre des points 3D à n'importe quel endroit raisonnable, ils pourraient aussi bien avoir juste quelques coordonnées abstraites d'index ou de texture ou quoi que ce soit comme attributs et pas nécessairement une position 3D significative. Personne ne dicte les attributs de vos sommets. Et vous pouvez même rendre des sommets sans aucun attribut . Mais vous devez rendre certains primitives pour invoquer le shader de géométrie, même si ces primitives n'ont pas d'attributs réels (la façon dont vous calculez ensuite votre géométrie de sortie dans le shader de géométrie est une question différente, cependant).

Mais ce que vous avez réellement fait, rendre un point pour chaque cellule de la grille et générer des triangles de cubes de marche pour cette cellule à partir de celle-ci, est exactement l'approche directe. Bien sûr, les attributs que cette cellule contient dépendent de vous, il peut s'agir d'une position 3D, d'un texcoord dans une texture 3D, peu importe, mais ce sont les cellules de la grille que vous rendez. Purement sémantique, vous ne "jetez" pas ces points et les "remplacez" par des triangles, vous "convertissez" chaque point en un ensemble de triangles. C'est exactement à cela que sert le shader de géométrie et il n'y a rien de "hacky" ou "inapproprié" à ce sujet. Personne ne dit que le shader de géométrie doit générer le même type primitif de sortie que celui entré pour être "correct" .


Ce que vous pouvez faire pour obtenir une manière largement sans entrée de rendre votre grille de voxels (et c'est peut-être ce que vous demandiez réellement) serait de simplement dessiner un ensemble de points sans attribution. Cela signifie que vous n'avez pas besoin de tableaux d'attributs du tout, désactivez-les tous et invoquez un simple glDrawArraysavec le nombre de cellules dont vous avez besoin. Ensuite, dans le vertex shader ou le geometry shader, vous pouvez générer l'index de cellule de grille 3D nécessaire avec un peu de magie d'index à partir de l'ID de vertex d'entrée (c.-à-d.gl_VertexID -à- , la seule information dont vous disposez), puis calculer la géométrie de vos cubes de marche à partir d'une recherche dans la texture du volume 3D (ou toute autre structure de données).

Donc, rétrospectivement, je devrais relativiser mon affirmation depuis le début: vous ne pouvez pas générer de primitives sans aucune primitive d' entrée , mais vous pouvez les générer sans aucune géométrie d' entrée .

Chris dit de réintégrer Monica
la source