Conteúdo deste artigo
Nota do Editor: A primeira Conferência Three.js chegará a Paris em setembro, e estamos entrando no espírito dela! Nas próximas semanas, traremos a você muitas joias do Three.js de pessoas maravilhosas da comunidade, compartilhando generosamente seus experimentos, técnicas e ideias criativas conosco. Seguindo o encantador xilofone interativo de Sujen Phea, Frank Reitberger agora compartilha “Garden Anomaly”, um divertido experimento WebGPU e TSL que combina física, deformações de vidro e som gerado processualmente. Aproveitar!
🎟️Indo para Paris? Como parte de nossa parceria com a primeira Conferência Three.js, os leitores do Codrops podem usar o código CODROPS para obter 15% de desconto em ingressos . Se você estava esperando por um sinal, pode ser este. Obtenha seu ingresso →
Desde a introdução do WebGPURenderer e TSL (Three Shading Language), tenho me esforçado para adotá-los o mais rápido possível. Isso me colocou na feliz posição de poder construir e publicar meus pequenos experimentos usando a moderna tecnologia WebGPU.
A ideia por trás disso
Muitas vezes me perguntam por onde começar com TSL ou WebGPU. Para ser honesto, não posso oferecer muitos conselhos sobre isso. Dei uma olhada em alguns exemplos de Three.js, e há muitos deles aqui: https://threejs.org/examples/ . Também li as informações disponíveis no TSL: https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language . Fora isso, comecei a experimentar.
Geralmente já tenho uma ideia de onde quero que a jornada me leve. O objetivo é sempre alcançar um resultado visualmente atraente, seja tecnicamente mais desafiador ou não. A maioria dos desafios só se revela durante a implementação. Geralmente é o caso de pensar: “Bem, se este funciona, então aquele deve funcionar também…”
Esta pequena anomalia no canteiro de flores na verdade surgiu de um experimento que fiz um ou dois meses atrás. Por causa disso, a base para a física, o som processual e muito mais já estava lá.

Renderização e materiais
A cena inteira é renderizada com WebGPURenderer usando materiais de nó TSL por toda parte. Aqui está uma rápida visão geral da configuração de renderização:
- Shell transmissivo (
MeshPhysicalNodeMaterial) com transmissão, espessura, IOR, iridescência (0,90, IOR 1,55), verniz e cor e distância de atenuação do azul. - TSL personalizado
positionNodepara as protuberâncias de impacto, usando deslocamento de vértice conduzido por um slot 8uniformArrayde vetores de direção e amplitude. - TSL personalizado
normalNodecom perturbação normal analítica, combinado com um mapa normal de espaço tangente construído a partir de um quadro tangente de esfera personalizado. - Personalizado
roughnessNodeusando um mapa de rugosidade de gelo robusto incorporado que é modulado por pixel. - Personalizado
emissiveNodeconduzido por uma faixa de scanline gerada em tela com rolagem contínua por meio de um uniforme de deslocamento UV. - Bolhas instanciadas (
InstancedMesh) , mantidas opacas porque a passagem de transmissão atualmente ignora a geometria transparente.
Física
No centro da demonstração está uma simulação de Position Based Dynamics (PBD) rodando inteiramente na CPU. Alguns sistemas orientados a eventos são colocados em camadas para orientar as interações, o som e o comportamento geral.
Impulsos de arremesso: A interação do ponteiro aplica impulsos aleatórios com uma tendência ascendente, permitindo que você mexa a simulação manualmente.
Prever: A gravidade e a resistência do ar são integradas nas velocidades usando Euler semi-implícito, então as posições são avançadas.
Restrições do projeto: Três iterações resolvem colisões esfera a esfera, com massa ponderada por r³ para que bolhas pequenas naturalmente cedam a bolhas maiores. As bolhas também são projetadas de volta para dentro da esfera de vidro, garantindo que toquem a superfície interna em vez de passarem por ela.
Derive speed: A velocidade é recalculada a partir da mudança de posição, v = (x − x_prev) / dt, em vez de manter a velocidade integrada. Esta é a característica definidora do PBD e permite que a pilha assente naturalmente em vez de se agitar constantemente.
Amortecimento de contato: Bolhas em contato recebem amortecimento de velocidade exponencial, atuando tanto como assentamento da pilha quanto como fricção do vidro. Na parede, apenas a velocidade normal de saída é removida, permitindo que as bolhas deslizem naturalmente ao longo do vidro.
Detecção de impacto: Um novo contato com a parede acima de um limite de velocidade radial cria uma protuberância de vidro temporária e aciona um som. Bolhas em repouso não podem ativar este efeito.
Rescatter de colisão: Colisões mais rápidas de bolha a bolha acionam um redirecionamento de velocidade aleatório usando uma fórmula de “repotenciação”, com um curto resfriamento por bolha para que as reações em cadeia energéticas desapareçam gradualmente.
Explosão de descanso: Um temporizador de descanso por bolha aplica um impulso ascendente aleatório após 200 ms abaixo do limite de velocidade, mantendo todo o sistema fervendo suavemente em vez de se estabilizar completamente.
Sistema de som
O sistema de som é construído inteiramente com a API de áudio da Web. Não há samples ou arquivos de áudio envolvidos, tudo é gerado processualmente. Aqui está uma rápida visão geral:
Gatilho: Um tom é tocado apenas quando uma bolha atinge o vidro com força suficiente para criar uma protuberância. As colisões bola a bola permanecem silenciosas, de modo que o som está sempre diretamente acoplado à deformação visível do vidro.
Tom: As notas são escolhidas em uma escala pentatônica de dó maior de duas oitavas (C4, D4, E4, G4, A4, C5, D5, E5, G5, A5). O raio da bolha determina o tom, com bolhas maiores produzindo notas mais graves e bolhas menores produzindo notas mais altas. Como a escala é pentatônica, batidas sobrepostas criam naturalmente acordes com sons agradáveis.
Voz: Cada hit é gerado por uma pilha de quatro osciladores senoidais em proporções consonantais. Cada parcial tem seu próprio envelope de ganho com um ataque exponencial curto e tempos de decaimento escalonados, permitindo que o som floresça intensamente antes de desaparecer em uma cauda senoidal pura. A intensidade aumenta com a velocidade do impacto, enquanto um StereoPannerNode posiciona cada golpe no campo estéreo com base na posição mundial da bolha.
Bus: Todas as vozes são mixadas em um ganho master antes de serem divididas em um caminho seco e um caminho flanger. O flanger usa um pequeno atraso modulado por um oscilador contínuo de baixa frequência com feedback, dando a cada golpe um caráter ligeiramente diferente. Ambos os caminhos são então recombinados e passados por um DynamicsCompressor, mantendo rajadas densas sob controle sem cortes.
Limpeza: O AudioContext é criado e retomado na primeira interação do ponteiro para cumprir as políticas de reprodução automática do navegador. Um limitador de taxa simples impõe um intervalo mínimo entre as vozes com um limite de oito vozes, enquanto as vozes finalizadas se limpam automaticamente. Os controles de volume e liga/desliga estão disponíveis no painel de depuração, com o volume padrão mantido deliberadamente baixo para criar uma atmosfera ambiente.
Tudo isso é complementado por um lindo cenário de jardim, gerado com Skybox AI: https://www.blockadelabs.com/ .
Aproveite!
