Mesclando geometria / malha sem perder benefícios


11

No three.js, podemos simplesmente mesclar a geometria para limitar a quantidade de chamadas de empate e, assim, aumentar o desempenho. Em um teste simples com um material, eu poderia desenhar 50.000 cubos + sombras a 60fps na minha GPU GTX660. Sem a fusão da geometria, 5.000 cubos já causaram um problema.

Gostaria de saber como preservar os benefícios de renderizar cada malha de cubo por si própria. Por exemplo, como escolher uma malha de cubo quando tudo é mesclado em uma geometria? Por padrão, isso não é possível, é claro.

Existe alguma técnica comum para esse problema? Afinal, eu tenho todos os objetos de malha não imersos, mesmo após a mesclagem. Portanto, deve haver alguma maneira de utilizá-los para a colheita?

O que eu quero fazer em poucas palavras

  • SimCity como jogo para fins de aprendizado
  • Cada casa é uma malha de cubo
  • Deseja renderizar 50.000 casas e poder adicionar e remover casas
  • A seleção da casa via cursor do mouse (picking) deve ser possível

Não tenho certeza se isso é útil para você, mas mencionei por completo. O Simplygon possui um modelo de precificação baseado em royalties para desenvolvedores independentes e pode fazer muito desse processo de mesclagem e particionamento em tempo de design.
steeveeet

Respostas:


11

OK, entendi. Depois de mesclar toda a geometria, ainda tenho as malhas individuais em uma matriz. Então, eu posso simplesmente usar essas malhas para transmissão de raios, mesmo que elas nem sejam renderizadas. Levei um tempo para perceber isso.

insira a descrição da imagem aqui

Para a colheita, uso esta implementação de octree: http://threejs.org/examples/#webgl_octree_raycasting

Isso reduz os testes de interseção por atualização de 50.000 para ~ 500. Sem o octree, o fps diminuirá bastante.

O casco de picking laranja que você vê é, na verdade, a malha agora renderizada (+1 de chamada) com um material alterado e tamanho modificado.

insira a descrição da imagem aqui

Então, acho que o próximo passo é implementar algum tipo de particionamento de mapa. Ou seja, quebre a geometria mesclada em várias partes. A razão para isso é que a geometria mesclada possui uma grande quantidade de vértices. Isso significa que, se eu retirar o mapa 99% da tela, a placa de vídeo ainda precisará processar todos os vértices porque a geometria ainda está em exibição, pelo menos 1% dela. Portanto, se estiver quebrado, apenas as peças em exibição precisam ser renderizadas.


Muito obrigado por esse insight. Também tenho tentado encontrar uma maneira de fazer isso, e acho que sua solução aqui é excelente! Porém, uma pergunta rápida: para a sua lista local de objetos (por exemplo, Three.Object3D), que tipo de propriedades são necessárias para o rayCaster.intersectObjects () funcionar?
AlvinfromDiaspar 26/09

Muito bem feito.
ClassicThunder

Eu tenho um problema semelhante, mas de alguma forma não consigo fazer o raycasting funcionar com o r70. Você fez algo especial ao criar e mesclar as caixas? Uso o código a seguir ( pastebin.com/PStaAF3P ) para criar e mesclar os nós, mas talvez haja algo faltando para que o raycaster funcione?
fhahn

Pergunta rápida: Estou fazendo algo muito parecido com você (um mapa 3d baseado em dados geoJSON). Com o seu método, sempre que você gira a câmera, você também precisa girar as malhas de construção pré-existentes? Ou você apenas adiciona caixas individuais à cena, mas não as processa?
Spencer #

@ Spencer Não, não precisa girar. Eu mantenho caixas individuais em uma matriz global e apenas adiciono geometria mesclada à cena. Você pode fazer radiodifusão com o objeto na matriz global, porque o raycaster depende da matriz da câmera e da posição de cada caixa. Provavelmente não é a melhor maneira, isso foi apenas uma prova de conceito para mim. Não há mais three.js neste momento.
user990827

1

Para escolher, você também pode renderizar IDs de cada cubo para outro destino de renderização e apenas verificar qual é o valor do ID no cursor. O benefício é que a escolha é perfeita em pixels e funciona com eficiência também para geometria mais complexa.

Se todos os objetos tiverem a mesma geometria, você poderá usar a renderização instanciada. Um fluxo define a geometria, enquanto outro define propriedades por instância (por exemplo, transformação). Para o descarte de frustum, você precisaria criar o fluxo da instância de cada quadro com base no teste de visibilidade. Se você tiver uma grande quantidade de objetos, convém colocá-los em uma octree frouxa ou em algo para acelerar a seleção.


0

Não tenho certeza dos detalhes do three.js, mas dois possíveis problemas de desempenho vêm à mente em geral no OpenGL:

  1. Você já pensou em instanciar? Você precisará apenas de uma chamada também e usará menos VRAM.
  2. Você deu uma olhada séria no algoritmo de picking? Se seus cubos tiverem volumes delimitadores em uma lista em vez de uma árvore, por exemplo, isso explicaria uma diferença dessa magnitude.

0

Outra abordagem que você pode adotar é criar algum atributo de vértice em sua geometria e colocar a lógica de destaque em seu shader de fragmento. Isso é extremamente útil quando você não deseja ter duas cópias de dados na memória e terá mais controle de como o destaque é implementado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.