Comment faire voir les blocs par le joueur?

15

J'écris un jeu de type Minecraft en utilisant le moteur Ogre et j'ai un problème. Je dois optimiser mon jeu, car quand j'essaye de dessiner 10000 blocs, j'ai 2 FPS ... Donc, j'ai eu l'idée que les blocs s'affichent de l'avion et de cacher les blocs invisibles. Mais j'ai un problème - comment savoir quels blocs à la fois sont visibles pour le joueur?

Et - si vous connaissez d'autres méthodes d'optimisation pour un tel jeu, écrivez quoi et comment les utiliser dans Ogre.

m4tx
la source

Réponses:

16

Eh bien, Ogre implémente déjà l'abattage du tronc (qui ne dessine essentiellement rien qui ne puisse pas être vu de la caméra) mais je pense que votre problème est différent.

Vous ne devriez pas vraiment afficher 10000 blocs, ce qui est communément fait (ou du moins, dans les quelques clones minecraft basés sur Ogre3d que j'ai vus (dont j'en fais un aussi), et dans l'original) crée un maillage ( d'une région NxNxN de morceaux) dont les faces externes des cubes sont représentées. Autrement dit, lorsque vous mettez 2 cubes côte à côte, les 2 faces se touchant ne peuvent pas être vues et n'ont donc pas besoin d'être dessinées.

Ces visages doivent également être dessinés dans quelque chose comme ceci: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=DynamicGrowingBuffers car les cartes vidéo modernes préfèrent un maillage de 100000 polygones contre 1000 mailles de 100 polygones.

Elva
la source
10

Il y a deux aspects à ce problème. Premièrement, comment dessinez-vous vos 10000 blocs? Les dessinez-vous réellement comme 10000 objets séparés? Si c'est le cas, il s'agit presque certainement de votre goulot d'étranglement, pas du manque d'abattage par occlusion. Vous devez regrouper ces blocs en un plus petit nombre de mailles (peut-être quelques milliers par maillage) afin de réduire les appels de tirage.

Quant à votre question réelle, il existe trois types d'abattage d'occlusion qui vous viennent à l'esprit.

1) Blocs en dehors du tronc de vue. Cela signifie des blocs qui sont derrière vous ou deux sur le côté. Ogre les supprime déjà via la suppression des vues tronconiques.

2) Des blocs qui sont «souterrains» ou complètement entourés par d'autres blocs de sorte qu'ils ne peuvent jamais être vus sous aucun angle. Vous pouvez les identifier en regardant les blocs voisins de taille. S'ils sont tous solides, votre bloc est caché. Le GPU ne devrait même jamais entendre parler de ces blocs - ils doivent être ignorés lorsque vous construisez le maillage qui représente votre surface.

3) Les blocs qui sont en surface et peuvent être vus de certaines positions dans le niveau, mais qui sont actuellement cachés par une colline (ou quelque chose). C'est le cas le plus délicat que je n'ai pas abordé moi-même, mais il y a de fortes chances que des requêtes d'occlusion matérielle puissent être utilisées pour ce cas.

C'est un plug sans vergogne, mais j'ai une bibliothèque assez mature que plusieurs personnes utilisent pour développer des clones Minecraft, dont certains utilisant Ogre. Vous définissez le contenu du volume et il génère le maillage de surface que vous pouvez ensuite rendre. Voici la page d'accueil:

http://www.thermite3d.org/

Et voici une vidéo du projet de quelqu'un d'autre qui l'utilise:

http://www.youtube.com/watch?v=Jju6WRPEK7o

David Williams
la source
4

Vous pouvez utiliser la suppression de face arrière pour supprimer les sommets et leurs pixels associés qui ne font pas face au lecteur. La mise en mémoire tampon de la profondeur devrait prendre soin du reste. Les blocs de 10k ne sont vraiment pas beaucoup, mon 5770 peut rendre 100k verts à 1500fps. Je pense que vous faites quelque chose d'autre de mal.

DeadMG
la source
Je suis d'accord. C'est probablement un problème avec autre chose.
Notabene
1

Si vous avez 10000 objets séparés, le goulot d'étranglement est probablement le nombre primitif, pas le sommet, le polygone ou le remplissage. Faites cuire vos objets en un plus petit nombre d'objets polygones supérieurs pour plus de vitesse.

Minecraft a un concept de blocs de cubes, mais je ne trouve pas la référence pour le moment.

Voici également mes expériences sur le dessin de tonnes de cubes avec différentes techniques. N'inclut pas (encore) la cuisson.

Jari Komppa
la source
0

Ce que je fais, c'est après avoir créé mon tableau de blocs, mais avant de créer les sommets, j'exécute un sous appelé UpdateBlockVisiblility.

Le sous vérifie simplement les voisins du bloc et met à jour le booléen facevisible des blocs en conséquence.

#define BLOCKFACE_NORTH 0

#define BLOCKFACE_SOUTH 1 

etc etc etc

if(IsBlockAt(NorthOfBlock))
  Blocks[Whatever].facevisible[BLOCKFACE_NORTH] = false;

Ensuite, je ne crée les sommets du visage que s'il est visible! Facile :)

BMW
la source