Communitygithub.com

zipang/Three.js e Pipeline Web glTF

Otimize assets 3D (.glb e .gltf) e integre-os em animações web interativas com Three.js, React Three Fiber, GSAP e gltf-transform. Use para compressão (Draco, Meshopt, KTX2), configuração de pivô e animação, e renderização web.

O que é Three.js e Pipeline Web glTF?

Este skill detalha o pipeline completo para transformar modelos 3D do Blender ou vcad em arquivos .glb otimizados para a web, garantindo carregamento rápido e animação suave no Three.js. Ele abrange desde a exportação correta com pivôs e transformações aplicadas, até a compressão usando ferramentas como `@gltf-transform/cli` com suporte a Draco, Meshopt e KTX2. O skill fornece código prático para carregar modelos com suporte a decodificadores, organizar animações procedurais ou baseadas em clips, e configurar iluminação PBR para peças metálicas. É útil para desenvolvedores que trabalham com Three.js, React Three Fiber ou qualquer stack que consuma glTF, oferecendo regras de performance, exemplo de loader robusto e dicas de otimização de geometria e texturas.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/zipang/bender-agent/tree/HEAD/.agents/skills/threejs-web

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que Three.js e Pipeline Web glTF faz?

Este skill cobre as etapas que transformam um modelo do Blender ou vcad em um arquivo .glb pequeno. O arquivo deve carregar rápido e animar facilmente no Three.js.

1. Checklist de exportação para Blender e vcad

Nomes dos nós

  • Nomeie cada parte móvel com um nome claro e estável: Head, Visor, Eye_L, Eye_R, Torso_Door, Wheel_FL, Wheel_FR, Steering_Wheel.
  • O Three.js então encontra a parte com model.getObjectByName("Torso_Door").

Pivôs

  • Coloque a origem raiz no centro da base do modelo. No Three.js, o modelo então fica no chão em Y = 0.
  • Coloque cada pivô de parte articulada em seu eixo de rotação. Exemplos: dobradiça da porta, centro da roda, base do pescoço, base da antena.

Transformações

  • Aplique todas as transformações antes da exportação.
  • A escala deve ser 1, 1, 1. A rotação de repouso deve ser 0, 0, 0.
  • Esta regra evita deriva e cisalhamento durante a animação procedural.

Orçamento de geometria

  • Junte as malhas estáticas que compartilham um material. Este passo reduz as chamadas de draw.
  • Mantenha uma malha separada apenas se um script a animar sozinha. Use um SkinnedMesh com um armature para deformação suave.
  • Almeje alguns milhares de triângulos por asset principal. Almeje abaixo de 1.000 triângulos para objetos de fundo.

2. Otimização via CLI com @gltf-transform/cli

O projeto usa Bun. Execute a ferramenta com bunx. npx também funciona em máquinas que têm Node.js.

# Mostrar malhas, texturas e animações
bunx @gltf-transform/cli inspect model.glb

# Otimização completa para a web: Meshopt mais WebP mais limpeza
bunx @gltf-transform/cli optimize model.glb model-optimized.glb \
  --compress meshopt \
  --texture-compress webp \
  --texture-size 2048

# Alternativa: Compressão de geometria Draco
bunx @gltf-transform/cli draco model.glb model-draco.glb

Meshopt ou Draco

  • Meshopt (EXT_meshopt_compression) decodifica muito rápido. Ele mantém a ordem dos vértices e também comprime keyframes de animação e alvos de morph. Use-o para assets animados.
  • Draco (KHR_draco_mesh_compression) gera o menor arquivo para malhas estáticas densas. Exemplos: carrocerias e digitalizações. O decodificador custa mais tempo na inicialização.

Outros passos úteis

# Remover malhas duplicadas e dados não utilizados
bunx @gltf-transform/cli dedup model.glb model.glb

# Converter texturas para KTX2 (BasisU)
bunx @gltf-transform/cli etc1s model.glb model-ktx2.glb

Verifique o arquivo após cada passo. Confirme o tamanho do arquivo, a contagem de triângulos e o tamanho das texturas.

3. Integração com Three.js

Carregador robusto com Draco e Meshopt

import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');

const gltfLoader = new GLTFLoader();
gltfLoader.setDRACOLoader(dracoLoader);
gltfLoader.setMeshoptDecoder(MeshoptDecoder);

const gltf = await gltfLoader.loadAsync('/models/bender-optimized.glb');
const root = gltf.scene;
scene.add(root);

Dois métodos de animação

  1. Animação procedural com transformações de nó. Use este método para robôs, veículos e outras partes rígidas. Exemplos: rotação de roda, abertura de porta, rastreamento de cabeça, balanço de antena.
const head = root.getObjectByName('Head');
const door = root.getObjectByName('Torso_Door');
const antenna = root.getObjectByName('Antenna');

function animate(time) {
  if (antenna) {
    antenna.rotation.z = Math.sin(time * 0.005) * 0.15;
  }
  if (head) {
    head.rotation.y = THREE.MathUtils.lerp(head.rotation.y, targetYaw, 0.1);
  }
}
  1. Clipes processados com THREE.AnimationMixer. Use este método para ciclos complexos vindos do Blender: caminhada, dança e morphs faciais.
const mixer = new THREE.AnimationMixer(root);
const idleClip = THREE.AnimationClip.findByName(gltf.animations, 'Idle');
if (idleClip) {
  mixer.clipAction(idleClip).play();
}

// No loop de renderização:
// mixer.update(clock.getDelta());

Iluminação PBR para peças metálicas

Um material metálico (metalness > 0.8) fica preto no Three.js quando nada o rodeia. Defina um mapa de ambiente:

import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

const pmremGenerator = new THREE.PMREMGenerator(renderer);
scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;

Use scene.environmentIntensity para ajustar a força do reflexo. Mantenha o mapeamento de tom em THREE.ACESFilmicToneMapping para assets metálicos.

Regras de performance

  • Um material por grupo de malha. Cada material custa uma chamada de draw.
  • Reutilize texturas. Empacote texturas pequenas em um atlas.
  • Defina renderer.outputColorSpace = THREE.SRGBColorSpace. O carregador glTF define os espaços de cor das texturas.
  • Use THREE.InstancedMesh quando um asset aparece muitas vezes.
  • Libere um modelo ao removê-lo: percorra a cena, depois chame geometry.dispose() e material.dispose().

Habilidades Relacionadas