Comment puis-je intégrer la physique dans un monde généré procéduralement à partir d'un shader de géométrie?

10

Essentiellement, je veux supprimer la nécessité de générer un bruit cohérent du CPU vers le GPU. De là, je veux aussi générer le terrain pour un monde en trois dimensions en utilisant ce bruit comme densités en points de voxel. Après cela, je veux prendre ces densités et les polygoniser (générer des sommets) représentant le terrain du monde.

C'est bien et tout. Mais, je veux aussi déformer dynamiquement le monde en temps réel. Une fois arrivé à ce point, j'ai un problème à essayer de récupérer les sommets vers le CPU pour faire des choses comme la détection de collision et tous les calculs de jeu que je veux impliquer sur le CPU et non sur le GPU.

Donc, la question est: comment puis-je récupérer un sous-ensemble des sommets vers le CPU pour gérer les collisions, entre autres?

Et encore une question: existe-t-il un moyen facile de prendre un ensemble de sommets et d'en générer des indices sur le GPU?

Je ne sais pas trop quels types de shaders je devrais utiliser pour ces différentes choses. J'entends parler de personnes utilisant un pixel shader pour rassembler les densités, puis utilisant un geometry shader pour gérer la génération de terrain à partir des sommets, puis incorporant en quelque sorte un vertex shader pour effectuer les déformations dynamiques.

J'utilise C # 4.0, .NET 4.0 et XNA Game Studio 4.0.

Michael J. Gray
la source
1
Vous dites que vous utilisez un shader de géométrie dans le titre, mais vous dites également que vous utilisez XNA4.0, pour autant que je sache, XNA 4.0 nécessite DirectX 10 (pour faciliter le développement d'une plate-forme plus uniforme), mais ne prend en charge que les fonctionnalités SM3.0, donc pas de shader de géométrie. forums.create.msdn.com/forums/p/31369/178924.aspx
Roy T.
Et maintenant, je ne vais plus utiliser XNA ni retravailler mon design. Merci d'avoir fait remarquer cela. Je l'avais étudié et je n'avais pas réalisé cette limitation (pas de SM 4). Je suppose que la question demeure cependant, sans la considération de XNA. Donc, du point de vue de DirectX uniquement, existe-t-il un moyen de faire ce que je veux? Ou peut-être avec un vertex shader dans XNA?
1
Eh bien, XNA est toujours valide à utiliser, sauf si vous avez un cas de test éprouvé où les déformations et la génération sont trop lentes. Et que vous avez prouvé dans un autre cas de test que la génération + déformation du GPU, puis la récupération des données vers le CPU est plus rapide :)
Roy T.
En effet. Nous avons constaté que l'utilisation de XNA et de tout garder sur le CPU nous a donné environ 1 million de sommets en environ trois minutes sur un Core i7 avec 8 cœurs et 8 threads parallélisant plusieurs sections de terrain par thread. En essayant de le faire en temps réel et en espérant rendre le terrain avant que le joueur ne puisse le voir, nous avons atteint environ 20 images par seconde. Ainsi, un cas de test est définitivement en règle avec chacune des méthodes.
Michael

Réponses:

3

Étant donné que XNA ne prend pas en charge les shaders de géométrie, je vais y répondre comme si vous utilisiez DX 10. Vous avez essentiellement trois options.

Shaders de géométrie Les shaders de géométrie peuvent réellement modifier et ajouter des sommets à un tampon de vertex. Vous pouvez lire ceci dans le CPU. Je ne l'ai pas examiné, mais c'est certainement possible.

Utilisez simplement le CPU Deuxièmement, pourquoi ne pas simplement le calculer sur le CPU? Le fait qu'il s'exécute sur le GPU dans les shaders suggère que votre algorithme de déformation est localisable, c'est-à-dire que vous pouvez facilement générer uniquement les parties pertinentes pour votre vérification de collision.

Par exemple, j'ai fait un jeu de voile il y a quelque temps. L'océan a utilisé les vertex et les shaders de géométrie pour déformer l'eau avec des vagues. J'ai utilisé le même algorithme calculé sur le CPU sur seulement quelques points sous le bateau pour le mouvement du bateau dans les vagues. Je suis sûr que vous pourriez faire quelque chose de similaire pour votre carte de voxels.

Pixel shaders La dernière option, vous l'avez également mentionnée dans votre question: générer les densités dans le pixel shader et l'écrire dans une texture 3D. Vous pouvez y accéder à partir du CPU et des shaders sans danger. Le pixel shader est parfait pour cette tâche, mais cette méthode a beaucoup de frais généraux. Rendu de la texture du volume, ainsi que l'échantillonnage de l'intérieur dans le sommet et la géo. shaders, et avoir à lire la texture sur le CPU.

Je ne connais pas les détails de votre projet, mais j'utiliserais toujours le CPU pour cela. Par tous les moyens, calculez également les densités sur les shaders, mais restez à utiliser la carte graphique pour le rendu.

Hannesh
la source
Le principal problème que nous avions était la barrière GPU-CPU. Dans le sens de, une fois que nous avons généré et rendu le terrain sur le GPU, comment pouvons-nous déterminer à quoi ressemble le terrain du côté CPU pour faire des collisions et d'autres choses. Je suppose que votre idée de le garder sur le CPU est valide. Je veux dire, nous pouvons probablement optimiser un peu notre algorithme et générer moins de terrain. Je marquerai votre réponse comme la solution dans un jour ou deux pour voir si quelqu'un d'autre a une réponse. Merci d'avoir provoqué des pensées alternatives.
Michael J. Gray
Avec votre exemple de navigation, vous ne pourriez pas facilement connecter le résultat de la forme d'onde d'un bateau éclaboussant des vagues au GPU, n'est-ce pas?
deceleratedcaviar
1
Vous pouvez conserver le même système de rendu, c'est-à-dire générer et restituer le terrain sur le GPU, mais refléter les parties du terrain dont vous avez besoin sur le CPU. En utilisant le même algorithme et les mêmes paramètres, vous obtiendriez le même terrain sur le CPU que vous voyez à l'écran.
Hannesh
@Daniel Pas directement avec l'algorithme de vague, mais il est possible de déformer le maillage de l'eau en fonction du sillage du bateau avec une texture de déplacement que chaque bateau "traîne" derrière lui.
Hannesh
Ah! C'est une bonne idée :). Mais il ne prend probablement pas très bien en charge plusieurs motomarines.
deceleratedcaviar