Dans mon moteur, je crée un terrain infini en utilisant l'algorithme de bruit Perlin calculé sur CPU.
La création d'un terrain se déroule comme suit:
- Si la caméra est proche d'un patch non chargé, créez-le
- Calculer un réseau de bruit 513x513 avec des limites données
- Calcul des normales, tangentes, binormales, indices
- Passer des données à vbo
Avantages:
- Ne doit être rendu qu'en cas de besoin
- Collision facile à réaliser
Con
- 64 correctifs 513x513 lents sont créés en 3,1s (un thread). Pour chaque tuile ~ 20ms de création de bruit, ~ 25ms sommets, normaux, tangents, bitangents, indices. Lorsque la caméra se déplace rapidement, l'utilisateur peut remarquer un chargement de tuiles.
- consommant de la mémoire ???
Maintenant, je me demandais comment accélérer cela en générant du terrain complètement sur GPU Mais il y a quelques doutes:
- Si les shaders exécutent chaque trame, cette perte de puissance de calcul n'est-elle pas pour calculer le bruit encore et encore? Cela peut être évité en écrivant le résultat dans la texture RBGA et utilisé plus tard dans le vertex shader pour le déplacement, mais augmente l'utilisation de la mémoire. Par contre si la création est super rapide, seules les tuiles visibles doivent rester en mémoire. Cependant, le détachement du tampon provoque une synchronisation gpu-cpu qui peut ralentir l'application (ai-je raison?)
- Si le terrain n'est qu'une grille plate déplacée par un vertex shader, le même travail doit être effectué sur le CPU pour calculer la hauteur et la normale à un point donné pour la collision.
- Ce n'est qu'un concept, mais pour accélérer le tout, je pensais à projeter la grille sur la fenêtre de façon à n'utiliser qu'une quantité minimale de sommets. Pensez-vous que cela fonctionnerait?
Ma dernière question est:
Quelle est la meilleure technique / la plus rapide / la plus largement utilisée pour créer un terrain infini sur GPU?
Réponses:
Eh bien, si je devais essayer d'utiliser le GPU pour une telle chose, je pense que j'irais pour compute / opencl / cuda.
Cependant, indépendamment de l'utilisation du GPU ou du CPU (ce que je fais réellement), je le ferais de manière asynchrone, décidant que vous avez besoin d'un nouveau terrain pour la trame actuelle est probablement trop tard (par exemple, considérez 1000ms / 60 = 16.666ms, et le cadre entier veut s'insérer dans cela).
Commencez à générer (ou à charger à partir de fichiers compressés) un terrain sur un thread de travail, et à le rendre disponible pour le reste du jeu et à le rendre une fois que ce travailleur a terminé, généralement ce sera la prochaine image, ou peut-être l'image suivante, donc le l'utilisateur ne remarquera pas vraiment la différence, mais cela rend les choses plus fluides.
la source