3D na web com Three.js: um recanto acolhedor num só ficheiro HTML
Coloque modelos 3D reais numa página web com algumas linhas de JavaScript. Um tutorial de Three.js para principiantes, com código completo.
Nesta página
Um modelo 3D a rodar numa landing page capta a atenção de uma forma que uma imagem plana não consegue. A boa notícia: o GLB é o formato nativo do mundo 3D na web, pelo que mostrar os nossos modelos num browser exige surpreendentemente pouco código.
Neste tutorial, vamos construir uma pequena cena interativa com Three.js: um recanto de leitura com a Poltrona de madeira, o Candeeiro de mesa em cerâmica, a Mesa de cabeceira de carvalho e a Figueira-lira em cesto.
Do que precisa
Os ficheiros GLB dos modelos, colocados numa pasta models junto ao seu ficheiro HTML.
Um servidor web local. Os browsers bloqueiam o carregamento de ficheiros diretamente do disco, por isso execute algo como npx serve ou a extensão Live Server no VS Code.
Nenhuma ferramenta de build: vamos carregar o Three.js a partir de uma CDN, usando um import map.
O código completo
Crie o ficheiro index.html com este conteúdo:
<!doctype html>
<html>
<head>
<style>body { margin: 0; background: #f3efe8; }</style>
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
} }
</script>
</head>
<body>
<script type="module">
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(devicePixelRatio);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color('#f3efe8');
const pmrem = new THREE.PMREMGenerator(renderer);
scene.environment = pmrem.fromScene(new RoomEnvironment()).texture;
const camera = new THREE.PerspectiveCamera(40, innerWidth / innerHeight, 0.1, 100);
camera.position.set(2.5, 1.6, 3);
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0.6, 0);
controls.enableDamping = true;
const loader = new GLTFLoader();
const place = (file, x, z, rotY = 0) =>
loader.load('models/' + file, (gltf) => {
gltf.scene.position.set(x, 0, z);
gltf.scene.rotation.y = rotY;
scene.add(gltf.scene);
});
place('wooden-armchair.glb', 0, 0, 0.4);
place('oak-bedside-table.glb', 0.9, -0.2);
place('ceramic-table-lamp.glb', 0.9, -0.2);
place('fiddle-leaf-fig.glb', -0.9, -0.4);
renderer.setAnimationLoop(() => { controls.update(); renderer.render(scene, camera); });
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
</script>
</body>
</html>
Mude o nome dos ficheiros transferidos para corresponderem aos nomes no código, ou altere os nomes no código. Inicie o seu servidor local e abra a página. Pode rodar a cena com o rato e fazer zoom com a roda de deslocamento.
O que faz o código
Renderizador e cena. Criamos um renderizador WebGL que ocupa toda a janela e uma cena com uma cor de fundo quente.
Iluminação ambiente. O RoomEnvironment gera um ambiente de luz suave, semelhante a um estúdio. Os materiais PBR precisam de um ambiente para refletir, e esta única linha dá aos nossos modelos reflexos credíveis sem carregar um HDRI.
Câmara e controlos. Uma câmara de perspetiva aponta para o recanto, e os OrbitControls permitem aos visitantes rodar e fazer zoom. O amortecimento (damping) torna o movimento suave.
Carregar os modelos. O GLTFLoader lê cada GLB, incluindo os respetivos materiais e texturas, e devolve um objeto de cena que podemos posicionar e rodar. Os nossos modelos usam a escala real em metros e têm a origem na base, pelo que colocá-los no chão é apenas y = 0.
Dicas de posicionamento
Empilhar objetos. O candeeiro tem de ficar em cima da mesa. Eleve-o à altura da mesa: substitua 0 pela altura da mesa na linha de posição, ou calcule-a com new THREE.Box3().setFromObject(table).
Rotação. rotation.y é em radianos: Math.PI / 2 roda um modelo 90 graus.
Escala. Todos os nossos modelos partilham a mesma escala, pelo que não deverá precisar de redimensionar nada.
Preparar para produção
Sombras. Acrescente uma DirectionalLight com castShadow = true e defina castShadow nas malhas dos modelos para que os objetos fiquem bem assentes.
Ecrã de carregamento. Use o THREE.LoadingManager para mostrar o progresso enquanto os modelos são transferidos.
Compressão. Em cenas grandes, ferramentas como o gltf-transform conseguem comprimir ainda mais a geometria e as texturas. Converter ficheiros para o seu próprio projeto é permitido pela nossa licença.
Opção mais simples. Se só precisa de um único modelo com rotação e zoom, o componente web model-viewer da Google mostra um GLB com uma única tag HTML.
A sua vez
Troque o recanto de leitura por uma cozinha, um quarto de brincar ou uma pequena aldeia. Todos os modelos da loja são GLB que funcionam exatamente com este código.
Modelos deste artigo
Todos os modelos →Continue a ler
Artigos selecionados do mesmo grupo temático.
Número de polígonos: de quantos triângulos precisa mesmo?
5000 triângulos ou 60 000? Um guia prático para interpretar o número de polígonos e escolher modelos adequados ao orçamento do seu projeto.
LerUsar modelos da 3dpolyx no Unity e no Unreal Engine
O GLB não serve só para o Blender e para a web. Veja como trazer os nossos modelos para os dois maiores motores de jogo.
LerImportar um GLB para o Blender em dois minutos
Da transferência ao primeiro render: como trazer um modelo GLB para o Blender, verificar se está tudo no sítio e começar a construir a sua cena.
Ler