A instância melhora o desempenho (significativamente) ao renderizar várias cópias (centenas? Milhares?) Da mesma malha ao mesmo tempo. Mas quanto sobrecarga ela tem ao renderizar exatamente uma cópia com uma chamada de desenho? Seria uma boa ou má idéia usar instanciamento para toda a geometria renderizada pelo mecanismo?
Edit: Digamos que estamos criando um jogo de FPS. A maioria dos objetos tem apenas um exemplo: uma faca, uma arma, uma metralhadora, um prédio e uma torre de rádio. Mas também existem alguns objetos com várias instâncias: árvores (por exemplo, três tipos de árvores com centenas de instâncias), grama e assim por diante ... O que quero dizer é: em vez de renderizar os objetos de uma instância da maneira "tradicional" e árvores e grama usando instanciamento, renderizamos todos eles usando instanciação. Portanto, nossa torre de rádio possui apenas uma instância (cujas informações armazenamos em um buffer de dados da instância) e processamos essa torre usando algum tipo de DrawInstanced()
chamada com contagem de instâncias igual 1
. O mesmo acontece com todos os outros objetos (é claro, árvores e grama têm várias instâncias).
Então, minha pergunta é: é uma má idéia desenhar uma única instância de um objeto usando instanciamento? O instanciamento tem muita sobrecarga (em termos de memória e desempenho) ou é de alguma forma indesejável para renderizar objetos de instância única?
fonte
(No meu sistema, não testei em nenhum outro lugar) No GL, instanciar uma única malha (desenho com contagem = 1) tem uma sobrecarga desagradável, mas não sei de onde ela vem. Eu sugiro fortemente que não faça isso.
Testei isso em uma aplicação prática há alguns meses. Codifiquei alguns algoritmos de iluminação global na cena Crytek Sponza, que consiste em aproximadamente 350 malhas (não me lembro exatamente), das quais algumas compartilham algumas instâncias. No começo, eu fiz como você sugere, instale tudo e desenhe o restante com a contagem de instâncias 1, pois isso simplificou um pouco o código de renderização.
Mais tarde, ao otimizar o renderizador, apenas passar de instanciar os objetos count = 1 para enviá-los da maneira usual me salvou em cerca de 3,5 milissegundos por quadro em um i7 3770k (e GTX 770). Mudar as malhas com várias instâncias para apenas fazê-las da maneira tradicional me salvou mais 0,5 ms. No geral, o aplicativo passou de ~ 120 FPS para cerca de ~ 230 FPS.
É claro que esses números sempre dependem de onde estão os gargalos em seu aplicativo, e os últimos 0,5 ms podem realmente se tornar um abrandamento em um aplicativo em que você é muito limitado. Mas, caso contrário, na minha experiência, a instanciação tem uma sobrecarga desagradável se você não estiver desenhando muitas coisas ao mesmo tempo.
fonte
Você pode ter certeza de que desenhar um único objeto instanciado é mais caro do que desenhar um único objeto normalmente. Para instanciar, a GPU está se preparando para uma grande quantidade de objetos e essa preparação será diferente da de um único objeto. No entanto, o tamanho dessa lacuna de desempenho só pode ser encontrado através da experimentação e depende muito da sua configuração de renderização real. A única maneira de saber com certeza é testando você mesmo. O benchmarking de uma única chamada de empate é difícil. Aqui estão várias idéias sobre como você pode proceder.
fonte
Faz quatro anos ... e acho seguro dizer que é perfeitamente adequado enviar chamadas de instancia "instanciadas" com 1. Como você deve ter notado, as novas APIs DX12 e Vk têm uma contagem de instâncias que pode variar de 0 a NUM_INSTANCES . Observe também que não há DrawIndexed (...) .
EDITAR
Como uma nota de cautela, o acima exposto provavelmente é bom com essas APIs modernas, talvez o uso de algo antigo como Gl <3.3 ou DX11 exija alguns perfis, conforme mencionado por outros usuários.
fonte