Prática de otimização e desenvolvimento interativo 3D em grande escala | Equipe técnica JD Cloud

fundo de desenvolvimento

Graças à explosão do conceito "Metaverse" há algum tempo, várias empresas lançaram atividades ou canais usando cenas 3D.

Em comparação com a página 2D tradicional, a cena 3D tem mais uma dimensão e mais conteúdo pode ser exibido na mesma tela, que pode exibir completamente as informações de objetos e produtos.

A desvantagem correspondente é que o método de uso do usuário muda e o usuário precisa de custos adicionais de aprendizado. Além disso, a quantidade de desenvolvimento, recursos artísticos e equipamentos para geração de modelos 3D necessários na fase inicial também são custos acrescidos.

Neste contexto, a nossa equipa recebeu um pedido de desenvolvimento de um projecto interactivo do Food Channel. Esperamos que através da exibição e interacção de cenas 3D, como tentativa e exploração de futuras compras, possamos ir ao encontro das necessidades dos utilizadores de um produto bonito e futuro novo. . Faça cenários de compras e entretenimento e traga aos usuários uma experiência de compra maravilhosa.

Seleção de framework front-end

Em comparação com os projetos 2D anteriores, o projeto 3D mudou principalmente no desempenho do cliente. Na esperança de não depender do suporte do cliente de aplicativos e ser capaz de executar em tantos ambientes quanto possível, nossa primeira solução é realizar a realização do projeto 3D no lado da Web.

kit de desenvolvimento

Em primeiro lugar, consideramos kits de desenvolvimento maduros, como unity/egret, etc., mas esses kits de desenvolvimento têm alguns problemas que não podemos ignorar, como:

  • O uso comercial requer uma taxa

  • Precisa ser desenvolvido em outras linguagens (como C#), o que vai custar muito para a equipe aprender

  • O tamanho do arquivo da saída empacotada é muito grande

  • Os documentos oficiais não são detalhados o suficiente e a curva de aprendizado é instável

Nome do motor/dimensões de comparação Preço de utilização (peso 50% Introdução ao script (peso 30% Construção da cena (peso 20% Formato do modelo de suporte (peso 10% A riqueza das informações da comunidade (peso 30% Apoiar a publicação na web (um voto de veto
Unidade 3D 3 7 10 8 10 Y
Laya 4 9 7 7 7 Y
Garça 10 8 7 7 6 Y
Cocos2d-js N
Godot 10 7 7 8 7 Y

Devido aos motivos acima, não há escolha satisfatória para a equipe no kit de desenvolvimento e procuramos ferramentas de desenvolvimento em outras direções.

Biblioteca de renderização de código aberto

Além disso, são comparadas duas bibliotecas de renderização 3D amplamente utilizadas pelo front-end Web:

◦ Os componentes fornecidos pelo three.js são pequenos em granularidade e relativamente básicos e podem fazer um alto grau de desenvolvimento secundário personalizado, mas se você precisar desenvolver um projeto interativo, precisará desenvolver mais componentes

◦babylon.js não apenas fornece componentes básicos de pequena granularidade, mas também encapsula componentes prontos para uso. E vem com ferramentas de medição de desempenho, fornecendo métodos de depuração convenientes e estratégias de otimização

Depois de testar vários kits de desenvolvimento/bibliotecas de renderização na equipe, babylon.js foi finalmente selecionado como a biblioteca de camadas de renderização do projeto, e a lógica de negócios foi redesenvolvida nos componentes fornecidos por ela.

Construção da cena do projeto

hierarquia de renderização

O nível de renderização do projeto geralmente é dividido em duas camadas: camada de cena 3D e camada de HUD

A camada de cena 1.3D, como o nome sugere, renderiza cenas 3D, consistindo em modelos interativos, como modelos de personagens, modelos de construção e baús de tesouro

2. A camada HUD renderiza conteúdo de interface do usuário 2D, como botões interativos, janelas pop-up e listas de produtos exigidas pelo negócio

Originalmente, o babylonjs oferece suporte à renderização mista de conteúdo 3D e 2D, mas se você usar o babylonjs para ambas as renderizações, precisará usar uma resolução uniforme ao definir os dois conteúdos, mas nos dispositivos móveis atuais, ele pode oferecer suporte à resolução de pixels (como o iPhone 14 A resolução de pixel é 1170x2532) apenas uma pequena parte da renderização não é interrompida. Na maioria dos dispositivos, ele suporta apenas uma execução suave em uma resolução lógica (como a resolução lógica do iPhone 14 é 390x844), mas definir essa resolução tornará a renderização da camada 2D borrada, portanto, use um método de renderização em camadas.

A camada de cena 3D é renderizada por babylonjs, enquanto a camada HUD é renderizada usando o método DOM tradicional por meio do framework react.

Segunda camada de renderização 3D

A camada de renderização é dividida em camada de cena 3D e camada HUD, o que traz um problema. Quando é necessário renderizar conteúdo 3D na camada HUD, como exibir modelos 3D, é necessário adicionar outra camada de camada de renderização 3D e a camada de renderização 3D não para O método de renderização é chamado para responder às operações do usuário e reproduzir animações, o que consome muitos recursos de computação da CPU e GPU, e também ocupa espaço de memória para armazenar informações de vértice do modelo e texturas do mapa. Portanto, quando várias camadas de renderização 3D coexistem, certo gerenciamento é necessário para otimizar o desempenho. Empregamos a seguinte estratégia para gerenciar várias camadas de renderização 3D:

◦ Reinstância ao exibir outra camada de renderização 3D e suspender a renderização da camada de renderização 3D original

◦ Destrua quando nenhuma exibição for necessária, restaure a chamada do método de renderização da camada de renderização 3D original

A fim de minimizar a ocupação de recursos e melhorar o desempenho de renderização do projeto.

Desenvolvimento de componentes interativos

Verificação de impacto

babylonjs vem com um método para detectar colisões entre modelos, mas se você usar o modelo de alta precisão fornecido pelo designer para chamar diretamente o método de detecção de colisão, a quantidade de cálculo será muito grande. Embora não haja nenhum fenômeno de atraso sério no equipamento de teste, foi Faça o dispositivo quente.

Portanto, é necessário usar um modelo de "parede de ar" invisível e de face fina que envolve o modelo para detecção de colisão. No estágio inicial do projeto, o modelo de "parede de ar" precisa ser fornecido pelo projetista e um modelo de fechamento de baixa precisão é feito no software de modelagem com base no modelo original. No desenvolvimento iterativo subsequente, nossa equipe desenvolveu uma ferramenta de "geração de parede de ar com um clique", que gera automaticamente modelos de baixa precisão, reduz o número de recursos entregues pelos projetistas e reduz a chance de erros na atualização dos modelos.

Prevenção de obstáculos da lente

Como o projeto usa uma lente de terceira pessoa, a lente fica a uma certa distância do modelo do personagem. Quando o personagem caminha ou o usuário controla o ângulo, a lente pode colidir com o modelo arquitetônico ou modelo de cena, resultando no fenômeno de "lente passando pelo modelo".

A lente embutida do babylonjs não tem a função de evitar o modelo. Quando o produto não tem experiência de processamento, fizemos as duas soluções a seguir:

  1. A periferia da lente é circundada por um modelo invisível, e a detecção de colisão é realizada com os modelos de construção e cena assim como os personagens, para que a lente não entre no modelo.

A vantagem dessa abordagem é que o método de detecção de colisão embutido pode ser usado e nenhum desenvolvimento adicional é necessário. Mas as deficiências também são óbvias: o usuário não espera a colisão entre a lente e o modelo e sempre sente que a lente não é natural e está fora de controle.

  1. A câmera e o personagem são conectados por um modelo de bastão, e a detecção de colisão com os modelos de construção e cena também é chamada no modelo de bastão. Quando ocorre uma colisão em uma determinada posição do modelo de bastão, a câmera se moverá para a posição entre o personagem e o ponto de colisão. Ao mesmo tempo em que evita que a lente entre no modelo, também evita que o modelo fique intercalado entre o personagem e a lente, causando o problema de o usuário não conseguir encontrar o personagem.

O efeito alcançado por este método está de acordo com a lógica de movimento da lente de alguns jogos 3D que também são perspectivas de terceira pessoa.O usuário se sente mais natural e não perderá o controle. A quantidade de desenvolvimento adicional introduzido também está dentro de uma faixa controlável.

Transferência de recursos com a equipe de design

formato do modelo

Entre os vários formatos de modelos 3D, escolhemos o formato .gltf. Comparado a outros formatos de modelo, o .gltf pode reduzir dados redundantes em formatos 3D não relacionados à renderização, garantindo assim um tamanho de arquivo menor.

Atualmente, os materiais 3D são relativamente grandes, o que é sem dúvida fatal para a experiência de carregamento do terminal móvel. Portanto, um formato com tamanho menor também tem um peso de preferência maior.

Além disso, .gltf é um resumo de vários formatos 3D nas últimas duas décadas. Ele usa a estrutura de dados ideal para garantir compatibilidade e escalabilidade máximas e suporta mais expansão enquanto possui uma grande capacidade. , como suporte para várias texturas, várias animações, etc

Então .gltf se tornou o único formato de material que combinamos com o visual.

Processo de saída do modelo

Originalmente, o software de modelagem usado pelo fluxo de trabalho do designer era o C4D, mas no processo de transferência de recursos, encontramos vários problemas:

1. Falta de função de arquivo gltf de exportação. Algumas versões do C4D não podem exportar modelos no formato gltf; algumas versões podem exportar, mas há um problema com a exportação. E devido a alguns problemas de suporte ao renderizador usado pelo designer, a versão C4D não pode ser facilmente atualizada.

2. O tamanho do modelo exportado não é uniforme. Talvez por causa de alguma versão de problemas de exportação do C4D, ou algumas configurações no C4D falharam ao exportar para o arquivo gltf, o tamanho do modelo exportado pelo designer várias vezes não é uniforme, por exemplo, o modelo do personagem é várias vezes maior que o modelo arquitetônico.

3. As informações do material de exportação foram perdidas. Quando o designer está modelando, como o modelo pode ser usado em vários canais, como renderização de imagens promocionais, a maioria dos casos usará um renderizador de terceiros para renderização. Neste momento, os materiais exclusivos desses renderizadores podem ser usados ​​em o modelo. Quando esses materiais são exportados para arquivos gltf, as informações desses materiais exclusivos serão perdidas. Ao importá-lo para a cena na página, os designers descobrirão que o efeito exibido está longe do que viram no software de modelagem.

Depois de muitas discussões com designers, estabelecemos um fluxo de trabalho para exportar modelos:

Após a conclusão da modelagem C4D, exporte o arquivo no formato FBX e, em seguida, importe-o para o software do Blender que suporta melhor o gltf. Os designers podem visualizar se seus materiais foram perdidos durante o processo de transferência. O modelo no arquivo gltf exportado pelo Blender pode também manter um tamanho consistente.

iluminação predefinida

Nas configurações de renderização padrão, colocamos a saída do modelo do lado do design na cena e, com a fonte de luz, há apenas mudanças na luz e na sombra, sem sombras e alguns efeitos tridimensionais estão faltando.

Durante nossas tentativas de incorporar sombras, o desempenho foi severamente afetado. Depois de consultar o princípio de renderização, descobri que toda vez que uma sombra é adicionada em um plano, é equivalente a renderizar a cena mais uma vez, e a pressão de renderização dobra.

Depois de comunicar com o lado do projeto, decidiu-se pré-adicionar a projeção do edifício na textura do piso. Este método pode ter um efeito melhor na maioria das cenas com modelos fixos, e as sombras dos personagens podem ser simuladas movendo-se com o modelo usando imagens estáticas.

otimização de renderização

textura comprimida

Durante o período de desenvolvimento, verificou-se que flashbacks são fáceis de ocorrer em dispositivos iPhone mais antigos. Deve ser que a memória usada pela página exceda o limite superior.

O maior recurso utilizado no projeto é o arquivo gltf do modelo. Verifique o conteúdo do arquivo. O mapa de texturas representa grande parte do volume. Após análise dos recursos, verifica-se que o tamanho de muitas texturas é 3K (3072x3072 imagens). De acordo com o princípio de renderização WebGL, não importa qual seja o formato original do recurso de textura e, finalmente, ele precisa ser descompactado antes da renderização, o que significa que uma textura precisa ocupar 3072 x 3072 x 3Byte = 27 MB na memória, e precisa ser transmitido para a GPU após a descompactação, o que é muito provável quando várias texturas são renderizadas ao mesmo tempo Ocupa muita memória.

Após comunicação com o lado do design, foi acordado substituir as texturas de resolução mais baixa em alguns modelos cuja distância de exibição não pode ser muito próxima.

Além disso, geralmente as imagens em formato png/jpg usadas em projetos 2D não são adequadas para renderização em 3D, elas precisam passar pelo processo de descompactação mencionado acima antes de serem lidas pela GPU.

No campo da renderização 3D, existem outros formatos adequados para leitura de GPU, como ETC suportado por Android, PVRTC suportado por iOS e uma nova geração de formato padrão de textura compactada ASTC. Eles podem ser lidos por GPU sem descompactação, o que pode reduzir significativamente o intermediário A capacidade de memória ocupada pela descompressão.

No projeto, usamos a ferramenta gltf-transform para reduzir a resolução da textura e converter o formato.

Redução do modelo

O processo de renderização de um modelo em WebGL é primeiro usar as informações de vértice do modelo para determinar as faces triangulares e, em seguida, calcular a cor a ser exibida em cada face triangular. Portanto, se o número de faces do modelo puder ser reduzido, a quantidade de cálculo para cada renderização pode ser reduzida e o tempo de renderização necessário para cada quadro pode ser reduzido.

Conforme mencionado acima, quando o designer está modelando, ele pode se deparar com a necessidade de gerar renderizações, sem otimizar a renderização em tempo real, portanto, muitas superfícies podem ser usadas em alguns lugares.

Referindo-se à experiência de otimização 1 de outros alunos da equipe, a ferramenta gltf-transform é usada para reduzir automaticamente a superfície do modelo. Após comunicação repetida com o testador de design, determinamos a proporção de parâmetros = 0, erro = 0,0001

renderização em lote

Existe um conceito de chamada de desenho na renderização 3D. Uma chamada de desenho é uma instrução de desenho da CPU para a GPU. Em uma instrução, a CPU transmitirá as informações do triângulo a serem desenhadas para a GPU e como calcular a cor do triângulo. Esse método é chamado de material em uma linguagem que os humanos entendem. Portanto, uma chamada de desenho só pode desenhar superfícies do mesmo material.

Como cada draw call tem essas ações de preparação, geralmente duas draw calls levarão mais tempo do que uma.

No arquivo de modelo, as superfícies do mesmo material podem não estar definidas no mesmo modelo, portanto, a CPU dividirá essas superfícies em diferentes instruções de desenho, aumentando o número de chamadas de desenho.

Existe um método de otimização para essa situação chamado batching, que pode mesclar essas faces do mesmo material para que possam ser desenhadas em uma chamada de desenho.

Não há nenhuma ferramenta para nos ajudar a processar arquivos de modelo neste trabalho, mas ao carregar arquivos de modelo no front-end, podemos percorrer a malha de malha no modelo e mesclar aqueles usando o mesmo material.

Deve-se observar que a malha com animação não pode ser tratada dessa maneira, pois o centro do objeto mesclado mudará, por exemplo, depois que duas bolas auto-rotativas forem mescladas, elas girarão em torno do ponto médio das duas bolas.

Iterações subsequentes

Modelo de carregamento lento e carregamento hierárquico

Embora a cena exibida pelo projeto temporário não seja muito grande e o carregamento e a renderização simultâneos não exerçam muita pressão sobre o dispositivo, mas quando a cena cresce até certo ponto, é necessário introduzir carregamento lento e carregamento hierárquico de o modelo.

◦ Estratégia de carregamento preguiçoso: carregue e insira o modelo na cena quando a câmera se aproximar o suficiente e destrua o modelo longe o suficiente da câmera.

◦ Estratégia de carregamento gradual: quando a câmera estiver distante, carregue um modelo de menor precisão e, em seguida, alterne para um modelo de maior precisão quando estiver mais próximo.

As duas estratégias acima são as estratégias de carregamento usadas por jogos 3D maiores agora, que podem reduzir o número de faces desenhadas na mesma tela e reduzir a pressão de renderização.

Renderização graduada

Atualmente, existe uma grande lacuna no desempenho dos dispositivos para acessar projetos 3D, alguns podem rodar sem problemas com efeitos especiais, e alguns só rodam basicamente na resolução do aparelho.

babylonjs vem com uma função de renderização hierárquica, que pode detectar a taxa de quadros em execução em tempo real para determinar se deve ser rebaixada. Em iterações subsequentes, uma estratégia de renderização hierárquica de resolução de pixel mais efeitos especiais para renderização básica de resolução de dispositivo pode ser adicionada.

iluminação em tempo real

Depois de usar a estratégia de renderização hierárquica acima, você pode adicionar efeitos de luz e sombra em tempo real em dispositivos com melhor desempenho e substituir dinamicamente as texturas pré-criadas

construtor de cena

No processo de desenvolvimento de projeto anterior, designers, produtos e operações precisavam produzir demonstrações por meio do front-end para experimentar aproximadamente o efeito da cena 3D e decidir como ajustar na próxima etapa. Para resolver esse problema, nossa equipe desenvolveu uma ferramenta de criação de cenas 3D. Os usuários podem criar cenas 3D fazendo upload de arquivos gltf e visualizar o efeito de renderização em tempo real.

E adicionou componentes interativos depositados no projeto para gerar rapidamente projetos de cena 3D.

Fonte de referência:

  1. Fale sobre compactação de arquivo glTF https://jelly.jd.com/article/61057292df18aa019e8a2967

Autor: JD Retail Hu Junwen

Fonte: JD Cloud Developer Community

{{o.name}}
{{m.name}}

Acho que você gosta

Origin my.oschina.net/u/4090830/blog/9777177
Recomendado
Clasificación