Como posso testar a unidade de renderização?

19

Estive adotando o TDD (Test-Driven Development) recentemente e isso teve um impacto maravilhoso no resultado do meu desenvolvimento e na resiliência da minha base de código. Gostaria de estender essa abordagem a alguns dos trabalhos de renderização que faço no OpenGL, mas não consegui encontrar boas abordagens para isso.

Vou começar com um exemplo concreto para sabermos que tipo de coisas eu quero testar; digamos que eu queira criar um cubo de unidade que gire em torno de algum eixo e que garanta que, para algum número de quadros, cada quadro seja renderizado corretamente.

Como posso criar um caso de teste automatizado para isso? De preferência, eu seria capaz de escrever um caso de teste antes de escrever qualquer código para renderizar o cubo (por práticas usuais de TDD). Entre muitas outras coisas, eu gostaria de garantir que o tamanho, o local e a orientação do cubo sejam correto em cada quadro renderizado. Talvez eu queira ter certeza de que as equações de iluminação em meus shaders estão corretas em cada quadro.

A única abordagem remotamente útil que encontrei envolve a comparação da saída renderizada com uma saída de referência, que geralmente impede a prática do TDD, e é muito complicada.

Eu poderia continuar com outros requisitos desejados, mas temo que os que eu listei já estejam fora de alcance.

entalhe
fonte
3
O problema aqui é que seu caso de teste é determinado por uma boa saída; mas o que acontece se esse resultado for incorreto (falso positivo)? De qualquer maneira, começaria verificando os wireframes primeiro; depois vá para uma cena renderizada para frente e, finalmente, adiada (se você a usar). Você pode fazer o XOR da imagem inteira para fazer uma comparação rápida (passes totalmente em preto). A GPU é realmente uma área ruim para aplicar TDD; mas se você tiver alguma coisa inteligente, eu adoraria saber.
Jonathan Dickinson
Suspeito que não receberei exatamente a resposta que espero, mas ainda espero algumas boas idéias. Bom pensamento no passe preto. Testar o buffer de profundidade também pode ser útil.
fácil
@ Adam obrigado por compartilhar isso. Infelizmente, é maneira fora do alcance para um indie como eu trabalhando em jogos para celular :) Ele também falhar a maioria dos meus requisitos básicos.
Janelas
@ Adam, você definitivamente deve 'responder' a esse link. Muito romance.
Jonathan Dickinson

Respostas:

8

Parece uma boa aplicação da estrutura Testes de aprovação ou algo parecido.

Conforme declarado nos comentários, você ainda terá um problema com falsos positivos, se aprovar resultados ruins, mas isso indica pelo menos quando a saída mudou significativamente.

Como você está usando o OpenGL, presumo que as aprovações não funcionem diretamente para você, mas a ideia é sólida. Basta verificar o hash do arquivo e, se for diferente, mostrar a falha em um visualizador de diferenças apropriado (como um programa de diferenças de imagem). Se você aprovar a nova versão, atualize o arquivo "aprovado" para corresponder ao novo resultado.

John Gietzen
fonte
Essa é uma ferramenta interessante. Se você pegasse algo como o farm de testes no link de Adam nos comentários acima e aplicasse um mecanismo de aprovação integrado como esse, provavelmente começaria a abordar algo que é muito baixo. Obrigado por compartilhar!
notlesh
O teste de aprovação não é automático.
Zwcloud 11/11/19
@zwcloud: Como assim? É automatizado quando é criado, como qualquer teste. Só que a primeira aprovação faz parte do processo de criação.
John Gietzen
@ JohnGietzen Não entendi isso com a sua resposta. Eu acho que você deve esclarecer a ideia dos Testes de aprovação mais explicitamente. Vou remover o voto negativo quando a resposta for atualizada.
Zwcloud 4/11/18
6

Eu não sou do ramo de jogos, então, por favor, tenha qualquer percepção estúpida e ingênua em potencial

Para mim, escrever testes que comparem imagens totalmente renderizadas não são realmente testes de unidade , mas testes de integração completa , porque tudo tem que funcionar bem para uma execução de teste bem-sucedida.

Que tal uma camada intermediária onde você pode verificar se está tudo bem? Há duas coisas que me vêm à mente:

  1. Não desenhe diretamente, mas emita um fluxo de comando que se transforma em renderizar chamadas no caminho. O fluxo de comando pode ser verificado quanto à correção. Este não é um teste de ponta a ponta, mas você deseja testes de unidade , não testes de integração completa.

  2. Essa é realmente uma variação do 1. Envolva o OpenGL, atenda todas as chamadas, reduza para o que você realmente deseja testar e verifique se a saída ainda corresponde. O wrapper OpenGL pode fazer a própria verificação, se configurado corretamente, e se transforma em uma farsa .

Stefan Hanke
fonte
3

O problema é que os motores 3D não precisam gerar uma imagem exata, bit a bit. Alguma margem de manobra é tolerada desde que os artefatos causados ​​por ela não sejam visíveis para o visualizador. Uma textura 1% mais escura que o esperado geralmente não é um problema sério ... geralmente. Sob algumas condições, pode ser um artefato visual. E esse é o problema: é difícil julgar por um teste automatizado quais artefatos seriam notados por um espectador humano e quais não são. Ainda assim, testes automatizados podem ser usados ​​para verificações simples de sanidade quando usados ​​em geometria muito simples.

O que você pode fazer é renderizar algumas cenas simples e comparar a imagem gerada com uma renderização de referência. Essa renderização de referência pode vir de outro mecanismo gráfico ou ser uma captura de tela anterior do mesmo mecanismo (teste de regressão).

Quando alguns testes falham após uma alteração no mecanismo gráfico, um testador humano deve comparar a saída com a imagem de referência e julgar por si próprio se a nova saída parece tão boa quanto antes (ou melhor ainda). Nesse caso, o teste deve ser alterado para comparar com os novos e aprimorados resultados.

Outra coisa que você pode verificar automaticamente são os requisitos de desempenho. Um desses requisitos poderia ser que, durante uma demonstração de execução automática (simulando uma sequência real do jogo), a taxa de quadros não caia abaixo de 40 Fps no sistema de teste. Isso é algo que você pode testar automaticamente. O que você não pode testar é que a renderização é satisfatória. Mas você pode usar esses testes para impedir que seus desenvolvedores desenvolvam um jogo que pareça excelente, mas que não funcione adequadamente em nenhum sistema acessível até anos após o lançamento (olá Crytek).

Philipp
fonte