Pergunta

Eu li em algum lugar que, ao renderizar muitos objetos 3D, poderia -se mesclar para formar uma malha gigante, para que apenas uma chamada fosse feita. Portanto, deixando a citação: "GPU fazer sua mágica", enquanto o A CPU é gratuita para outras chamadas do que desenhar.

Então, para a minha pergunta, isso seria viável em um 2D Ambiente com atuação em mente?

Por exemplo, digamos que temos um sistema de ladrilhos simples e, em vez de fazer uma chamada para cada ladrilho em vista, um seria mesclar todos os azulejos Para formar um sprite grande e depois chamar um empate.

Qualquer visão do assunto - dicas, links ou outros enfeites - é muito apreciada, pois não tenho experiência anterior no desempenho gráfico.

Editar: Desculpe pela minha pobre explicação. Estou criando um enxerto de azulejo para uso pessoal e quero que seja o mais versátil possível. Portanto, quero otimizar apenas caso eu tenha que desenhar muitos ladrilhos em um futuro próximo.

EU Faz Use uma folha de inclinação, mas o que eu quis dizer com a pergunta é se a fusão de todos os ladrilhos que devem ser extraídos da folha para uma nova textura2D ganhará desempenho. Por exemplo:

Temos peças 128x72 para desenhar na tela. Em vez de fazer loop através de todos os ladrilhos e chamando o sorteio para que cada ladrilho seja desenhado, mesclamos todos os ladrilhos em um novo sprite 1280x720 de tamanho e o desenhamos. Dessa forma, o método draw () só será chamado uma vez por quadro. Meu pergunta foi se isso melhorar o desempenho, pois fundiria objetos 3D em uma única malha ao fazer 3D.

Porque as informações que reuni é que o chamado draw () é um porco de desempenho e deve ser chamado o mínimo possível. Alguém para confirmar ou negar? :)

Foi útil?

Solução

Não tenho nenhuma experiência com XNA e 3D, mas darei alguns conselhos para jogos em 2D. Passei algum tempo criando um mecanismo de ladrilhos em XNA no início deste ano e me perguntei a mesma coisa. Eu acho que a resposta curta aqui é sim, combinar seus ladrilhos em um sprite maior é uma boa ideia se você estiver preocupado com o desempenho. No entanto, há uma resposta muito mais longa se você estiver interessado.

Em geral, quando se trata de otimizações de desempenho, a resposta é quase sempre: "Não faça isso". Se você tem certeza de que precisa otimizar o desempenho, a próxima resposta é quase sempre: "Não faça isso ainda". Por fim, se você tentar otimizar o desempenho, a coisa mais importante que você pode fazer é usar os benchmarks para reunir medições precisas do desempenho antes e depois das alterações. Sem isso, você não sabe se está conseguindo!

Agora, relacionado mais aos jogos em 2D, aprendi que vi um desempenho muito melhor no meu motor de ladrilhos, menos que mudei de texturas. Por exemplo, digamos que eu tenho um ladrilho de grama e um ladrilho de cascalho. Se estas são duas texturas separadas na memória, e eu desenho um azulejo de grama, depois um ladrilho de cascalho, depois um ladrilho de grama na tela, a GPU carregará a textura da grama e depois trocará para carregar a textura do cascalho e depois alternar o Textura da grama de volta para desenhar outro ladrilho de grama. Isso mata o desempenho muito rapidamente! A maneira mais fácil de contornar isso é ter uma folha de sprite, onde você coloca sua grama e texas de cascalho em uma textura e basta dizer à Spritebatch para extrair de uma área diferente na mesma textura a cada vez.

Outra coisa a considerar é quantas ladrilhos você estará desenhando na tela de uma só vez. Não me lembro especificamente, mas estava desenhando milhares de ladrilhos de uma só vez (em uma vista ampliada). Percebi que, quando usei telhas maiores e desenhei menos delas, como você está sugerindo em sua pergunta, esse desempenho também melhorou. Isso não foi tão grande quanto o que eu descrevi no último parágrafo, e eu ainda o encorajaria a medir as mudanças de desempenho resultantes de diferentes implementações. Além disso, se você estiver apenas desenhando uma dúzia ou poucas centenas de telhas, pode não valer a pena tentar otimizar isso agora (veja o segundo parágrafo).

Só para você saber que não estou inventando completamente isso, aqui está um link para um post de Shawn Hargreaves sobre troca de textura, folhas de sprites, etc. Provavelmente existem posts melhores nos fóruns XNA e no blog de Shawn Hargreaves se você pesquisar no o tópico.

http://forums.xna.com/forums/p/24254/131437.aspx#131437

Atualizar:

Desde que você atualizou sua pergunta, deixe -me atualizar minha postagem. Decidi apenas comparar algumas amostras para lhe dar uma idéia de quais podem ser as diferenças de desempenho. Na minha função draw (), tenho o seguinte:

        GraphicsDevice.Clear(Color.CornflowerBlue);

        Stopwatch sw = new Stopwatch();
        sw.Start();

        spriteBatch.Begin();

#if !DEBUG
        spriteBatch.Draw(tex, new Rectangle(0, 0, 
                         GraphicsDevice.Viewport.Width,
                         GraphicsDevice.Viewport.Height), 
                         Color.White);            
#else
        for (int i = 0; i < 128; i++)
            for (int j = 0; j < 72; j++)
            {
                Rectangle r = new Rectangle(i * 10, j * 10, 10, 10);
                spriteBatch.Draw(tex, r, r, Color.White);
            }
#endif
        spriteBatch.End();

        sw.Stop();

        if (draws > 60)
        {
            numTicks += sw.ElapsedTicks;
        }
        draws++;

        if (draws % 100 == 0)
            Console.WriteLine("avg ticks: " + numTicks / (draws - 60));

        base.Draw(gameTime);

Basta soltar o ponto de exclamação na declaração "#if! Debug" para alternar entre os dois métodos. Eu pulei os primeiros 60 empates porque eles incluíam alguma configuração inicial (não tenho certeza do quê) e estavam distorcendo as médias. Baixei uma imagem de 1280x720 e, para o melhor caso de teste, acabei de desenhar uma vez. Para o caso de teste inferior, desenhei a imagem de origem em ladrilhos, 128x72 como você fez sobre sua pergunta. Aqui estão os resultados.

Desenhando uma imagem:

avg ticks: 68566
avg ticks: 73668
avg ticks: 82659
avg ticks: 81654
avg ticks: 81104
avg ticks: 84664
avg ticks: 86626
avg ticks: 88211
avg ticks: 87677
avg ticks: 86694
avg ticks: 86713
avg ticks: 88116
avg ticks: 89380
avg ticks: 92158

Desenho de 128x72 ladrilhos:

avg ticks: 7902592
avg ticks: 8052819
avg ticks: 8012696
avg ticks: 8008819
avg ticks: 7985545
avg ticks: 8028217
avg ticks: 8046837
avg ticks: 8291755
avg ticks: 8309384
avg ticks: 8336120
avg ticks: 8320260
avg ticks: 8322150
avg ticks: 8381845
avg ticks: 8364629

Como você pode ver, há uma diferença de ordem de magnitude lá, por isso é bastante significativo. É muito simples testar esse tipo de coisa, e eu recomendo que você execute seus próprios parâmetros de referência para sua configuração específica para levar em consideração algo que eu poderia ter perdido.

Outras dicas

Quanto menos a placa gráfica tiver para alternar as texturas, melhor o desempenho. Você pode classificar por textura no método spritebatch.begin (), se quiser, para que a placa gráfica alterne as texturas o mínimo possível.

Coloquei meus ladrilhos / sprites em lençóis quando faz sentido. Por exemplo, um caractere pode estar em uma folha e uma camada de ladrilhos pode estar na mesma folha. Isso funcionou muito bem até agora.

Eu diria que não otimize até que você precise. Se seus jogos funcionam rápido o suficiente, como é por isso que se preocupa com a otimização.

Retângulo r = novo retângulo (i * 10, j * 10, 10, 10);

Criar muitos novos objetos chamará a coleção de lixo que pode desacelerar muito! Você não deve alocar novos objetos em grandes loops:

O desempenho não é um imperativo universal ou um mandamento de Deus; É um meio para um fim. Se o que você tem um desempenho bom o suficiente, você não tem literalmente nada a ganhar ao melhorar seu desempenho. Manter "o melhor desempenho possível em todos os momentos" é a definição de otimização prematura e causará mais dores de cabeça do que evita.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top