2017-07-05 2 views
0

J'utilise instancing pour dessiner plusieurs fois le même quad, pour le sol dans un moteur de jeu. Chaque étage a des coordonnées de texture différentes en fonction de sa taille et mon problème est que toutes les instances utilisent les coordonnées de texture de la première instance.Différentes coordonnées de texture par objet lors de l'instanciation

enter image description here

Voilà comment je suis mise en mémoire tampon des données.

public static void UploadTextureCooridnates() 
{ 
    // Construct texture co-ordinate array 
    List<Vector2> textureCoords = new List<Vector2>(); 
    foreach (Floor floor in Floor.collection) 
    { 
     float xCoordLeft = 0; 
     float yCoordBottom = 0; 
     float yCoordTop = floor.scale.X; 
     float xCoordRight = floor.scale.Z; 

     textureCoords.Add(new Vector2(xCoordLeft, yCoordBottom)); 
     textureCoords.Add(new Vector2(xCoordRight, yCoordBottom)); 
     textureCoords.Add(new Vector2(xCoordRight, yCoordTop)); 

     textureCoords.Add(new Vector2(xCoordLeft, yCoordBottom)); 
     textureCoords.Add(new Vector2(xCoordRight, yCoordTop)); 
     textureCoords.Add(new Vector2(xCoordLeft, yCoordTop)); 
    }  
    Vector2[] texCoords = textureCoords.ToArray(); 

    // Buffer data 
    GL.BindBuffer(BufferTarget.ArrayBuffer, VBOtexcoordsInstanced); 
    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(texCoords.Length * Vector2.SizeInBytes), texCoords, BufferUsageHint.StaticDraw); 
    GL.EnableVertexAttribArray(1); 
    GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 0, 0); 
    GL.VertexAttribDivisor(1, 0); 
} 
+0

Si le sol est plat, il serait plus logique de le dessiner comme un quadruplé et d'échantillonner les données de texture en se basant sur les informations du pavé. –

Répondre

3

Si vous utilisez vraiment instanciation pour dessiner plusieurs quadriceps, vous devez avoir clairement:

  1. Un objet tampon contenant les positions d'un seul quad.
  2. Un mécanisme permettant d'obtenir des données par instance pour compenser ces positions.

Votre problème est votre attente. Vous instanciez avec des quads. Cela signifie que votre appel de rendu n'utilise que 4-6 sommets. Ce sera tout aussi vrai pour votre coordonnées de texture que vos positions.

Votre problème est que vous traitez les données par instance comme s'il s'agissait de données par vertex. Les coordonnées de texture changent avec chaque instance; par conséquent, ce sont des données par instance. Mais vous ne leur demandez pas d'instanciation, ils sont donc traités comme des données par vertex. Ainsi, seules les coordonnées de texture des 6 premiers sommets seront utilisées.

Bien sûr, vous ne pouvez pas non plus vraiment en faire des données par instance. Chaque paire vertex + instance a une valeur de coordonnée de texture distincte. Et l'instanciation ne fournit pas un moyen de le faire directement. Au lieu de cela, vous devrez utiliser gl_VertexID et gl_InstanceID pour extraire des données directement d'un objet tampon; soit un SSBO ou une texture tampon.

Et donc, votre problème est vraiment ceci:

J'utilise instanciation pour dessiner le même quad plusieurs fois

Arrêtez de faire ça. Ça ne vaut pas la peine. Il suffit de mettre les positions dans les données du tampon CPU. Utilisez des techniques de streaming de tampon appropriées, et votre performance sera raisonnable.

+0

Fait sens, et il sera facile de mettre les positions dans les données de tampon CPU pour les étages, mais pas pour les objets muraux, ce sont des modules individuels avec trim et autres géométrie. La raison pour laquelle je veux avoir différentes coordonnées de texture par instance est que les textures ne sont pas étirées lorsque les objets de la paroi sont mis à l'échelle le long d'un seul axe. Pouvez-vous suggérer une meilleure approche? –