Si solo necesita normales por cara, y si sus texcoords para una cara son estrictamente 0/0, 0/1, 1/0, 1/1 (o similar para adaptarse a su diseño), entonces puede construir un cubo con 8 verts y 30 (tira con reinicio) o 36 (lista) índices. Obtenga las normales y los códigos de texto utilizando una búsqueda de matriz constante basada en SV_VertexID en su sombreador de vértices.
Hacer esto significa que ni siquiera necesita incluir texcoords o normales en su búfer de vértices, lo que le dará aún más ahorro de memoria.
Yendo más lejos, aún podría llegar a 24 verts por cubo, pero también usar instancing. Cada cubo tendría un tamaño fijo en su búfer de vértices (1x1x1) y tendría un factor de escala y una posición (suponiendo que sus cubos no giren, una matriz si lo hacen) como datos por instancia. En el caso no rotativo, tiene un costo único de 24 verts, pero luego cada cubo solo necesita 6 flotadores para especificar por completo. En el caso de rotación, está viendo 16 flotadores, pero incluso eso es un ahorro sustancial (es más probable que se produzca un cuello de botella en las transformaciones de la matriz en este caso, para el caso no giratorio que construye una matriz sobre la marcha) su sombreador de vértices, incluso si está hecho por vértice, es tan estúpidamente rápido que ni siquiera necesita preocuparse por eso).
Para texturas por cara, solo use una matriz de texturas. Debe asegurarse de que cada una de esas texturas en la matriz sea del mismo tamaño, por supuesto, y aún tendrá que dividir su lote actual si la matriz en sí misma necesita cambiar, pero de lo contrario hará el trabajo bien. Agregue un tercer texcoord a su definición de vértice que define el segmento de matriz que se utilizará para cada cara.
No necesita un GS con esto, y debe ejecutarse más rápido que usar uno, ya que tener habilitada la etapa de sombreado de geometría impondrá una sobrecarga adicional.
Tengo un código de referencia en mi motor que solo dibuja un montón de cubos usando este método, y puedo masticar fácilmente más de 300,000 cubos sin dejar de limpiar 60 fps, en una GPU relativamente baja, y sin hacer nada más para optimizar el proceso . Es cierto que no los estoy iluminando ni texturizando, pero tengo habilitada la mezcla alfa, desactivado el descarte de la cara posterior y, en general, se equilibra con mi parte de "no hacer nada más para optimizar", por lo que debería darle una idea razonable del tipo de estadio puede golpear con este método.