Primeiros passos com o Three.js

Introdução

Usei o Three.js em alguns dos meus experimentos, e ele é muito útil para eliminar as dores de cabeça relacionadas ao 3D no navegador. Com ele, você pode criar câmeras, objetos, luzes, materiais e muito mais. Além disso, é possível escolher o renderizador, o que significa que você pode decidir se quer que sua cena seja desenhada usando a tela, WebGL ou SVG do HTML 5. E, por ser de código aberto, você poderia até se envolver no projeto. Mas agora vou me concentrar no que aprendi ao usá-lo como motor, e falar sobre alguns dos princípios básicos.

Apesar de todos os recursos incríveis do Three.js, em alguns casos, pode ser difícil. Normalmente, você precisará passar um bom tempo com os exemplos, engenharia reversa e (no meu caso, certamente) buscando funcionalidades específicas e, ocasionalmente, fazendo perguntas pelo GitHub. Aliás, se tiver dúvidas, acho que Sr. doob e AlteredQualia são extremamente úteis.

1. Noções básicas

Presumimos que você tenha pelo menos um conhecimento básico de 3D e proficiência razoável em JavaScript. Se não fizer isso, vale a pena aprender um pouco antes de tentar fazer isso, porque pode ficar um pouco confuso.

No nosso mundo 3D, teremos alguns dos itens a seguir, que guiarei você pelo processo de criação:

  1. Uma cena
  2. Um renderizador
  3. Uma câmera
  4. Um ou dois objetos (com materiais)

Você pode, claro, fazer algumas coisas legais, e espero que você faça isso e comece a experimentar o 3D em seu navegador.

2. Suporte

Apenas uma observação rápida sobre o suporte nos navegadores. O navegador Chrome do Google é, na minha experiência, o melhor navegador para trabalhar em termos de renderizadores compatíveis e a velocidade do mecanismo JavaScript subjacente. O Chrome oferece suporte a Canvas, WebGL e SVG, e é incrivelmente rápido. O Firefox vem logo atrás com o advento da versão 4. O mecanismo JavaScript dele parece ser um pouco mais lento do que o do Chrome, mas a compatibilidade com as tecnologias de renderização é excelente. O Opera e o Safari estão em processo de adição da compatibilidade com WebGL, mas as versões atuais são compatíveis apenas com canvas. O Internet Explorer (versão 9+) só é compatível com renderização de tela, e não sei nada da Microsoft que planeja adicionar recursos WebGL.

3. Prepare o terreno

Vamos supor que você tenha escolhido um navegador que ofereça suporte a todas as tecnologias de renderização e queira renderizar com canvas ou WebGL, já que essas são as opções mais padrão. O Canvas é mais amplamente compatível que o WebGL, mas é importante notar que o WebGL é executado na GPU da placa de vídeo, o que significa que a CPU pode se concentrar em outras tarefas que não sejam de renderização, como qualquer física ou interação do usuário que você esteja tentando fazer.

Independentemente do renderizador escolhido, lembre-se de que o JavaScript precisará ser otimizado para a performance. 3D não é uma tarefa leve para um navegador, e o incrível é que isso é possível. Por isso, tenha cuidado para entender onde estão os gargalos no seu código e remova-os, se possível.

Tendo dito isso, e presumindo que você fez o download e incluiu o three.js no arquivo HTML, o que fazer para configurar uma cena? Assim:

// set the scene size
var WIDTH = 400,
HEIGHT = 300;

// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
                VIEW_ANGLE,
                ASPECT,
                NEAR,
                FAR );

var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;

// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

Nada complicado demais, na verdade!

4. Como fazer uma malha

Temos uma cena, uma câmera e um renderizador (eu optei por um WebGL no meu exemplo de código), mas não temos nada para desenhar. Na verdade, o Three.js é compatível com o carregamento de alguns tipos de arquivo padrão diferentes, o que é ótimo para gerar modelos do Blender, Maya, Cinema4D ou qualquer outra coisa. Para simplificar (afinal, trata-se de começar!) Falarei sobre primitivos. Primitivas são malhas geométricas, relativamente básicas, como esferas, planos, cubos e cilindros. A Three.js permite criar facilmente estes tipos de primitivos:

// set up the sphere vars
var radius = 50, segments = 16, rings = 16;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),

sphereMaterial);

// add the sphere to the scene
scene.add(sphere);

Tudo certo, mas e o material para a esfera? No código, usamos uma variável sphereMaterial, mas ainda não a definimos. Primeiro, precisamos falar sobre os materiais com um pouco mais de detalhes.

5. materiais

Sem dúvida, essa é uma das partes mais úteis da Three.js. Ela fornece vários materiais comuns e muito úteis para aplicar às malhas:

  1. "Básico" significa apenas que a renderização está "apagada".
  2. Lambert
  3. Phong

Há mais, mas, novamente, para simplificar, vou deixar que você as descubra por conta própria. No caso do WebGL, em especial, esses materiais podem economizar vidas. Por quê? Porque, no WebGL, você precisa programar sombreadores para tudo que está sendo renderizado. Os sombreadores são um assunto enorme por si só, mas, em resumo, são escritos em GLSL (OpenGL Shader Language), que informa à GPU como algo precisa ser. Isso significa que você precisa imitar a matemática da iluminação, reflexão e assim por diante. Isso pode ficar muito complicado muito rapidamente. Graças ao Three.js, não é necessário fazer isso se não quiser, porque ele abstrai isso para você. No entanto, se você quiser programar sombreadores, também poderá fazer isso com um MeshShaderMaterial, o que torna a configuração flexível.

No entanto, por enquanto, vamos aplicar um material lambert à esfera:

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});

Também vale a pena ressaltar que há outras propriedades que podem ser especificadas ao criar um material além da cor, como suavização ou mapas ambientais. Confira a página da Wiki para ver as várias propriedades que podem ser definidas nos materiais e, na verdade, qualquer objeto que o mecanismo fornecer. Além disso, o site threejs.org (em inglês) foi lançado recentemente, o que oferece uma visualização mais atrativa da API.

6. Luzes!

Se você renderizar a cena agora, verá um círculo vermelho. Embora tenhamos um material Lambert aplicado, não há luz na cena. Portanto, por padrão, a Three.js será revertida para uma luz ambiente completa, que é o mesmo que uma coloração plana. Vamos corrigir isso com um ponto de vista simples:

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);

7. Renderizar

Agora, de fato, temos tudo configurado para renderizar. Mas, na verdade, precisamos fazer exatamente isso:

// draw!
renderer.render(scene, camera);

No entanto, você provavelmente vai querer renderizar mais de uma vez, então, se fizer um loop, use o requestAnimationFrame. Essa é a maneira mais inteligente de lidar com animações no navegador. Ele ainda não é totalmente compatível. Por isso, recomendo que você confira o paliativo de Paul irlandês (link em inglês).

8. Propriedades de objetos comuns

Se você analisar o código do Three.js, verá que muitos objetos "herdam" do Object3D. Este é um objeto base que contém algumas propriedades muito úteis, como as informações position, rotation e scale. Em particular, o Sphere é uma malha herdada de Object3D, à qual ele adiciona as próprias propriedades: geometria e materiais. Por que os mencionamos? É improvável que você queira apenas ter uma esfera na tela que não faça nada. Vale a pena investigar essas propriedades, porque permitem que você manipule os detalhes subjacentes das malhas e dos materiais em tempo real.

// sphere geometry
sphere.geometry

// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array

// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same

9. Pequenos segredos sujos

Só queria mostrar rapidamente um pegadinha rápido para o Three.js, que é que, se você modificar, por exemplo, os vértices de uma malha, vai perceber no loop de renderização que nada muda. Por quê? Porque a Three.js (até onde posso notar) armazena os dados de uma malha em cache como uma otimização. O que você precisa fazer é sinalizar para o Three.js que algo mudou para que ele possa recalcular o que for necessário. Para isso, siga estas etapas:

// changes to the vertices
sphere.geometry.__dirtyVertices = true;

// changes to the normals
sphere.geometry.__dirtyNormals = true;

Novamente, há mais, mas os dois que encontrei são os mais úteis. Obviamente, você precisa sinalizar apenas as coisas que foram alteradas para evitar cálculos desnecessários.

Conclusão

Espero que esta breve introdução ao Three.js tenha sido útil. Não há nada como realmente colocar as mãos na massa e tentar algo, e não posso recomendar isso o suficiente. O 3D executado nativamente no navegador é muito divertido, e usar um mecanismo como o Three.js elimina muitas dores de cabeça e permite que você faça coisas muito legais. Para ajudar você, reunimos o código-fonte neste artigo de laboratório para que você possa usá-lo como referência. Se você gostou desta postagem, conte comigo pelo Twitter. É sempre bom dar um oi!