Babylon Native em um ambiente sem cabeça
Quando dizemos renderização, geralmente estamos falando de renderização a 60 fps para um aplicativo, seja um jogo ou outro aplicativo que utilize a GPU. Existem, no entanto, outros cenários em que podemos querer usar a GPU para executar processos que nunca exibem absolutamente nada, como processar um vídeo, manipular imagens ou renderizar ativos 3D, talvez todos executados em um servidor. Neste artigo, descreverei como tais cenários podem ser alcançados com o Babylon Native. Especificamente, mostrarei um exemplo de como podemos usar o Babylon Native para capturar imagens de ativos 3D usando o DirectX 11 no Windows.
Se você ainda não leu algumas de nossas outras histórias sobre o Babylon Native , especialmente se você nunca ouviu falar do Babylon Native antes, pode valer a pena lê-las para obter algum contexto antes de continuar.
Isenção de responsabilidade: os contratos de API usados neste exemplo estão sujeitos a alterações, pois a equipe principal ainda está trabalhando no formato correto do contrato de API.
ConsoleApp
O repositório de exemplo está localizado aqui . Ele usa o CMake para gerar projetos do Visual Studio direcionados ao Windows. As dependências Babylon Native e DirectXTK são incluídas por meio de submódulos e consumidas no CMake. A dependência DirectXTK é usada apenas para salvar uma textura DirectX em um arquivo PNG. A essência do aplicativo é um arquivo chamado App.cpp mais a contraparte JavaScript em index.js . Vamos mergulhar em alguns detalhes começando com o lado nativo.
O dispositivo gráfico
Primeiro, precisamos criar um dispositivo DirectX autônomo.
Este código não é incomum, mas pode ser ajustado para usar WARP , por exemplo, se o ambiente não tiver GPU.
Em seguida, criaremos um dispositivo gráfico Babylon Native usando este dispositivo DirectX.
Devemos especificar a largura e a altura (1024x1024 neste exemplo), pois o dispositivo Babylon Native não está associado a uma janela ou exibição como normalmente é.
O host JavaScript
E, é claro, também devemos criar o ambiente de host JavaScript, neste caso usando Chakra (o padrão para Windows), para carregar o núcleo Babylon.js e os módulos carregadores, bem como o index.js mencionado anteriormente, onde fica a lógica JavaScript . Depois, também começamos a renderizar um quadro que desbloqueará o JavaScript de enfileirar comandos gráficos.
O uso do Chakra é conveniente com o Visual Studio, pois podemos adicionar uma debugger;instrução em qualquer lugar no código JavaScript e o Depurador Just-In-Time do Visual Studio solicitará uma caixa de diálogo para depurar o JavaScript. Observe que o aplicativo deve estar em execução na configuração de depuração para que isso funcione.
A Textura de Saída
Também devemos criar uma textura de destino de renderização de saída para a outputRenderTargetcâmera Babylon.js. Primeiro, criamos uma textura de destino de renderização DirectX.
Em seguida, expomos a textura nativa ao JavaScript por meio de um plugin Babylon Native chamado ExternalTexture.
Observe que, como este não é um aplicativo de renderização normal, estamos renderizando explicitamente quadros individuais e, portanto, também precisamos de construções de sincronização ( std::promiseneste caso) para garantir a ordem correta. Conforme observado na documentação de ExternalTexture , a ExternalTexture::AddToContextAsyncfunção requer que o dispositivo gráfico renderize um quadro antes de ser concluído. O addToContextfuturo aguardará até AddToContextAsyncser chamado e FinishRenderingCurrentFramerenderizará um quadro para permitir AddToContextAsynca finalização.
O JavaScript (Parte 1)
Em seguida, revisaremos a primeira parte ( startup) do lado do JavaScript. Ignorando o mecanismo típico do Babylon.js e a configuração da cena, esta função recebe um argumento chamado nativeTextureque é a textura do resultado de AddToContextAsync. Esse argumento é então agrupado usando wrapNativeTexturee adicionado como o anexo de cor de uma textura de destino de renderização Babylon.js. Veremos como isso é usado em breve.
Os ativos da glTF
De volta ao lado nativo, agora estamos prontos para carregar os ativos glTF e capturar imagens.
Isso pode parecer longo, mas não é muito complicado. Estamos percorrendo cada ativo e chamando a função JavaScript loadAndRenderAssetAsync, esperando que ela seja concluída e salvando um PNG no disco.
O JavaScript (Parte 2)
A loadAndRenderAssetAsyncfunção, no lado do JavaScript, importa o recurso glTF, configura uma câmera, aguarda a cena ficar pronta e renderiza um único quadro. Isso deve ser semelhante ao que aconteceria com um aplicativo da web usando Babylon.js!
O destino de renderização de saída da câmera é atribuído à textura de destino de renderização de saída anterior para que a cena seja renderizada para esta textura de saída em vez do buffer traseiro padrão que, é claro, não existe neste contexto. Isso, por sua vez, será renderizado diretamente para a textura de destino de renderização nativa do DirectX que configuramos anteriormente.
O resultado
Construir e executar o exemplo ConsoleApp tem esta aparência.
Junto com três arquivos PNG.
The RenderDoc
Tem mais uma coisa! Observe as chamadas de função auxiliar para RenderDoc::StartFrameCapturee RenderDoc::StopFrameCapture? Isso dirá ao RenderDoc para iniciar e parar a captura de um quadro, pois o RenderDoc não saberá quando um quadro começa ou para, pois não estamos no caso típico de renderização. Podemos ativar a captura RenderDoc descomentando uma linha em RenderDoc.h. O uso do RenderDoc é incrivelmente útil para depurar problemas com a GPU.
Conclusão
Espero que isso lhe dê uma ideia de como o Babylon Native pode ser usado em um ambiente headless. Não é o cenário típico, mas é um cenário mais difícil ou mais caro de ser alcançado usando outras tecnologias. Continuaremos nos esforçando para tornar o Babylon Native útil em tantos cenários quanto possível.
Gary Hsu — líder da equipe nativa da Babylon





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)