O que é uma boa solução de estrutura de dados para um gerenciador de cenas no XNA?

8

Estou jogando com o XNA em um projeto de jogo, tive uma exposição anterior ao OpenGL e trabalhei um pouco com o Ogre, então estou tentando obter os mesmos conceitos trabalhando no XNA.

Especificamente, estou tentando adicionar ao XNA um gerenciador de cenas para lidar com transformações hierárquicas, seleção de objetos (talvez até oclusão) e classificação de objetos de transparência.

Meu plano era criar um gerenciador de cena em árvore para lidar com transformações hierárquicas e iluminação e, em seguida, usar um Octree para seleção de objetos e classificação de objetos. O problema é como fazer a classificação geométrica para suportar as transparências corretamente. Sei que a classificação é muito cara se for feita por polígono, tão cara que nem é gerenciada pelo Ogre. Mas as imagens estáticas do Ogre parecem corretas.

Alguma idéia de como fazê-lo e quais estruturas de dados usar e seus recursos? Eu sei que as pessoas ao redor estão usando:

  • Octrees
  • Kd-trees (alguém no fórum GameDev disse que estes são muito melhores que Octrees)
  • BSP (que deve lidar com pedidos por polígono, mas é muito caro)
  • BVH (mas apenas para seleção de frustum e oclusão)

Obrigado

Tunnuz

tunnuz
fonte

Respostas:

6

Octtrees (ou mesmo apenas quadtrees) e Kd-trees são bons esquemas de particionamento espacial de uso geral e, se seu pipeline de construção e / ou mecanismo os estiver gerando, você descobrirá que eles são úteis de várias maneiras diferentes para otimizar consultas / iterações. Eles funcionam subdividindo um volume fixo de uma maneira hierárquica, o que torna consultas muito baratas como o raycasting no seu espaço de objeto (ótimo para verificações de colisão).

As hierarquias de volume delimitadoras funcionam de uma maneira ligeiramente diferente (elas agregam os volumes dos objetos na árvore em vez de subdividir os espaços) e são uma maneira simples de impedir que coisas desnecessárias sejam repetidas. Mas como o BVH não impõe restrições sobre a relação entre dois nós irmãos, não é um esquema tão bom para descobrir a ordem de renderização ou para consultas arbitrárias de colisão.

Os sistemas BSP são bons quando você está subdividindo o mundo com base em polígonos individuais, mas para objetos maiores, uma abordagem baseada em volume faz mais sentido.

Acima de tudo, vale ressaltar que nenhum desses sistemas é perfeito para determinar a ordem de renderização da transparência, mesmo a abordagem BSP. Sempre será possível construir geometria que quebre seu algoritmo, a menos que você possa subdividir polígonos em tempo real. O que você provavelmente está procurando é uma solução de "melhor esforço", onde a geometria pode ser ordenada corretamente na maioria dos casos; e a equipe de arte pode subdividir modelos para qualquer um dos casos que não funcionam (porque o modelo / polígonos são anormalmente grandes, longos ou se interceptam). Modelos / nós menores são sempre muito mais fáceis de classificar 'corretamente', mas você paga por isso em termos de sobrecarga de iteração.

Kd-trees e Oct / quad-trees são boas soluções de uso geral, para as quais uma implementação amigável da plataforma pode ser escrita, mas no final, você precisará equilibrar a profundidade / complexidade de sua árvore de particionamento espacial com o custo de iterando-o e a sobrecarga por modelo (ou seja, custo da chamada de desenho). Se você estiver direcionando o XNA, recomendo que você o mantenha simples e de alto nível, e se houver problemas de classificação em parte do conteúdo, considere fortemente mudar o conteúdo antes de tentar melhorar seu mecanismo até que ele possa lidar com ele; os retornos diminuem muito rapidamente após a implementação da classificação de renderização mais básica.

MrCranky
fonte
Li que mesmo as técnicas de Depth Peeling para lidar com a classificação por fragmento geralmente obtêm bons resultados. Você acha que isso é possível em um pequeno mecanismo de jogo? Os jogos AAA usam essas técnicas?
tunnuz
O que você acha que é melhor / mais fácil de implementar entre Kd-trees e Octrees?
tunnuz
Eu ficaria muito surpreso se não houvesse uma implementação em C # para os dois já disponíveis: é o tipo de coisa em que a parte dela (a subdivisão e a consulta) é a mesma para todas as implementações, mas os bits interessantes (como você itera / consulta / associa itens aos nós) pode variar. Oct / quad-trees são, em minha opinião, conceitualmente mais simples, mas, como foi apontado, os kd-trees são mais eficientes de várias maneiras. Eu provavelmente usaria o kd-tree apenas porque, se você puder fazer isso, poderá executar o oct-trees (mas o inverso não é necessariamente verdadeiro).
precisa saber é o seguinte
11
Quanto à classificação por fragmento: sem saber nada sobre seu mecanismo, é difícil dizer, mas parece uma otimização prematura. Sim, os jogos AAA podem usar essas técnicas, mas também embaralharão mais objetos do que um mecanismo XNA poderá gerenciar e, portanto, exigirão técnicas de otimização mais extremas para aproveitar ao máximo. Meu conselho seria sempre fazer o básico (classificação da transparência) de maneira sólida e, se você achar que o desempenho não é o ideal, vá em frente e faça uma classificação mais refinada. As chances são de que outra coisa vinculará o desempenho primeiro.
precisa saber é o seguinte
11
Na verdade, existem desenvolvedores de AAA por aí que pulam os BV-tree desde que fazem força bruta, certificando-se de que você realmente usa a maioria das motocicletas de maneira eficiente (nenhum cache LHS / L2 + L1 perde, etc) fornece um desempenho bom o suficiente. É incrível quantos testes você pode realizar com um sistema bem projetado.
21810 Simon
3

McCranky cobriu surpreendentemente todas as estruturas de dados que você mencionou, no entanto, vejo que você não considerou R-Trees. O corpo de conhecimento sobre essas estruturas é enorme e elas são muito adequadas para consultas de alcance espacial (a maior parte do trabalho foi realizada por teóricos e profissionais de banco de dados) nos últimos 30 anos. Recentemente, Sebastian Sylvain, da Rare, deu um curso no GDC sobre por que eles também trabalham em jogos (especialmente em consoles com processadores em ordem). Você pode aprender mais com seu pdf: http://www.gdcvault.com/play/1012452/R-Trees-Adapting-out-of

Uma implementação simples e ingênua é bastante fácil, e a estrutura básica oferece muito espaço para melhorias (melhor gerenciamento de heurísticas de divisão, oportunidades de pré-busca, pesquisa paralela etc.).

Cavaleiro Vermelho
fonte
2

A resposta depende muito da quantidade de modelos que você planeja usar. Eu realmente não trabalhei com esse tipo de coisa para o XNA, mas se você usa o AABB para os testes e não possui muitos modelos, pode ser bom o suficiente com um teste de força bruta. Talvez até jogue fora um fio. Não sei como / se existem otimizações de SSE / VMX que podem ser usadas para C #, mas se você conseguir obter os AABBs linearmente na memória (para que você não perca o cache da CPU), poderá para realizar uma grande quantidade de testes em pouco tempo.

Simon
fonte