Dans three.js, nous pouvons simplement fusionner la géométrie pour limiter la quantité d'appels de tirage et ainsi augmenter les performances. Dans un test simple avec un matériau, j'ai pu dessiner 50.000 cubes + ombres @ 60fps sur mon GPU GTX660. Sans fusion de géométrie, 5.000 cubes ont déjà causé un problème.
Je me demande comment conserver les avantages du rendu de chaque maillage de cube par lui-même. Par exemple, comment choisir un maillage de cube lorsque tout est fusionné en une seule géométrie? Par défaut, ce n'est bien sûr pas possible.
Existe-t-il une technique courante pour ce problème? Après tout, j'ai tous les objets maillés non fusionnés même après la fusion. Il doit donc y avoir un moyen de les utiliser pour la cueillette?
Ce que je veux faire en bref
- SimCity comme un jeu à des fins d'apprentissage
- Chaque maison est un maillage cube
- Vous voulez rendre 50 000 maisons et pouvoir ajouter et supprimer des maisons
- La sélection de la maison via le curseur de la souris (cueillette) doit être possible
Réponses:
OK j'ai compris. Après avoir fusionné l'ensemble de la géométrie, j'ai toujours les maillages individuels dans un tableau. Je peux donc simplement utiliser ces maillages pour le raycasting, même s'ils ne sont même pas rendus. Cela m'a pris un certain temps pour réaliser cela.
Pour la cueillette, j'utilise cette implémentation octree: http://threejs.org/examples/#webgl_octree_raycasting
Cela réduit les tests d'intersection par mise à jour de 50 000 à ~ 500. Sans l'octree, les fps diminueront fortement.
La coque de cueillette orange que vous voyez est en fait le maillage maintenant rendu (+1 appel de tirage) avec un matériau changé et une taille modifiée.
Donc je suppose que la prochaine étape consiste à implémenter une sorte de partitionnement de carte. Autrement dit, divisez la géométrie fusionnée en plusieurs parties. La raison en est que la géométrie fusionnée a une grande quantité de sommets. Cela signifie que si je déplace la carte à 99% hors écran, la carte graphique doit toujours traiter tous les sommets car la géométrie est toujours en vue, au moins 1% de celle-ci. Donc, s'il est cassé, seules les pièces en vue doivent être rendues.
la source
Pour la sélection, vous pouvez également restituer les ID de chaque cube à une autre cible de rendu et vérifier simplement quelle est la valeur de l'ID au niveau du curseur. L'avantage est que le prélèvement est parfait au pixel près et fonctionne efficacement aussi pour une géométrie plus complexe.
Si tous les objets ont la même géométrie, vous pouvez utiliser le rendu instancié. Un flux définit la géométrie, tandis qu'un autre définit les propriétés par instance (par exemple transformation). Pour l'abattage de troncs, vous devez créer le flux d'instance à chaque image en fonction du test de visibilité. Si vous avez une grande quantité d'objets, vous souhaiterez peut-être placer ces objets dans un octree lâche ou quelque chose pour accélérer l'abattage.
la source
Je ne suis pas sûr des détails de three.js, mais deux porcs de performances possibles me viennent à l'esprit en général OpenGL:
la source
Une autre approche que vous pouvez adopter consiste à créer un attribut de sommet dans votre géométrie et à mettre une logique de surbrillance dans votre shader de fragment. Ceci est extrêmement utile lorsque vous ne voulez pas avoir deux copies de données en mémoire, et vous aurez plus de contrôle sur la façon dont la mise en évidence est implémentée.
la source