Fusionar geometría / malla sin perder beneficios


11

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

No estoy seguro de si esto es útil para usted, pero lo menciono por completo. Simplygon tiene un modelo de precios basado en regalías para desarrolladores independientes y puede hacer mucho de esta fusión y división de mallas en tiempo de diseño.
steeveeet

Respuestas:


11

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.

ingrese la descripción de la imagen aquí

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.

ingrese la descripción de la imagen aquí

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.


Muchas gracias por esta idea. He estado tratando de encontrar una manera de hacer esto también, ¡y creo que su solución aquí es excelente! Pregunta rápida: para su lista local de objetos (es decir, Three.Object3D's), ¿qué tipo de propiedades son necesarias para que funcione rayCaster.intersectObjects ()?
AlvinfromDiaspar

Muy bien hecho.
ClassicThunder

Tengo un problema similar, pero de alguna manera no puedo hacer que el raycasting funcione con r70. ¿Hiciste algo especial al crear y fusionar las cajas? Utilizo el siguiente código ( pastebin.com/PStaAF3P ) para crear y fusionar los nodos, pero ¿quizás falta algo para que funcione el raycaster?
fhahn

Pregunta rápida: estoy haciendo algo muy similar a usted (un mapa 3D basado en datos geoJSON). Con su método, cada vez que gira la cámara, ¿necesita también girar las mallas de construcción preexistentes? ¿O simplemente agrega los cuadros individuales a la escena pero no los procesa?
Spencer

@Spencer No no necesita rotar. Mantengo cuadros individuales en una matriz global y solo agrego geometría combinada a la escena. Luego puede hacer la emisión de rayos con el objeto en una matriz global, porque el emisor de rayos depende de la matriz de la cámara y de la posición de cada cuadro. Lo más probable es que no sea la mejor manera, esto fue solo una prueba de concepto para mí. No hacer tres.js más en este momento.
user990827

1

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.


0

No estoy seguro de los detalles de three.js, pero en general OpenGL me viene a la mente dos posibles cerdos de rendimiento:

  1. ¿Has considerado instancing? Solo necesitará una llamada de sorteo y usará menos VRAM.
  2. ¿Has analizado seriamente el algoritmo de selección? Si sus cubos tienen volúmenes delimitadores en una lista en lugar de un árbol, por ejemplo, eso explicaría una diferencia de esa magnitud.

0

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.