WebGL - Objetos 3D no Navegador
- #HTML
- #JavaScript
Resultado:
https://didibr.github.io/exemplo3d/
WebGL
Neste artigo vou apresentar como utilizar o WebGL no navegador para, criar
um objeto 3D animado diretamente na pagina do navegador.
Oque é WebGL
No computador quem trabalha com os gráficos é a placa de vídeo, (GPU). o WebGL é um conjunto de APIs, que praticamente já é nativa dos motores Javascript mais modernos para navegadores, existem as que utilizam software para simular a GPU ou as que acessam diretamente a GPU.
Isso quer dizer, a mesma capacidade gráfica que o seu joguinho predileto tem para desenhar os gráficos na tela, pode ser conseguida com a utilização do WebGL em rodando em uma pagina.
WebGL ( Javascript )
Como falei o próprio WebGL em si é um conjunto de APIs do navegador.
Nativamente a criação de uma área de Renderização é feita assim:
const canvas = document.querySelector("#glcanvas");
// Initialize the GL context
const gl = canvas.getContext("webgl");
E dentro deste canvas que é um elemento HTML será atualizado todo o gráfico que é exibido ao usuário na pagina.
APIs ( Javascript )
Assim como existem vários frameworks dentro da linguagem javascript para facilitar o manuseio e implementações. Existem também os específicos para trabalhar com WebGL, como por exemplo o Babylon, PlayCanvas, e o tree.js que irei utilizar a partir de agora.
Inicio dos Códigos
Pagina HML5 ( html - javascript )
Primeiro vamos criar uma pagina html simples, com o código abaixo:
Veja que definimos a pagina como HTML5 com o !DOCTYPE
Definimos para que a visualização da tela responsiva seja de 1 para 1
Incluímos um elemento DIV que ira receber o canvas com WebGL
Adicionamos o framework three.js diretamente do unpkg CDN
Adicionamos o modulo javascript meumodulo.js ( ainda iremos escrever ele )
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="viewport" content="width=device-width">
<title>3D Exemplo</title>
</head>
<body>
<div id="main" style="width:300px;height:300px">
</div>
<script type="importmap">
{"imports": {"three": "https://unpkg.com/three@0.150.0/build/three.module.js"}}
</script>
<script type="module" src="/meumodulo.js"></script>
</body>
</html>
meumodulo.js ( Javascript )
Dentro deste arquivo está o restante da importação do framework three.js referenciada pelo importmap e o código utilizado para criar, renderizar e atualizar o canvas através do WebGL.
Seguem as os códigos e suas funções:
Termina de Incluir o three.js e suas funções e adiciona o OrbitControls que manipula a câmera, e cria o textureloader que serve para carregar imagens.
E define as variáveis globais.
import * as THREE from 'three';
import { OrbitControls } from "https://unpkg.com/three@0.150.0/examples/jsm/controls/OrbitControls.js";
const textureloader = new THREE.TextureLoader();
var camera, scene, renderer, orbitControls;
var mesh, div;
var light;
Função init
Esta função dentro do modulo ira criar o vinculo entre canvas e WebGL, irá colocar o canvas dentro do elemento DIV na pagina, irá inicializar a câmera e adicionar uma luz ambiente para que o objeto 3d possa ser visto, as descrições estão nas linhas de código.
function init() {
//informa quem é o div que contem o canvas
div = document.querySelector('#main');
//define o aspect ration (largura/altura)
//alterar o ratio pode alterar a qualidade do render
var aspect = div.offsetWidth / div.offsetHeight;
//funcao do framework para criar o webgl
//campo de visao, aspecto, max proximidade, max profundidade
camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
//coloca a camera um pouco distante da posicao zero (0,0,0)
camera.position.set(0, 0, 20);
//cria uma cena (é onde os objetos podem estar)
scene = new THREE.Scene();
//seta configurações de renderização
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0x000000, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(div.offsetWidth, div.offsetHeight);
//adiciona a visualização do render (canvas) no div da pagina
div.appendChild(renderer.domElement);
//cria o controlador de camera orbital (framework)
orbitControls = new OrbitControls(camera, renderer.domElement);
//manda a camera olhar de onde está para o ponto zero
orbitControls.target.set(0, 0, 0);
//adiciona uma luz ambiente
//objetos sem luz não tem cor ou textura visiveis
light = new THREE.AmbientLight(0x404040); // soft white light
//inclui a luz a cena
scene.add(light);
//chama funcao para criar a caixa
createBox();
//chama funcao para pintar o render
animate();
}
Função createBox
esta função ira carregar uma imagem para utilizar como textura, irá criar um objeto mesh 3D e anexa a textura ao objeto antes de inseri-lo na cena.
function createBox() {
//Cria a geometria Box (caixa) largura, altura, segmentos
const geometry = new THREE.BoxGeometry(10, 10, 10);
//utiliza o textureloader para carregar a imagem dentro
//da variavel textura
var textura = textureloader.load(
'https://i.ibb.co/f0Ct6CJ/Brick-Groutless0092-5-download600.jpg');
//cria o material para ser ablicado na geometria
const material = new THREE.MeshBasicMaterial({ map: textura });
//cria o objeto mesh juntando material e geometria
mesh = new THREE.Mesh(geometry, material);
//inclui o objeto na cena
scene.add(mesh);
//todo objeto que não tem definido a posicao é adicionado
//na posição zero (0,0,0)
}
Função animate
Esta função fica em repetição automática a partir da primeira vez que for chamada, atualizando os objetos, suas posições e a cena. e pinta tudo no render.
function animate() { //esta funcao fica se repetindo
//pinta o WebGL no canvas ( renderiza a cena)
renderer.render(scene, camera);
//funcao do navegado para chamar o animate novamente
//quando for possivel no proximo frame
requestAnimationFrame(animate);
//o requestAnimationFrame é uma API nativa do navegador
}
//por fim isso que iniciliza o init
document.addEventListener("DOMContentLoaded", function (e) {
init();
});