Como posso incorporar a física em um mundo processualmente gerado a partir de um sombreador de geometria?

10

Essencialmente, quero remover a necessidade de gerar ruído coerente da CPU para a GPU. A partir daí, também quero gerar o terreno para um mundo tridimensional usando esse ruído como densidades nos pontos voxel. Depois disso, quero pegar essas densidades e poligonizá-las (gerar vértices), representando o terreno do mundo.

Tudo bem e tudo. Mas também quero deformar dinamicamente o mundo em tempo real. Quando chego a esse ponto, tenho um problema ao tentar obter os vértices de volta à CPU para fazer coisas como detecção de colisão e todos os cálculos de jogos que quero envolver na CPU e não na GPU.

Portanto, a pergunta é: como posso obter um subconjunto dos vértices de volta à CPU para lidar com colisões, entre outras coisas?

E mais uma pergunta: existe uma maneira fácil de pegar um conjunto de vértices e gerar índices a partir deles na GPU?

Estou confuso e com que tipos de shaders devo usar para essas coisas diferentes. Eu ouço pessoas usando um sombreador de pixel para coletar densidades e, em seguida, usando um sombreador de geometria para lidar com a geração de terreno a partir dos vértices e, de alguma forma, incorporando um sombreador de vértice para fazer as deformações dinâmicas.

Estou usando C # 4.0, .NET 4.0 e XNA Game Studio 4.0.

Michael J. Gray
fonte
1
Você diz que está usando um sombreador de geometria no título, mas também diz que está usando o XNA4.0, tanto quanto eu sei que o XNA 4.0 requer o DirectX 10 (para facilitar o desenvolvimento para uma plataforma mais uniforme), mas suporta apenas recursos SM3.0, portanto, nenhum sombreador de geometria. forums.create.msdn.com/forums/p/31369/178924.aspx
Roy T.
E agora não vou mais usar o XNA nem refazer o meu design. Obrigado por apontar isso. Eu estava pesquisando e não percebi essa limitação (sem SM 4). Suponho que a questão ainda permaneça, sem a consideração do XNA. Portanto, de uma perspectiva do DirectX, existe uma maneira de fazer o que eu quero? Ou talvez com um shader de vértice no XNA?
1
Bem, o XNA ainda é válido para uso, a menos que você tenha um caso de teste comprovado em que as deformações e a geração são muito lentas. E que você tenha provado em outro teste caso que GPU deformam + geração e, em seguida, recebendo dados de volta para a CPU é mais rápido :)
Roy T.
De fato. Descobrimos que usar XNA e manter tudo na CPU nos deu cerca de 1 milhão de vértices em aproximadamente três minutos em um Core i7 com 8 núcleos e 8 threads, paralelizando várias seções do terreno por segmento. Ao tentar fazer isso em tempo real e, esperançosamente, renderizar o terreno antes que o jogador pudesse vê-lo, alcançamos cerca de 20 quadros por segundo. Portanto, um caso de teste está definitivamente em ordem com cada um dos métodos.
22911 Michael Michael Gray

Respostas:

3

Como o XNA não suporta shaders de geometria, responderei como se você estivesse usando o DX 10. Você tem essencialmente três opções.

Shaders de geometria Os shaders de geometria podem realmente modificar e adicionar vértices a um buffer de vértice. Você pode ler isso de volta na CPU. Eu não olhei para isso, mas é definitivamente possível.

Basta usar a CPU Em segundo lugar, por que você simplesmente não calcula na CPU? O fato de ser executado na GPU em shaders sugere que seu algoritmo de deformação é localizável, ou seja, você pode facilmente gerar apenas as partes relevantes para a verificação de colisão.

Por exemplo, eu fiz um jogo de vela há um tempo atrás. O oceano usou os shaders de vértice e geometria para deformar a água com ondas. Usei o mesmo algoritmo calculado na CPU em apenas alguns pontos sob o barco para o movimento do barco nas ondas. Tenho certeza de que você poderia fazer algo semelhante ao seu mapa voxel.

Pixel shaders A última opção, você mencionou isso na sua pergunta também: gere as densidades no pixel shader e grave-o em uma textura 3D. Você pode acessar isso a partir da CPU e dos shaders de maneira bastante inofensiva. O pixel shader é perfeito para esta tarefa, mas esse método possui muita sobrecarga. Renderização da textura do volume, bem como amostragem de dentro no vértice e na região geográfica. shaders e ter que ler a textura na CPU.

Não sei as especificidades do seu projeto, mas sempre usaria a CPU para isso. Por todos os meios, calcule as densidades também nos shaders, mas continue usando a placa gráfica para renderização.

Hannesh
fonte
O principal problema que tivemos foi a barreira da GPU-CPU. No sentido de, uma vez que geramos e renderizamos o terreno na GPU, como podemos descobrir como o terreno se parece no lado da CPU das coisas para fazer colisões e outras coisas. Suponho que seu pensamento sobre mantê-lo na CPU seja válido. Quero dizer, provavelmente podemos otimizar bastante nosso algoritmo e gerar menos terreno. Marcarei sua resposta como a solução em um ou dois dias para ver se mais alguém tem uma resposta. Obrigado por provocar alguns pensamentos alternativos.
18711 Michael J. Gray
Com o seu exemplo de vela, você não seria capaz de conectar facilmente o resultado da forma de onda de um barco que espirra nas ondas à GPU, certo?
Deceleratedcaviar
1
Você pode manter o mesmo sistema de renderização, ou seja, gerar e renderizar o terreno na GPU, mas espelhar as partes do terreno necessárias na CPU. Usando o mesmo algoritmo e os mesmos parâmetros, você obteria o mesmo terreno na CPU que você vê na tela.
Hannesh
@ Daniel Não com o algoritmo de ondas diretamente, mas é possível deformar a malha de água de acordo com a esteira do barco com uma textura de deslocamento que cada barco "arrasta" atrás dele.
Hannesh
Ah! É uma ótima ideia :). Mas provavelmente não suporta muito várias embarcações muito bem.
Deceleratedcaviar