Three.js: Solicitação de recurso: Aumente o desempenho de detecção de colisão de raycaster por meio de árvores de pesquisa espacial

Criado em 11 dez. 2017  ·  36Comentários  ·  Fonte: mrdoob/three.js

Eu construí um aplicativo VR semelhante ao WebVR-Vive-Dragging que permite interagir com vários objetos 3D usando controladores VR. Isso significa que um usuário pode pegar um objeto com um controlador VR e pode movê-lo ou dimensioná-lo.

Problema : Quando há objetos 3d complexos na cena, ou seja, objetos THREE.Mesh com geometrias com um número muito grande de vértices, então o raycasting durante a detecção de colisão fica muito lento. Portanto, o problema é a complexidade da geometria de um objeto.

Existem estruturas de dados em árvore para pesquisa espacial rápida, como Octree ou R-Tree . Eu encontrei threeocttree que permite dividir uma geometria em pedaços menores, mas parece que está um pouco desatualizado (Three.js r60).

Até onde eu vejo, no método $#$2$ THREE.Mesh do objeto raycast já existem algumas otimizações de desempenho (verificando a caixa delimitadora e a esfera antes de fazer o raycast real). Talvez fizesse sentido ter outro estágio de verificação usando árvores de busca espacial?! O que você acha?

Atenciosamente

Enhancement

Comentários muito úteis

Eu sugeri que o índice espacial fosse incluído no threejs no passado. Tem havido algum trabalho nessa direção, e o exemplo de oct-tree existente é um deles. Em última análise, acho que é falta de interesse da comunidade principal em relação a ter essa funcionalidade como cidadão de primeira classe em três.

Eu ficaria feliz em doar meu código BVH para o projeto, se houver interesse e intenção suficientes para incluí-lo na distribuição principal (não exemplos).
Meu código se concentra em 2 aspectos:

  • cenas dinâmicas

    • inserção rápida

    • exclusão rápida

    • reajuste (capacidade de os nós mudarem de forma sem precisar ser reinseridos)

  • velocidade de consulta

Tenho 2 implementações:

  • BinárioBVH

    • muito compacto, usando ByteBuffer

    • mistura de tipos UintX e FloatX via DataView

    • ótimo para serialização

    • pode ser compactado usando ferramentas padrão como a biblioteca lzma

    • imutável

    • a velocidade de construção é altamente otimizada

    • só funciona para BufferGeometry

    • Otimização de SAH

    • consultas de raio

  • BVH

    • A árvore de objetos, como consequência, é muito maior que a implementação binária

    • mutável

    • inserção em massa rápida

    • inserção rápida de item único

    • remontagem

    • implementações de travessia de pilha, recursivas e sem pilha (diferentes características de desempenho)

    • Otimização de SAH

    • Consultas frustradas

    • Consultas Ray

Pessoalmente, não posso viver sem um índice espacial, é uma diferença entre o desempenho de n^2 e log(n). Por exemplo, no meu projeto atual, as seguintes partes dependem do índice espacial:

  • sistema de folhagem (árvores, flores, arbustos, etc.)
  • todos os posicionamentos de objetos (personagens e casas)
  • picking (usado em interações, como cliques do mouse)

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

terreno tem cerca de 1m de polígonos, e colocar milhares de árvores e executar ray-casts em tempo real é simplesmente impossível, especialmente para dispositivos de baixo custo.

Todos 36 comentários

Correndo o risco de dizer o óbvio, mas você já tentou a versão de threeocttree que já está no repositório( example/js/Octree.js )?

Eu não voto por um uso hard-wired de árvores de busca espacial em three.js . A sobrecarga/complexidade de tais algoritmos desequilibra o ganho de desempenho em muitas aplicações.

verificando a caixa delimitadora e a esfera antes de fazer o raycast real

Isso é razoável e deve ser suficiente. Se os usuários precisarem de mais desempenho no contexto de casos de uso mais avançados, eles podem usar o exemplo mencionado como ponto de partida. Octrees pode ser uma boa escolha. Mas nunca vi uma solução R-Tree em aplicativos 3D interativos porque sua abordagem é bastante sofisticada (o algoritmo executa dados em vez de particionamento de espaço).

Olá e obrigado pelas respostas,
@Mugen87 Concordo que muitos casos de uso não exigem pesquisas tão rápidas. No entanto, tendo um mecanismo para interagir com objetos 3D (e eu acho que esse é o caso para o qual ele é usado principalmente), o passo de THREE.Raycaster de verificar primeiro a caixa/esfera delimitadora (o que eu concordo totalmente em ser razoável ) em, digamos, tempo constante para um esforço de tempo linear ao fazer o raycast real é bastante grande. Eu poderia imaginar uma espécie de "árvore de pesquisa por geometria" em vez de uma árvore de pesquisa global. Desde que a geometria não mude (muitas vezes as transformações são muito mais prováveis ​​do que as mudanças na geometria), a árvore de pesquisa não precisa ser atualizada.

É por isso que pensei que esse tipo de otimização usando árvores de pesquisa espacial poderia ser uma parte mais integral de three.js . Mas também entendo que isso causa complexidade e sobrecarga adicionais.

@moraxy vou dar uma olhada na versão de exemplo. Eu só queria saber se esse recurso faria sentido.

Obrigado novamente e um grande abraço

Talvez uma árvore de busca mais simples possa ser integrada em THREE.BufferGeometry . Por exemplo, uma chamada para computeBoundingBox também pode construir um tipo de árvore de busca somente leitura referenciando os vértices correspondentes. Como THREE.BufferGeometry é

mais adequado para objetos estáticos onde você não precisa manipular muito a geometria depois de instanciá-la

esta árvore de busca não precisa ser alterada após inicializá-la. Isso reduziria alguma sobrecarga para atualização/exclusão. Um Octree seria um bom ponto de partida ( conceito semelhante no BabylonJS ).

mais adequado para objetos estáticos onde você não precisa manipular muito a geometria depois de instanciá-la

FWIW, eu não acredito que seja uma afirmação verdadeira.

@WestLangley Citação da documentação THREE.BufferGeometry

TRÊS. Documentação do BufferGeometry

Provavelmente deve ser removido - em qualquer caso, não acho que isso signifique qualquer tipo de declaração técnica, mas significa que é mais difícil para o usuário manipular a geometria depois de criada.

Provavelmente deve ser removido

Definitivamente.

Acabei de implementar um método melhor para raycasting em PlaneBufferGeometry. Eu uso o parâmetro far e encontro as primeiras e últimas posições do índice. Isso funciona no planebuffer porque a matriz de índice está na ordem x/y. Uma vez fora da caixa delimitadora x/y, todas as colisões devem estar fora do alcance distante. Existe algum desejo de cometer isso em algum lugar? A implementação atual é específica para o meu caso de uso, mas eu estaria disposto a tentar tornar mais genérico, se desejado. Consegui reduzir significativamente meu desempenho de raycasting em um grande planeBuffer (2,5 segundos a 10 ms)

@kpetrow Acho que os exemplos de três.js octree são adequados. É claro que você é livre para compartilhar seu código no GitHub se achar que seria útil para outras pessoas.

Eu sugeri que o índice espacial fosse incluído no threejs no passado. Tem havido algum trabalho nessa direção, e o exemplo de oct-tree existente é um deles. Em última análise, acho que é falta de interesse da comunidade principal em relação a ter essa funcionalidade como cidadão de primeira classe em três.

Eu ficaria feliz em doar meu código BVH para o projeto, se houver interesse e intenção suficientes para incluí-lo na distribuição principal (não exemplos).
Meu código se concentra em 2 aspectos:

  • cenas dinâmicas

    • inserção rápida

    • exclusão rápida

    • reajuste (capacidade de os nós mudarem de forma sem precisar ser reinseridos)

  • velocidade de consulta

Tenho 2 implementações:

  • BinárioBVH

    • muito compacto, usando ByteBuffer

    • mistura de tipos UintX e FloatX via DataView

    • ótimo para serialização

    • pode ser compactado usando ferramentas padrão como a biblioteca lzma

    • imutável

    • a velocidade de construção é altamente otimizada

    • só funciona para BufferGeometry

    • Otimização de SAH

    • consultas de raio

  • BVH

    • A árvore de objetos, como consequência, é muito maior que a implementação binária

    • mutável

    • inserção em massa rápida

    • inserção rápida de item único

    • remontagem

    • implementações de travessia de pilha, recursivas e sem pilha (diferentes características de desempenho)

    • Otimização de SAH

    • Consultas frustradas

    • Consultas Ray

Pessoalmente, não posso viver sem um índice espacial, é uma diferença entre o desempenho de n^2 e log(n). Por exemplo, no meu projeto atual, as seguintes partes dependem do índice espacial:

  • sistema de folhagem (árvores, flores, arbustos, etc.)
  • todos os posicionamentos de objetos (personagens e casas)
  • picking (usado em interações, como cliques do mouse)

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

terreno tem cerca de 1m de polígonos, e colocar milhares de árvores e executar ray-casts em tempo real é simplesmente impossível, especialmente para dispositivos de baixo custo.

Eu gostaria de ver qualquer coisa que torne o raycast otimizado. Existe algum espaço para otimização sem adicionar complexidade? Octree requer todas as novas bibliotecas, com todas as novas adições e atualizações, etc.

Uma coisa que noto é que uma vez que uma geometria é convertida em uma matriz de buffer indexada, ela não usa mais as propriedades da geometria original de forma inteligente. Como mencionado acima, as geometrias de buffer de plano podem ser super otimizadas sabendo que o arrayBuffer veio de um PlaneGeometry. Talvez substituindo o método MESH.raycast ( raycaster, intersects ) para se basear no tipo de geometria?

Outra abordagem é ter o Raycaster como um plug-in separado -- assim como os controles interativos e os carregadores. Então, adicionar um raycaster de alto desempenho semelhante ao que @Usnul propõe seria ótimo.

Eu gosto da ideia de ter Raycasters conectáveis, mas acho que há um pouco de confusão. O que eu acho útil é um índice espacial, não um Raycaster em si. O índice espacial permite coisas como:

  • seleção espacial (pense em seleção de frustum)
  • fazendo consultas de visibilidade
  • construindo um renderizador de rastreamento de caminho
  • classificação rápida (explorando a localidade de dados)

atualmente, o three.js faz 2 desses explicitamente (classificação e seleção) e 1 por meio de exemplos (renderizador de rastreamento de raio)

manter um índice espacial internamente aceleraria a classificação e a seleção, proporcionando progressivamente mais benefícios para cenas maiores ao custo de RAM extra necessária para armazenar o índice.

Por que você não usa apenas a seleção de GPU? Existem alguns exemplos ao redor e é bastante fácil de implementar. O desempenho é noite e dia. Em nossos casos de uso, com modelos de mais de um milhão de polígonos, a escolha passou de quase um segundo para execução em tempo real a 60fps enquanto arrastava coisas sobre o modelo.

https://github.com/brianxu/GPUPicker

@hccampos
A seleção de GPU não é necessariamente mais rápida do que fazê-lo na CPU, para a GPU você precisa renderizar na resolução proporcional à precisão desejada; portanto, se você deseja precisão de pixel, deve renderizar na resolução de tela de 1:1. Tenha em mente que este é um passo de renderização separado, você está renderizando objetos como cores distintas separadas. Uma passagem de renderização extra significa uso de memória gráfica (típico para pipeline adiado).
O uso de um índice de particionamento de espaço binário fornece um perfil de tempo log(n) em sua seleção, portanto, para 1.000.000 de polígonos, você observaria cerca de 14 operações para resolver uma consulta de raio. Dependendo da sua estrutura de dados, é provável que leve alguns microssegundos, permitindo milhares de consultas antes de começar a afetar seu orçamento de quadros.

Vamos fazer uma comparação, digamos que você tenha um modelo poli de 1m e deseja lançar um raio do espaço da tela diretamente na direção da câmera para a cena (escolhendo o caso de uso). Vamos supor que você esteja usando a resolução inferior do barril, "full hd", ou 1920 × 1080. Vamos supor que você renderize apenas RGB (24 bits por pixel), você precisará de 6220800 bytes (cerca de 6 Mb) ou RAM gráfica para renderizar aquele. Se você usa solução de CPU, digamos que você vá com AABB BVH com 10 polígonos por folha, o que significa que você precisa de cerca de 200.000 nós, digamos que cada nó tenha cerca de 6 * 8 bytes para coordenadas, nós intermediários têm 2 * 4 bytes extras para ponteiros filhos e nós folha têm 10 * 4 bytes para ponteiro de polígono, que é 14.400.000 bytes (cerca de 14Mb). A principal diferença entra em jogo quando você considera o fato de que suas consultas BVH têm muito pouca demanda na largura de banda da RAM, em comparação com o gabinete da GPU, e há apenas um punhado de operações envolvidas por consulta, em comparação com a renderização de geometria poli completa de 1m.
Se você pegar uma resolução que é mais típica para desktops, como 2560x1440, você terá um destino de renderização de 11059200byte (11Mb).

Se você tem um grande orçamento de largura de banda de RAM gráfica e uma contagem de núcleos de sombreamento bastante decente - com certeza, essa é uma maneira simples e direta de fazer a escolha.

@Usnul absolutamente, mas provavelmente é a solução mais simples de implementar. Implementar e manter estruturas de dados de índice espacial provavelmente será um fardo não insignificante para os mantenedores do threejs.

Dito isto, eu adoraria ter uma estrutura de dados de índice espacial boa, bem testada e mantida como parte de três ou como um pacote npm separado.

Eu estava curioso para implementar esse índice espacial para minhas geometrias usadas, então implementei um Octree bastante simples (somente criar e pesquisar) que divide meu BufferGeomtry. Com esta solução simples obtive resultados bastante promissores: aplicado em uma geometria com cerca de 500K vértices o tempo de raycast foi reduzido de ~120ms para ~2,3ms. A construção da árvore atualmente leva ~500ms, mas como a geometria e a criação da árvore são feitas dentro de um web worker apenas uma vez no início do aplicativo, isso não é um problema.

Eu acho que o algoritmo poderia ser facilmente integrado em THREE.BufferGeometry e talvez ligado ou desligado usando um sinalizador como THREE.BufferAttribute dynamic . Dessa forma, ele pode ser usado apenas quando o BufferGeometry não deve ser alterado. Infelizmente, eu tive que substituir o método $#$4$# THREE.Mesh raycast , embora eu só precisasse alterar duas linhas nele (chamada de pesquisa Octree e iteração de matriz de posição).

De qualquer forma, no meu aplicativo de RV, tenho que detectar colisões do controlador de objeto durante o loop de renderização e não apenas uma vez no clique do mouse. Assim, tenho que confiar na minha solução atual. Vou tentar se puder melhorá-lo ainda mais.

ATUALIZAÇÃO Eu cometi um erro ao medir o tempo de raycast. O valor correto é ~2,3ms (em vez de ~0,3ms). Alterei o valor acima de acordo.

Eu acho que ter uma maneira opcional de fazer pesquisas espaciais rápidas é necessário na maioria dos aplicativos mais complexos construídos em cima de três.js. Por exemplo, um editor 3D. Eu brinquei com algumas implementações por aí, mas elas não se integram bem ou se encaixam em uma versão específica do three.js com muita força. Portanto, se alguém tiver uma maneira opt-in de fazer isso sem interromper o caminho de atualização para versões mais recentes do three.js, seria ótimo.

@matthias-w Eu tentei o raycaster para um modelo obj, mas o controlador não está detectando nada. Os raios estão passando pelo modelo. Você pode me dizer como você resolveu esse problema

Sobre o assunto de ter índice espacial opcional. Acredito que seja suficientemente útil até para o próprio renderizador (por exemplo: para culling) ser parte integrante do motor. Aqui está uma discussão relacionada:

13909

Ei! Eu também estava um pouco interessado nisso (embora tenha encontrado outras soluções para nossas necessidades de raycast), mas achei que poderia contribuir com alguns de meus experimentos também. É um pouco difícil, mas eu montei isso há alguns meses:

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

Ele adiciona uma função computeBoundsTree aos TRÊS objetos de geometria e substitui a função raycast para usá-la (e retorna apenas o primeiro hit como uma otimização adicional). É realmente benéfico apenas para malhas estáticas altamente complexas e não faz nada para segmentar espacialmente a cena. Aqui está a demonstração onde você pode ver a diferença no desempenho do raycast em uma malha de 80.000 triângulos. Calcular a árvore de limites é um pouco lento, mas com um pouco de trabalho provavelmente poderia ser mais suave.

Quanto à minha opinião sobre isso, sinto-me um pouco conflitante. Isso parece algo que pode ser construído muito bem como uma extensão do THREE. E, finalmente, não parece que fazer verificações / colisões / lançamentos por triângulo para malhas complexas ou animadas seja o ideal, de qualquer maneira. Em casos simples, pode ser bom, mas parece que usar as representações típicas de plano / cubo / esfera / cápsula ou malhas simplificadas seria mais adequado para permitir raycasting super rápido (ou oclusão-culling, colisões, etc) em casos complexos. É claro que, se você estiver procurando por lançamentos perfeitos em pixels, isso não funcionará tão bem, mas a solução certa realmente depende do seu caso de uso.

@Usnul @matthias-w Alguma de suas implementações octree / BVH é de código aberto ou está disponível online? Eu definitivamente estaria interessado em dar uma olhada!

@gkjohnson

Alguma de suas implementações octree / BVH é de código aberto ou está disponível online? Eu definitivamente estaria interessado em dar uma olhada!

O código não é de código aberto atualmente. Eu poderia fornecer-lhe as fontes se você entrar em contato comigo em particular.

Há um exemplo que fiz para malhas instanciadas:
http://server1.lazy-kitty.com/tests/instanced-foliage-1mil/
O exemplo acima inclui o seguinte:

  • O BVH é atualizado dinamicamente à medida que novas instâncias são inseridas na árvore
  • O BVH é otimizado incrementalmente usando rotações de profundidade 1-2 em tempo real
  • O BVH é amostrado com uma consulta frustum para quais instâncias renderizar

Eu tenho uma versão dele rodando no jogo em que estou trabalhando:
http://server1.lazy-kitty.com/komrade/

Com relação à sua implementação. Eu gosto, o meu é diferente de 2 maneiras principais:

  • Eu foco no desempenho
  • Eu me concentro na pegada de memória
  • Evito a coleta de lixo em muitos lugares

Alguns pontos mais específicos:

  • Eu também uso uma mistura de estratégias de divisão de forma transparente, com base no que você deseja fazer com o BVH
  • Meu BVH é baseado em AABB
  • Eu dou suporte a atualizações de limites de nós por meio de reajuste

@Usnul Não consigo ver seu endereço de e-mail nem nada, mas estou bastante interessado em estudar sua solução de indexação espacial.

Atualmente, apenas percorro todos os objetos de cena relevantes e calculo a distância da câmera. Não é a abordagem mais ideal.

@titansofttime
Está
travnick at gmail com
Não sabia que não está disponível publicamente. Foi mal.

@Usnul Também estou interessado no projeto de 1 milhão. Talvez até 10 ou 20 milhões, se possível. Por favor, envie-me um e-mail: kaori.nakamoto. [email protected]

Obrigado MUITO gentilmente!

Desculpe pela resposta tardia.
@gkjohnson O código não é de código aberto. Além disso, sua solução parece muito mais sofisticada que a minha. Assim, acho que não há muito o que aprender com minha solução.

@sid3007 Não tenho certeza se entendi seu problema. Posso explicar minha abordagem. Talvez seja útil.

Meu caso de uso é bastante simples. Quando meu aplicativo é iniciado, as geometrias para diferentes modelos são carregadas. Esses modelos podem ser transformados pelo usuário. As geometrias não mudam. Não há deformações geométricas. Por isso, implementei um Octree muito simples que é construído uma vez para cada geometria quando o aplicativo é iniciado. A octree não é dinâmica. Ele é construído com base na caixa delimitadora da geometria fornecida e na matriz de vértices. Durante sua construção ele verifica se um octante contém um vértice ou a caixa delimitadora Box3 do octante cruza com um triângulo (três vértices consecutivos em geometria não indexada) e armazena as referências do array de vértices com o nó da octree.
A octree por malha é então armazenada junto com a malha. Eu também sobrescrevo o método raycast THREE.Mesh minhas instâncias de malha (apenas uma linha) para chamar o método de teste de interseção octree. Isso retorna os índices de vértices da face das geometrias que podem ser usados ​​pela lógica de interseção padrão da malha.
Eu fiz uma otimização: a criação da octree é feita uma vez na inicialização do aplicativo dentro de um WebWorker (na verdade, um pool de workers). A razão é que a criação da árvore para grandes geometrias leva algum tempo (alguns segundos). Isso bloquearia a interface do usuário do navegador, então eu a movi para outro thread.
Espero que minha abordagem fique clara.

@matthias-w Parece um ótimo trabalho! Eu fiz quase o mesmo de forma independente, mas não acho que alcancei uma melhoria de desempenho tão grande. https://discourse.threejs.org/t/octree-injection-for-faster-raytracing/8291/2 (implementação octree orientada a objetos e modificações menos limpas no Mesh.raycast)

Seria possível para você open-source/contribuir com a implementação do Octree, permitindo mais experimentos por outros?

@EliasHasle Obrigado. Na verdade, o ganho de desempenho não é tão bom, pois errei nas minhas primeiras medidas. Corrigi o valor (veja meu post acima). Os tempos fazem mais sentido agora em relação à complexidade de busca logarítmica do Octree. Infelizmente, não posso disponibilizar o código no momento, mas talvez ainda este ano. De qualquer forma, minha implementação é bastante direta (e não tão limpa BTW ;)). Então eu acho que não haveria nenhum insight especial.

@matthias-w Acho que 2,3 ms vs 120 ms para um raycast em uma malha de vértices de 500k ainda é uma melhoria significativa, que, por exemplo, permite a resolução em tempo real de balas disparadas em jogos (em uma parte bastante grande da computação orçamento por quadro).

Você tentou raytracing também?

Sua implementação é baseada em uma árvore de objetos JS? Objetos literais ou instâncias de um protótipo? O meu é totalmente auto-semelhante, de modo que cada nó é uma octree, com métodos e tudo.

@EliasHasle

Se você estiver interessado em raycasting contra geometria estática, I e outros colocaram um esforço significativo em three-mesh-bvh , que usa um BVH para indexar triângulos e permite raycasting de alto desempenho, bem como detecção de interseção contra geometria estática complexa. O processo de construção da árvore é mais complexo, por isso leva um pouco mais de tempo, mas leva raycasting para menos de um milissegundo e muitas vezes menos de 0,1 ms quando raycasting contra geometria com centenas de milhares de triângulos.

O tempo de construção pode ser melhorado de algumas maneiras diferentes, mas tem sido bom o suficiente para o que eu queria fazer com ele - melhorar isso está na lista, no entanto.

Eu gostaria de construir uma octree dinâmica baseada em cena para permitir melhor raycasting e detecção de colisão para cenas com muitas malhas, mas eu mesmo não tive um bom caso de uso. Talvez algum dia!

@EliasHasle Minha implementação é uma árvore de objetos de classe JS (eu uso classes ES6, ou seja, instâncias de protótipo). Basicamente, um nó é uma árvore na minha implementação. No entanto, eu tenho uma classe Octree adicional que contém o nó raiz e fornece métodos para construir e pesquisar (e também algumas depurações e visualização) na árvore.

Eu não experimentei muito com os valores para o nível máximo do nó da árvore e o número máximo de vértices por nó folha. Talvez haja uma combinação melhor.
Também uso uma hierarquia de volume delimitadora para acelerar os testes de interseção. Então eu testo a esfera delimitadora e a caixa delimitadora da malha antes de verificar a octree da geometria da malha.

Posso recomendar um livro que é uma coleção muito boa de abordagens de detecção de colisão: C. Ericson, Real-Time Collision Detection, CRC Press, 2004

@gkjohnson Isso parece ótimo! O desempenho é impressionante. Que tipo de BVH você está usando?

@matthias-w Obrigado!

Existem algumas opções de estratégia de divisão, mas dividir os nós BVH no centro do lado mais longo cria a árvore mais rapidamente. Os triângulos são particionados em lados com base no centro de seus limites e os nós de árvore são expandidos para conter totalmente os triângulos filhos (portanto, há uma pequena sobreposição de nós de árvore).

@gkjohnson Então, a implementação do BVH é um tipo de árvore Kd desequilibrada com seleção de eixo dependente da forma da caixa, certo? Se sim, eu estava pensando em fazer algo assim para casos em que a raiz BB estava muito longe de um cubo e, em seguida, usar octrees após a divisão condicional. Isso provavelmente se aplicaria bem a casos como o mundo do mapa de @Usnul , onde a divisão inicial seria nas duas dimensões do "mapa" e a divisão subsequente prosseguiria em 3D. Eu acho que é uma solução muito melhor que a minha, que é expandir o BB raiz para um cubo delimitador com o mesmo centro e, em seguida, usar a divisão octree até o fim.

Acabei de implementar um método melhor para raycasting em PlaneBufferGeometry.

@kpetrow Acho que otimizar raycasts em PlaneBufferGeometry , a suposição de que as posições dos vértices não serão alteradas provavelmente não será válida para as geometrias de alta resolução em que uma pesquisa linear é insuficiente. Até onde eu sei, o principal uso do PlaneBufferGeometry de alta resolução é remodelá-lo movendo os vértices, mantendo a topologia, por exemplo, para construir terrenos.

Fechando a favor de #13909.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

yqrashawn picture yqrashawn  ·  3Comentários

donmccurdy picture donmccurdy  ·  3Comentários

konijn picture konijn  ·  3Comentários

makc picture makc  ·  3Comentários

filharvey picture filharvey  ·  3Comentários