Efeito de paralaxe no navegador com TensorFlow.js + WASM + Three.js

Lembra como a Apple introduziu o iOS7 com efeito de paralaxe? Agora você pode fazer isso diretamente no seu navegador.

webcam em paralaxe threejs



Todos os laptops e telefones agora têm uma câmera, para que você possa usar modelos com dezenas de baixas para analisar a posição da cabeça e dos olhos. Além disso, um novo artigo sobre o SIGGRAPH 2020 mostra como tornar os conjuntos de dados com fotogrametria convenientes para o efeito de paralaxe.



Provavelmente todo mundo sabe que existe uma biblioteca Tensorflow para redes neurais, que funciona nas linguagens Python e Javascript. O processo de convolução nas redes neurais é uma computação bastante pesada que é bem paralelizada e existem versões não apenas para a CPU, mas também no CUDA para Python e WebGL / WebGPU para Javascript. É engraçado, mas se você não possui NVidia, a versão oficial do Tensorflow na linguagem Javascript funcionará mais rápido no PC, pois não há versão oficial com suporte ao OpenGL. Felizmente para todos, o TF 2.0 possui uma arquitetura modular que permite pensar apenas na essência, e não na linguagem em que é realizada. Existem também conversores 1.0 -> 2.0.







No momento, existem dois modelos oficiais de reconhecimento facial: facemesh e blazeface. O primeiro é mais adequado para expressões faciais e máscaras, o segundo é mais rápido e simplesmente determina os pontos quadrados e característicos, como olhos, ouvidos, boca. Então eu peguei a versão leve - blazeface. Por que informações desnecessárias? Em geral, pode ser possível reduzir ainda mais o modelo existente, pois além da posição dos olhos, não preciso de mais nada.



No momento, existem 5 back-ends no navegador: cpu, wasm, webgl, wasm-simd, webgpu. A primeira CPU é muito lenta e não deve ser tomada de forma alguma agora, as duas últimas são muito inovadoras e estão na fase de propostas e funcionam sob sinalizadores, para que os clientes finais não tenham suporte. Portanto, eu escolhi entre dois: WebGL e WASM.







A partir dos benchmarks existentes, é possível ver que, para modelos pequenos, o WASM às vezes é mais rápido que o WebGL. Além disso, o paralaxe pode ser usado com cenas 3D e, executando o back-end do WASM, percebi que o WASM funciona muito melhor, pois as placas de vídeo de laptop discretas não exportam simultaneamente redes neurais e cenas 3D. Para fazer isso, fiz uma cena simples com 75 capítulos em .glb. O link é clicável e existe o WASM.







Se você clicou no link, provavelmente notou que o navegador solicitou permissão para acessar a câmera de vídeo. A questão é: o que acontecerá se o usuário clicar em não? Seria sensato não carregar nada neste caso e fallback para controlar o mouse / giroscópio. Não encontrei a versão ESM do tfjs-core e do tfjs-converter, portanto, em vez de uma importação dinâmica, decidi por uma construção bastante assustadora com a biblioteca fetchInject, onde a ordem na qual os módulos são carregados é importante.



construção de fluência
, (Promise.All), , , .

fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow-models/blazeface@0.0.5/dist/blazeface.min.js'
], fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter@2.0.1/dist/tf-converter.min.js',
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@2.0.1/dist/tfjs-backend-wasm.wasm'
], fetchInject([
  'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core@2.0.1/dist/tf-core.min.js'
]))).then(() => {

  tf.wasm.setWasmPath('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@2.0.1/dist/tf-backend-wasm.min.js');

  //some other code

}




Para encontrar a posição do olhar, tomo a média entre os dois olhos. E é fácil entender que a distância da cabeça será proporcional à distância entre os olhos no vídeo, devido à semelhança dos lados do triângulo. Os dados de posição ocular que vêm do modelo são bastante barulhentos, portanto, antes de fazer os cálculos, eu os suavizei usando a EMA (Média Móvel Exponencial):



pos = (1 - smooth) * pos + smooth * nextPos;


Ou escrevendo de outra maneira:



pos *= 1 - smooth;
pos += nextPos * smooth;


Assim, obtemos as coordenadas x, y, z, em um determinado sistema de coordenadas esféricas centralizado na câmera. Além disso, x e y são limitados pelo ângulo de visão da câmera e z é a distância aproximada da cabeça à mesma. Em pequenos ângulos de rotaçãosEun(α)αentão x e y podem ser tomados como ângulos.



pushUpdate({
  x: (eyes[0] + eyes[2]) / video.width - 1,
  y: 1 - (eyes[1] + eyes[3]) / video.width,
  z: defautDist / dist
});


Fotogrametria



Data bastante engraçada da publicação SIGGRAPH 2020 Vídeo de campo de luz imersivo com uma representação de malha em camadas. Eles fizeram fotos especificamente para que você pudesse mover a câmera em um determinado intervalo, o que é ideal para a paralaxe. Exemplo de paralaxe.







Uma cena 3D é criada em camadas e uma textura é aplicada a cada camada. Não menos engraçado é o dispositivo com o qual eles criaram a fotogrametria. Eles compraram 47 câmeras de ação Yi 4K baratas por 10k rublos cada e as colocaram em um hemisfério na forma de um icosaedro no qual uma grade triangular é triplicada. Depois disso, todos foram colocados em um tripé e as câmeras foram sincronizadas para fotografar.







Ligações






All Articles