“`html
Guia prático
WebGL + Three.js: introdução ao 3D na Web
Se você quer renderizar cenas 3D no navegador sem mergulhar em todo o boilerplate de WebGL,
Three.js é o caminho mais rápido. Aqui eu explico os conceitos fundamentais e como montar
uma primeira cena com segurança, desempenho e uma base sólida para evoluir.
1) WebGL e o “pipeline” do 3D: o que acontece por trás
- Geometria: vértices, arestas e faces (ex.: malhas com triângulos).
- Transformações: posição/rotação/escala via matrizes (Model → View → Projection).
- Câmera e projeção: transformam o “mundo” em coordenadas de tela (perspectiva ou ortográfica).
- Shaders e materiais: determinam cor, luz, textura e como cada fragmento é renderizado.
- Render loop: a cada frame, a cena é atualizada e redesenhada (ou não, dependendo do caso).
Three.js organiza esse pipeline pra você: ele monta cena, câmeras, materiais e abstrai a configuração de WebGL.
Você ainda precisa entender conceitos como câmera, luz e render loop.
2) Três objetos que você sempre vai usar: Scene, Camera e Renderer
- Scene: “container” dos objetos 3D. Você adiciona malhas, luzes, helpers e grupos aqui.
- Camera: define o ponto de vista. Dois tipos comuns:
- PerspectiveCamera (boa para UI 3D e cenas realistas).
- OrthographicCamera (útil para cenas “flat”, mapas e efeitos 2.5D).
- Renderer: desenha a cena no canvas. Ele também lida com:
- pixel ratio (resolução real vs CSS)
- tamanho do viewport
- cor do fundo e configuração de renderização
- atualização quando algo muda
Pense assim: Scene é o “mundo”, Camera é o “olho” e Renderer é a “tela”.
Se a cena não aparece, normalmente o problema está em câmera, luz, escala ou dimensão do canvas.
3) Geometria, Material e Luz: o trio que define como o 3D “fica”
- Geometria: define a forma. Exemplos:
BoxGeometry,SphereGeometry,PlaneGeometry- ou geometrias vindas de assets (GLTF/GLB)
- Material: define aparência. Para começar:
MeshStandardMaterial(responde bem a luz; PBR)MeshBasicMaterial(não precisa de luz; “chato” mas útil para debug)
- Luz: sem luz, materiais PBR podem parecer escuros.
AmbientLightdá base (sem direção)DirectionalLightsimula luz “de longe” (sol)PointLightemite de um ponto
Para debug visual, eu costumo começar com MeshBasicMaterial (garantir que a malha está no lugar).
Depois troco para MeshStandardMaterial e adiciono luz até ficar consistente.
4) Loop de renderização e responsividade: sem gargalos
- Resize: atualize câmera e renderer quando o viewport muda.
- para perspectiva, recalcule
aspect - para o renderer, chame
setSizee ajustesetPixelRatio
- para perspectiva, recalcule
- Animation: use um loop apenas quando há mudanças.
- movimento/rotacionar: loop necessário
- cenas estáticas: renderize uma vez e pare
- Pixel ratio: usar
devicePixelRatiointeiro pode custar caro em telas high-DPI.
Normalmente eu usoMath.min(2, devicePixelRatio)para equilíbrio.
Three.js (ESM)
<!-- index.html -->
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Three.js - Primeira cena</title>
<style>
html, body { margin: 0; height: 100%; background: #0b1220; }
canvas { display: block; width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script type="module">
import * as THREE from "https://unpkg.com/three@0.160.0/build/three.module.js";
const canvas = document.getElementById("c");
// 1) Scene (mundo)
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0b1220);
// 2) Camera (olho)
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(2.5, 1.5, 4);
// 3) Renderer (tela)
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true
});
renderer.setPixelRatio(Math.min(2, window.devicePixelRatio));
renderer.setSize(window.innerWidth, window.innerHeight);
// 4) Luz (para materiais PBR)
const ambient = new THREE.AmbientLight(0xffffff, 0.55);
scene.add(ambient);
const dir = new THREE.DirectionalLight(0xffffff, 1.2);
dir.position.set(3, 5, 2);
scene.add(dir);
// 5) Objeto (geometria + material)
const geometry = new THREE.TorusKnotGeometry(0.65, 0.22, 240, 24);
const material = new THREE.MeshStandardMaterial({
color: 0x7c5cff,
metalness: 0.4,
roughness: 0.35
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// 6) Resize
window.addEventListener("resize", () => {
const w = window.innerWidth;
const h = window.innerHeight;
camera.aspect = w / h;
camera.updateProjectionMatrix();
renderer.setPixelRatio(Math.min(2, window.devicePixelRatio));
renderer.setSize(w, h);
});
// 7) Loop
const clock = new THREE.Clock();
function animate() {
const t = clock.getElapsedTime();
// animação simples: rotação suave
mesh.rotation.y = t * 0.8;
mesh.rotation.x = t * 0.3;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
Se quiser testar rapidamente, copie o HTML acima e abra no navegador. Quando tudo aparecer,
aí sim vale evoluir para assets (GLTF/GLB), controles e materiais mais avançados.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!