Three.js: Solicitud de función: aumentar el rendimiento de detección de colisiones de raycaster a través de árboles de búsqueda espacial

Creado en 11 dic. 2017  ·  36Comentarios  ·  Fuente: mrdoob/three.js

He creado una aplicación de realidad virtual similar a WebVR-Vive-Dragging que permite interactuar con numerosos objetos 3D mediante controladores de realidad virtual. Esto significa que un usuario puede agarrar un objeto con un controlador VR y puede moverlo o escalarlo.

Problema : cuando hay objetos 3D complejos en la escena, es decir, THREE.Mesh objetos que tienen geometrías con una gran cantidad de vértices, la emisión de rayos durante la detección de colisión se vuelve muy lenta. Por lo tanto, el problema es la complejidad de la geometría de un objeto.

Hay estructuras de datos de árbol para una búsqueda espacial rápida, como Octtree o R-Tree . Encontré threeocttree que permite dividir una geometría en partes más pequeñas, pero parece que está un poco desactualizado (Three.js r60).

Por lo que veo, en el método THREE.Mesh del objeto raycast ya hay algunas optimizaciones de rendimiento (marcando primero el cuadro delimitador y la esfera antes de hacer el raycast real). ¡¿Tal vez tendría sentido tener otra etapa de verificación de este tipo usando árboles de búsqueda espacial?! ¿Qué piensas?

Saludos cordiales

Enhancement

Comentario más útil

He sugerido que el índice espacial se incluya en threejs en el pasado. Ha habido algún trabajo en esta dirección, y el ejemplo existente de oct-tree es uno de ellos. En última instancia, creo que es la falta de interés de la comunidad central con respecto a tener esta funcionalidad como ciudadano de primera clase en tres.

Estaría feliz de donar mi código BVH al proyecto, si hay suficiente interés e intención de incluirlo en la distribución principal (no ejemplos).
Mi código se centra en 2 aspectos:

  • escenas dinámicas

    • inserción rápida

    • eliminación rápida

    • reacondicionamiento (capacidad para que los nodos cambien de forma sin tener que volver a insertarlos)

  • velocidad de consulta

Tengo 2 implementaciones:

  • BinarioBVH

    • muy compacto, usando ByteBuffer

    • combinación de tipos UintX y FloatX a través de DataView

    • genial para la serialización

    • se puede comprimir usando herramientas estándar como la biblioteca lzma

    • inmutable

    • la velocidad de construcción está altamente optimizada

    • solo funciona para BufferGeometry

    • optimización SAH

    • consultas de rayos

  • BVH

    • El árbol de objetos, como consecuencia, es mucho más grande que la implementación binaria.

    • mudable

    • inserción rápida a granel

    • inserción rápida de un solo artículo

    • reacondicionamiento

    • implementaciones transversales de pila, recursivas y sin pila (diferentes características de rendimiento)

    • optimización SAH

    • Frustum consultas

    • Consultas de rayos

Personalmente, no puedo vivir sin un índice espacial, es una diferencia entre el rendimiento n^2 y log(n). Por ejemplo, en mi proyecto actual, las siguientes partes se basan en el índice espacial:

  • sistema de follaje (árboles, flores, arbustos, etc.)
  • toda la colocación de objetos (personajes y casas)
  • elegir (utilizado en interacciones, como clics del mouse)

http://server1.lazy-kitty.com/komrade

el terreno tiene polígonos de aproximadamente 1 m, y colocar miles de árboles y ejecutar ray-casts en tiempo real es simplemente imposible, especialmente para dispositivos de gama baja.

Todos 36 comentarios

A riesgo de decir lo obvio, pero ¿ha probado la versión de threeocttree que ya está en el repositorio ( examples/js/Octree.js )?

No voto por un uso fijo de árboles de búsqueda espacial en three.js . La sobrecarga/complejidad de dichos algoritmos compensa la ganancia de rendimiento en muchas aplicaciones.

marcando el cuadro delimitador y la esfera primero antes de hacer raycast real

Esto es razonable y debería ser suficiente. Si los usuarios necesitan más rendimiento en el contexto de casos de uso más avanzados, pueden usar el ejemplo mencionado como punto de partida. Octrees podría ser una buena opción. Pero nunca he visto una solución R-Tree en aplicaciones 3D interactivas porque su enfoque es bastante sofisticado (el algoritmo realiza datos en lugar de dividir el espacio).

Hola y gracias por sus respuestas,
@ Mugen87 Estoy de acuerdo en que muchos casos de uso no requieren búsquedas tan rápidas. Sin embargo, al tener un mecanismo para interactuar con objetos 3D (y supongo que ese es el caso para el que se usa principalmente), el paso de THREE.Raycaster de marcar primero el cuadro delimitador/esfera (que estoy totalmente de acuerdo en ser razonable ) en, digamos, tiempo constante a un esfuerzo de tiempo lineal cuando hacer el raycast real es bastante grande. Podría imaginar una especie de "árbol de búsqueda por geometría" en lugar de un árbol de búsqueda global. Siempre que la geometría no cambie (a menudo, las transformaciones son mucho más probables que los cambios de geometría), no es necesario actualizar el árbol de búsqueda.

Por eso pensé que este tipo de optimización mediante árboles de búsqueda espacial podría ser una parte más integral de three.js . Pero también entiendo que esto genera una complejidad y una sobrecarga adicionales.

@moraxy , echaré un vistazo a la versión de ejemplo. Solo quería saber si tal característica tendría sentido.

Gracias de nuevo y un saludo

Tal vez se podría integrar un árbol de búsqueda más simple en THREE.BufferGeometry . Por ejemplo, una llamada a computeBoundingBox también podría generar una especie de árbol de búsqueda de solo lectura que haga referencia a los vértices correspondientes. Dado que THREE.BufferGeometry es

más adecuado para objetos estáticos en los que no es necesario manipular mucho la geometría después de instanciarla

este árbol de búsqueda no necesita ser cambiado después de inicializarlo. Esto reduciría algunos gastos generales para actualizar/eliminar. Un Octtree sería un buen punto de partida ( concepto similar en BabylonJS ).

más adecuado para objetos estáticos en los que no es necesario manipular mucho la geometría después de instanciarla

FWIW, no creo que sea una declaración verdadera.

Cita de @WestLangley de la documentación de THREE.BufferGeometry

Documentación TRES.BufferGeometry

Probablemente debería eliminarse; en cualquier caso, no creo que se trate de ningún tipo de declaración técnica, sino que significa que es más difícil para el usuario manipular la geometría después de haberla creado.

Probablemente debería ser eliminado

Definitivamente.

Acabo de implementar un mejor método para emitir rayos en PlaneBufferGeometry. Uso el parámetro lejano y encuentro la primera y la última posición del índice. Esto funciona en planebuffer porque la matriz de índice está en orden x/y. Una vez fuera del cuadro delimitador x/y, todas las colisiones deben estar fuera del rango lejano. ¿Hay algún deseo de cometer esto en alguna parte? La implementación actual es específica para mi caso de uso, pero estaría dispuesto a intentar hacer algo más genérico si lo desea. Pude reducir significativamente mi rendimiento de transmisión de rayos en un avión grande Buffer (2.5 segundos a 10 ms)

@kpetrow Creo que los ejemplos de three.js octtree son adecuados. Por supuesto, eres libre de compartir tu código en GitHub si crees que sería útil para otros.

He sugerido que el índice espacial se incluya en threejs en el pasado. Ha habido algún trabajo en esta dirección, y el ejemplo existente de oct-tree es uno de ellos. En última instancia, creo que es la falta de interés de la comunidad central con respecto a tener esta funcionalidad como ciudadano de primera clase en tres.

Estaría feliz de donar mi código BVH al proyecto, si hay suficiente interés e intención de incluirlo en la distribución principal (no ejemplos).
Mi código se centra en 2 aspectos:

  • escenas dinámicas

    • inserción rápida

    • eliminación rápida

    • reacondicionamiento (capacidad para que los nodos cambien de forma sin tener que volver a insertarlos)

  • velocidad de consulta

Tengo 2 implementaciones:

  • BinarioBVH

    • muy compacto, usando ByteBuffer

    • combinación de tipos UintX y FloatX a través de DataView

    • genial para la serialización

    • se puede comprimir usando herramientas estándar como la biblioteca lzma

    • inmutable

    • la velocidad de construcción está altamente optimizada

    • solo funciona para BufferGeometry

    • optimización SAH

    • consultas de rayos

  • BVH

    • El árbol de objetos, como consecuencia, es mucho más grande que la implementación binaria.

    • mudable

    • inserción rápida a granel

    • inserción rápida de un solo artículo

    • reacondicionamiento

    • implementaciones transversales de pila, recursivas y sin pila (diferentes características de rendimiento)

    • optimización SAH

    • Frustum consultas

    • Consultas de rayos

Personalmente, no puedo vivir sin un índice espacial, es una diferencia entre el rendimiento n^2 y log(n). Por ejemplo, en mi proyecto actual, las siguientes partes se basan en el índice espacial:

  • sistema de follaje (árboles, flores, arbustos, etc.)
  • toda la colocación de objetos (personajes y casas)
  • elegir (utilizado en interacciones, como clics del mouse)

http://server1.lazy-kitty.com/komrade

el terreno tiene polígonos de aproximadamente 1 m, y colocar miles de árboles y ejecutar ray-casts en tiempo real es simplemente imposible, especialmente para dispositivos de gama baja.

Me gustaría ver algo que optimice Raycast. ¿Hay espacio para la optimización sin añadir complejidad? Octtree requiere toda la biblioteca nueva, con todos los nuevos agregados y actualizaciones, etc.

Una cosa que noto es que una vez que una geometría se convierte en una matriz de búfer indexada, ya no usa las propiedades de la geometría original de manera inteligente. Como se mencionó anteriormente, las geometrías del búfer plano se pueden optimizar al saber que el arrayBuffer proviene de un PlaneGeometry. ¿Quizás sobrescribir el método MESH.raycast (raycaster, intersects) para basarlo en el tipo de geometría?

Otro enfoque es tener Raycaster como un complemento separado, al igual que los controles interactivos y los cargadores. Entonces, agregar un emisor de rayos de rendimiento similar al que propone @Usnul sería genial.

Me gusta la idea de tener Raycasters enchufables, pero creo que hay un poco de confusión. Lo que creo que es útil es un índice espacial, no un Raycaster per-se. El índice espacial permite cosas como:

  • sacrificio espacial (piense en el sacrificio frustum)
  • haciendo consultas de visibilidad
  • construyendo un renderizador de trazado de ruta
  • clasificación rápida (explotación de la localidad de datos)

actualmente three.js hace 2 de estos explícitamente (clasificación y selección) y 1 a través de ejemplos (renderizador de trazado de rayos)

mantener un índice espacial internamente aceleraría la clasificación y la selección, brindando progresivamente más beneficios para escenas más grandes a costa de RAM adicional requerida para almacenar el índice.

¿Por qué no usas la selección de GPU? Hay algunos ejemplos y es bastante fácil de implementar. La actuación es de día y de noche. En nuestros casos de uso, con modelos de más de un millón de polígonos, la selección pasó de casi un segundo a ejecutarse en tiempo real a 60 fps mientras arrastraba elementos sobre el modelo.

https://github.com/brianxu/GPUPicker

@hccampos
La selección de GPU no es necesariamente más rápida que hacerlo en la CPU, para GPU debe renderizar a una resolución proporcional a la precisión que desea, por lo que si desea precisión de píxeles, debe renderizar a una resolución de pantalla de 1: 1. Tenga en cuenta que este es un pase de renderizado separado, está renderizando objetos como colores distintos separados. Un pase de procesamiento adicional significa el uso de la memoria de gráficos (típico de la canalización diferida).
El uso de un índice de partición de espacio binario le brinda un perfil de tiempo de registro (n) en su selección, por lo que para 1,000,000 de polígonos estaría buscando alrededor de 14 operaciones para resolver una consulta de rayos. Dependiendo de su estructura de datos, es probable que tome unos microsegundos, lo que le permite miles de consultas antes de comenzar a hacer mella en su presupuesto de marcos.

Hagamos una comparación, digamos que tiene un modelo polivinílico de 1 m y desea proyectar un rayo desde el espacio de la pantalla directamente a lo largo de la dirección de la cámara hacia la escena (elección del caso de uso). Supongamos que va con la parte inferior de la resolución del barril, "full hd", o 1920 × 1080. Supongamos que solo renderiza RGB (24 bits por píxel), necesitará 6220800 bytes (alrededor de 6 Mb) o RAM de gráficos para renderizar que. Si usa una solución de CPU, digamos que va con AABB BVH con 10 polígonos por hoja, eso significa que necesita alrededor de 200,000 nodos, digamos que cada nodo tiene aproximadamente 6 * 8 bytes para coordenadas, los nodos intermedios tienen 2 * 4 bytes adicionales para punteros secundarios y los nodos de hoja tienen 10 * 4 bytes para el puntero del polígono, eso es 14,400,000 bytes (alrededor de 14Mb). La principal diferencia entra en juego cuando considera el hecho de que sus consultas BVH tienen muy poca demanda de ancho de banda de RAM, en comparación con el caso de GPU, y solo hay un puñado de operaciones involucradas por consulta, en comparación con la representación de geometría poligonal completa de 1 m.
Si elige una resolución que es más típica para computadoras de escritorio, como 2560x1440, termina con un destino de procesamiento de 11059200 bytes (11 Mb).

Si tiene un gran presupuesto de ancho de banda de RAM de gráficos y un recuento de núcleos de sombreado bastante decente, seguro, esa es una forma simple y directa de elegir.

@Usnul absolutamente, pero probablemente sea la solución más simple de implementar. La implementación y el mantenimiento de estructuras de datos de índices espaciales probablemente será una carga no insignificante para los mantenedores de threejs.

Dicho esto, me encantaría tener una estructura de datos de índice espacial buena, bien probada y mantenida como parte de tres o como un paquete npm separado.

Tenía curiosidad por implementar un índice espacial de este tipo para mis geometrías usadas, así que implementé un Octree bastante simple (solo crear y buscar) que divide mi BufferGeomtry. Con esta sencilla solución logré resultados bastante prometedores: aplicada a una geometría con unos 500 000 vértices, el tiempo de emisión de rayos se redujo de ~120 ms a ~2,3 ms. La construcción del árbol actualmente toma ~500 ms, pero dado que la geometría y la creación del árbol se realizan dentro de un trabajador web solo una vez al iniciar la aplicación, esto no es un problema.

Supongo que el algoritmo podría integrarse fácilmente en THREE.BufferGeometry y tal vez activarse o desactivarse usando una bandera como THREE.BufferAttribute 's dynamic . De esta manera, podría usarse solo cuando se supone que BufferGeometry no debe cambiar. Desafortunadamente, tuve que sobrescribir el método THREE.Mesh de raycast aunque solo necesitaba cambiar dos líneas en él (llamada de búsqueda de Octtree e iteración de matriz de posición).

De todos modos, en mi aplicación de realidad virtual tengo que detectar colisiones entre el objeto y el controlador durante el ciclo de procesamiento y no solo una vez al hacer clic con el mouse. Por lo tanto, tengo que confiar en mi solución actual. Lo intentaré si puedo mejorarlo aún más.

ACTUALIZAR Cometí un error al medir el tiempo de raycast. El valor correcto es ~2,3 ms (en lugar de ~0,3 ms). Cambié el valor anterior en consecuencia.

Creo que es necesario tener una forma opcional de realizar búsquedas espaciales rápidas en la mayoría de las aplicaciones más complejas creadas sobre three.js. Por ejemplo, un editor 3D. He jugado con algunas implementaciones, pero no se integran bien o se ajustan demasiado a una versión específica de three.js. Entonces, si alguien tiene una forma de optar por hacerlo sin interrumpir la ruta de actualización a versiones más nuevas de three.js, sería genial.

@matthias-w Probé el raycaster para un modelo obj pero el controlador no detecta nada. Los rayos están pasando a través del modelo. me puedes decir como solucionaste ese problema

Sobre el tema de tener índice espacial opcional. Creo que es lo suficientemente útil incluso para el propio renderizador (por ejemplo, para la selección) como parte integral del motor. Aquí hay una discusión relacionada:

13909

¡Oye! También estaba un poco interesado en esto (aunque desde entonces he encontrado otras soluciones para nuestras necesidades de raycast), pero pensé que también contribuiría con algunos de mis experimentos. Es un poco tosco, pero armé esto hace unos meses:

https://github.com/gkjohnson/tresjs-fast-raycast

Agrega una función computeBoundsTree a los TRES objetos geométricos y anula la función raycast para usar eso (y solo devuelve el primer resultado como una optimización adicional). Solo es realmente beneficioso para mallas estáticas altamente complejas y no hace nada para segmentar espacialmente la escena. Aquí está la demostración donde puede ver la diferencia en el rendimiento de raycast en una malla de 80,000 triángulos. Calcular el árbol de límites es un poco lento, pero con un poco de trabajo probablemente podría ser más fluido.

En cuanto a mi opinión sobre esto, me siento un poco en conflicto. Esto se siente como algo que se puede construir bastante bien como una extensión de TRES. Y, en última instancia, no parece que hacer comprobaciones / colisiones / moldes por triángulo para mallas complejas o animadas sea óptimo, de todos modos. En casos simples, podría estar bien, pero parece que usar las representaciones típicas de plano/cubo/esfera/cápsula o mallas simplificadas sería más adecuado para permitir una emisión de rayos súper rápida (u eliminación de oclusiones, colisiones, etc.) en casos complejos. Por supuesto, si está buscando moldes con píxeles perfectos, esto no funciona tan bien, pero la solución correcta realmente depende de su caso de uso.

@Usnul @matthias-w ¿Alguna de sus implementaciones de octree/BVH es de código abierto o está disponible en línea? ¡Definitivamente estaría interesado en echar un vistazo!

@gkjohnson

¿Alguna de sus implementaciones de octree/BVH es de código abierto o está disponible en línea? ¡Definitivamente estaría interesado en echar un vistazo!

El código no es de código abierto actualmente. Podría proporcionarte las fuentes si me contactas en privado.

Hay un ejemplo que hice para mallas instanciadas:
http://server1.lazy-kitty.com/tests/instanced-folage-1mil/
El ejemplo anterior incluye lo siguiente:

  • BVH se actualiza dinámicamente a medida que se insertan nuevas instancias en el árbol
  • BVH se optimiza incrementalmente usando 1-2 rotaciones de profundidad sobre la marcha
  • BVH se muestrea con una consulta frustum a qué instancias representar

Tengo una versión ejecutándose en el juego en el que estoy trabajando:
http://server1.lazy-kitty.com/komrade/

Con respecto a su implementación. Me gusta, el mío es diferente en 2 formas principales:

  • me concentro en el rendimiento
  • Me concentro en la huella de la memoria.
  • Evito la recolección de basura en muchos lugares

Algunos puntos más específicos:

  • También uso una combinación de estrategias de división de forma transparente, según lo que quieras hacer con el BVH.
  • Mi BVH está basado en AABB
  • Admito actualizaciones de los límites de los nodos mediante reacondicionamiento

@Usnul No puedo ver su dirección de correo electrónico ni nada, pero estoy bastante interesado en estudiar su solución de indexación espacial.

Actualmente solo recorro todos los objetos de escena relevantes y calculo la distancia desde la cámara. No es el enfoque más óptimo.

@titansoftime
es
travnick at gmail com
No me di cuenta de que no está disponible públicamente. Mi error.

@Usnul También estoy interesado en el proyecto de 1 millón. Tal vez incluso 10 o 20 millones si es posible. Por favor envíeme un correo electrónico: kaori.nakamoto. [email protected]

¡Gracias MUY amablemente!

Lo siento por la respuesta tardía.
@gkjohnson El código no es de código abierto. Además, su solución suena mucho más sofisticada que la mía. Por lo tanto, supongo que no hay mucho que aprender de mi solución.

@ sid3007 No estoy seguro de entender su problema. Puedo explicar mi enfoque. Tal vez sea útil.

Mi caso de uso es bastante simple. Cuando se inicia mi aplicación, se cargan las geometrías para diferentes modelos. Estos modelos pueden ser transformados por el usuario. Las geometrías no cambian. No hay deformaciones de la geometría. Por lo tanto, implementé un Octtree muy simple que se crea una vez para cada geometría cuando se inicia la aplicación. El octárbol no es dinámico. Se construye en base al cuadro delimitador de la geometría dada y la matriz de vértices. Durante su construcción, verifica si un octante contiene un vértice o si el cuadro delimitador Box3 del octante se cruza con un triángulo (tres vértices consecutivos en geometría no indexada) y almacena las referencias de la matriz de vértices con el nodo del octárbol.
El octárbol por malla se almacena luego junto con la malla. También sobrescribo el método raycast mis instancias de malla THREE.Mesh (solo una línea) para llamar realmente al método de prueba de intersección de octárboles. Esto devuelve los índices de vértice de las caras de las geometrías que pueden ser utilizados por la lógica de intersección predeterminada de la malla.
Hice una optimización: la creación de octree se realiza una vez en el inicio de la aplicación dentro de un WebWorker (en realidad, un grupo de trabajadores). La razón es que la creación del árbol para geometrías grandes lleva bastante tiempo (algunos segundos). Esto bloquearía la interfaz de usuario del navegador, así que lo moví a otro hilo.
Espero que mi enfoque sea claro.

@matthias-w ¡Suena como un gran trabajo! Independientemente hice casi lo mismo, pero no creo que logré una mejora de rendimiento tan grande. https://discourse.threejs.org/t/octree-injection-for-faster-raytracing/8291/2 (implementación de octree orientada a objetos y modificaciones menos limpias a Mesh.raycast)

¿Sería posible para usted abrir/contribuir con la implementación de Octree, permitiendo más experimentos por parte de otros?

@EliasHasle Gracias. En realidad, la ganancia de rendimiento no es tan buena, ya que cometí un error en mis primeras medidas. Corregí el valor (ver mi publicación anterior). Los tiempos tienen más sentido ahora con respecto a la complejidad de búsqueda logarítmica de Octtree. Desafortunadamente, no puedo hacer que el código esté disponible en este momento, pero tal vez más adelante este año. De todos modos, mi implementación es bastante sencilla (y no tan limpia, por cierto;)). Así que supongo que no habría ideas especiales.

@matthias-w Creo que 2,3 ms frente a 120 ms para un raycast en una malla de vértices de 500k sigue siendo una mejora significativa, que, por ejemplo, permite la resolución en tiempo real de las balas disparadas en los juegos (en una parte bastante grande del cálculo presupuesto por cuadro).

¿Probaste también el trazado de rayos?

¿Su implementación se basa en un árbol de objetos JS? ¿Objetos literales o instancias de un prototipo? El mío es completamente similar a sí mismo, de modo que cada nodo es un octárbol, con métodos y todo.

@EliasHasle

Si está interesado en el raycasting contra la geometría estática, yo y otros hemos puesto un esfuerzo significativo en three-mesh-bvh , que usa un BVH para indexar triángulos y permite el raycasting de alto rendimiento, así como la detección de intersecciones contra geometría estática compleja. El proceso de construcción del árbol es más complejo, por lo que lleva un poco más de tiempo, pero la transmisión de rayos se reduce a menos de un milisegundo y, a menudo, a menos de 0,1 ms cuando se transmite contra geometría con cientos de miles de triángulos.

El tiempo de compilación podría mejorarse de diferentes maneras, pero ha sido lo suficientemente bueno para lo que quería hacer con él; sin embargo, mejorar eso está en la lista.

Me gustaría construir un octree dinámico basado en escenas para permitir una mejor proyección de rayos y detección de colisiones para escenas con muchas mallas, pero yo mismo no he tenido un buen caso de uso. ¡Tal vez algún día!

@EliasHasle Mi implementación es un árbol de objetos de clase JS (uso clases ES6, es decir, instancias de prototipo). Básicamente, un nodo es un árbol en mi implementación. Sin embargo, tengo una clase Octtree adicional que contiene el nodo raíz y proporciona métodos para construir y buscar (y también algo de depuración y visualización) del árbol.

No experimenté mucho con los valores para el nivel máximo de nodo de árbol y el número máximo de vértices por nodo de hoja. Quizá haya una mejor combinación.
También utilizo una jerarquía de volumen límite para acelerar las pruebas de intersección. Así que pruebo la esfera delimitadora y el cuadro delimitador de la malla antes de verificar el octárbol de la geometría de la malla.

Puedo recomendar un libro que es una muy buena colección de enfoques de detección de colisiones: C. Ericson, Real-Time Collision Detection, CRC Press, 2004

@gkjohnson ¡ Eso se ve genial! El rendimiento es impresionante. ¿Qué tipo de BVH estás usando?

@matthias-w ¡Gracias!

Hay un par de opciones de estrategia dividida, pero dividir los nodos BVH en el centro del lado más largo construye el árbol más rápido. Los triángulos se dividen en lados según el centro de sus límites y los nodos del árbol se expanden para contener completamente los triángulos secundarios (por lo que hay una pequeña cantidad de superposición de los nodos del árbol).

@gkjohnson Entonces, la implementación de BVH es una especie de árbol Kd desequilibrado con una selección de ejes que depende de la forma de la caja, ¿verdad? Si es así, estaba pensando en hacer algo así para los casos en que la raíz BB estaba demasiado lejos de un cubo, y luego usar octrees después de la división condicional. Presumiblemente, esto se aplicaría bien a casos como el mundo del mapa de @Usnul , donde la división inicial sería en las dos dimensiones del "mapa" y la división posterior se realizaría en 3D. Creo que es una solución mucho mejor que la mía, que es expandir la BB raíz a un cubo delimitador con el mismo centro, y luego usar la división de octágonos hasta el final.

Acabo de implementar un mejor método para emitir rayos en PlaneBufferGeometry.

@kpetrow Creo que al optimizar los raycasts en PlaneBufferGeometry , la suposición de que las posiciones de los vértices no se modificarán probablemente no sea válida para las geometrías de alta resolución donde una búsqueda lineal es insuficiente. Por lo que puedo decir, el uso principal de PlaneBufferGeometry de alta resolución es remodelarlo moviendo los vértices, manteniendo la topología, por ejemplo, para construir terreno.

Cierre a favor del #13909.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

boyravikumar picture boyravikumar  ·  3Comentarios

clawconduce picture clawconduce  ·  3Comentarios

jlaquinte picture jlaquinte  ·  3Comentarios

jack-jun picture jack-jun  ·  3Comentarios

Horray picture Horray  ·  3Comentarios