En three.js podemos simplemente fusionar geometría para limitar la cantidad de llamadas de extracción y así aumentar el rendimiento. En una prueba simple con un material, podría dibujar 50,000 cubos + sombras @ 60fps en mi GPU GTX660. Sin la fusión de geometría, 5.000 cubos ya causaron un problema.
Me pregunto cómo preservar los beneficios de renderizar cada malla de cubo por sí misma. Por ejemplo, ¿cómo elegir una malla de cubo cuando todo se fusiona en una geometría? Por defecto, eso no es posible, por supuesto.
¿Existe alguna técnica común para este problema? Después de todo, tengo todos los objetos de malla no fusionados, incluso después de la fusión. ¿Entonces debe haber alguna forma de utilizarlos para recoger?
Lo que quiero hacer en pocas palabras
- SimCity como juego para aprender
- Cada casa es un cubo de malla
- Quiere renderizar 50,000 casas y poder agregar y quitar casas
- La selección de la casa mediante el cursor del mouse (selección) debe ser posible
Respuestas:
Ok lo tengo Después de fusionar toda la geometría, todavía tengo las mallas individuales en una matriz. Entonces, simplemente puedo usar estas mallas para la emisión de rayos, incluso si ni siquiera están renderizadas. Me tomó un tiempo darme cuenta de esto.
Para la selección utilizo esta implementación de octree: http://threejs.org/examples/#webgl_octree_raycasting
Esto reduce las pruebas de intersección por actualización de 50,000 a ~ 500. Sin el octree, los fps disminuirán considerablemente.
El casco de selección naranja que ves es en realidad la malla ahora representada (llamada de sorteo +1) con un material cambiado y un tamaño modificado.
Así que supongo que el siguiente paso es implementar algún tipo de partición de mapas. Es decir, divida la geometría fusionada en varias piezas. La razón de esto es que la geometría fusionada tiene una gran cantidad de vértices. Eso significa que si muevo el mapa 99% fuera de la pantalla, la tarjeta gráfica todavía tiene que procesar todos los vértices porque la geometría todavía está a la vista, al menos el 1%. Entonces, si está dividido, solo las piezas a la vista tienen que ser renderizadas.
fuente
Para elegir, también puede representar las ID de cada cubo a otro objetivo de representación y simplemente verificar cuál es el valor de ID en el cursor. El beneficio es que la selección es perfecta en píxeles y funciona eficientemente también para geometrías más complejas.
Si todos los objetos tienen la misma geometría, entonces podría usar el renderizado instanciado. Una secuencia define la geometría, mientras que otra define propiedades por instancia (por ejemplo, transformación). Para el sacrificio de Frustum, necesitaría compilar la secuencia de instancia de cada cuadro en función de la prueba de visibilidad. Si tiene una gran cantidad de objetos, es posible que desee colocar esos objetos en un octree flojo o algo para acelerar el sacrificio.
fuente
No estoy seguro de los detalles de three.js, pero en general OpenGL me viene a la mente dos posibles cerdos de rendimiento:
fuente
Otro enfoque que puede tomar es construir algún atributo de vértice en su geometría y poner lógica de resaltado en su sombreador de fragmentos. Esto es extremadamente útil cuando no desea tener dos copias de datos en la memoria, y tendrá más control sobre cómo se implementa el resaltado.
fuente