2011-09-23 3 views
0

J'ai une surface dynamique dans WebGL, qui est animée dans vertex shader. Je veux que d'autres objets interagissent avec cette surface (par exemple, un objet roulant sur un terrain dynamique). Quelle est la meilleure façon de faire cela? Est-ce que tous ces calculs devraient être faits sur le CPU? Y at-il un moyen de calculer ce genre de choses sur GPU? Fondamentalement, ce que je veux est vertex shader avec l'accès à d'autres vertices (déjà transformés) - ce serait parfait.Interactions de géométrie WebGL

Répondre

1

Je ne suis pas sûr que vous pouvez faire cela sur le shader, malheureusement. Le plus proche que je peux penser est de passer dans un deuxième ensemble d'attributs, mais le nombre de vertex devrait être identique, et vous pourriez seulement valider un sommet d'un modèle contre un sommet avec le même index de l'autre modèle (parce que vous n'avez aucun moyen de les parcourir tous). D'une certaine manière, je ne pense pas que ce soit ce que vous cherchez.

Votre meilleur pari est d'implémenter ce genre de choses (détection de collision, par exemple) sur la CPU. Il est très lent en JavaScript, et vous devrez réfléchir longuement au meilleur algorithme à utiliser pour votre scène, mais c'est la seule chose à laquelle je peux penser qui fonctionnera. Un bon début serait d'utiliser un partitionnement spatial (exemples: octree, BSP -- binary space partitioning -- tree). Je n'ai pas encore fait d'analyse comparative, mais j'ai l'impression que les arbres BSP seraient plus efficaces que les octrees dans la plupart des scènes JavaScript. Il y a souvent moins de contrôles à effectuer globalement, et potentiellement beaucoup moins de récursivité. En outre, les arborescences BSP vous offrent la possibilité presque unique de traiter la géométrie d'avant en arrière ou d'avant en arrière par rapport à n'importe quel point arbitraire de l'espace sans devoir trier et trier constamment la géométrie. L'inconvénient des arborescences BSP (et octrees à une étendue moindre mais non triviale) est que leur géométrie doit rester statique. C'est-à-dire que déplacer des triangles individuels à la volée ne fonctionne pas très bien avec ces arbres, car alors la géométrie doit être re-triée. Je ne pense pas que la nature statique du partitionnement spatial soit un problème particulièrement gênant si les animations de vos mailles sont relativement simples, légères et prévisibles (comme un drapeau agité dans le vent), mais si elles sont plus complexes (comme un effritement). construire ou tomber des roches), alors ces types de partitions spatiales peuvent ne pas être viable pour vous du tout.

Mise à jour: Si vos modèles sont constitués de triangles partiels et partiellement dynamiques, tels que les éoliennes (dont les tours sont statiques et les ailettes dynamiques), vous pouvez utiliser le partitionnement spatial pour les parties statiques. prendre des coups de performance inutiles pour les triangles dynamiques, et récolter les avantages du partitionnement spatial pour les triangles qui ne bougent pas trop.

Mise à jour: En fait, il y a une façon de "faire" cela au moins en partie sur le shader. Spécifiquement en référence à votre exemple d'un objet roulant sur un terrain dynamique, vous pouvez rendre ce terrain dynamique à un framebuffer hors écran, puis tracer la position de l'objet sur le même framebuffer, et utiliser readpixels() pour lire à la hauteur du terrain. cette position. Cela ne fonctionnerait que pour les cartes de hauteur, et le framebuffer devrait évidemment être mis à jour chaque fois que le terrain change (si jamais). Cependant, ce serait une manière relativement simple de voir à quel point l'objet devrait être positionné sur un terrain dynamique sans avoir à faire la génération de terrain lui-même sur le CPU. Cependant, ce ne serait pas une véritable détection de collision, et l'objet serait encore sujet à d'autres problèmes (comme avoir une roue sur ou sous le terrain et une roue dans les airs). Vous pourriez contourner ces problèmes mais la solution serait non triviale, impliquant probablement plusieurs vérifications sur les données du framebuffer.