Essa é a terceira parte do tutorial onde eu ensino como criar no visualizador básico Web GL. Nós vamos usar o Blender para criar os modelos em 3D. E a codificação Web GL em si será feita com o three.js.
Na primeira parte falamos sobre o os programas necessários e os scripts. Na segunda parte foi tudo o que precisavamos para carregar o modelo via Collada e as configurações para o cenário. Caso necessite rever as postagens anteriores desse tutorial, segue os links abaixo.
Criando a SkyDome
Podemos criar um fundo de cor única com a seguinte linha de código.
renderer.setClearColorHex(0x262626, 1)
Se você quiser mudar a cor pesquise por uma HTML online. O Colorizer.org e o Color Hexa são sites que vão ajudar você a converter cores do RGB para cores Hexadecimais. O trio hexa dessa cor deve ser 262626 por isso certifique-se que você mantenha os dois primeiros dígitos. Porém um fundo de cor única é muito chato não?! Por isso decidi criar uma gradiente usando os recursos do three.js vamos precisar de um fragment shader, um vertex shader e um pouco mais de código. Observe a maior parte do código para gradiente usado foi retirado de exemplos do three.js. Visite o threejs.org se desejar mais informações a respeito.
Vamos começar com o Vertez Shader...
Cole o código do Fragment Shader logo após o Vertex Shader.
<script type="x-shader/x-vertex" id="vertexShader"> varying vec3 vWorldPosition; void main() { vec4 worldPosition = modelMatrix * vec4( position, 1.0 ); vWorldPosition = worldPosition.xyz; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } </script>
A SkyDome devemos criar excluindo todos os calculos de sombreamento exceto as relativas localizações (vertex shader) e de cores simples (fragment shader), sem fontes de luz e outros recursos.
Criando a SkyDome em si
Uma boa inclinação preta para acizentada deve aparecer agora. Se quiser alterar as cores, cole o código hexadecimal no lugar dos atuais em topColor e bottomColor. Cores mais contrastantes deixa o degradê mais exposto.
Script completo
Aqui está o script completo para acompanharmos.
<!doctype html><html lang="en"> <head> <title>Test von Web GL</title> <meta charset="utf-8"> </head> <body style="margin: 0;"> <script src="js/three.min.js"></script> <script src="js/OrbitControls.js"></script> <script src="js/ColladaLoader.js"></script> <script type="x-shader/x-vertex" id="vertexShader"> varying vec3 vWorldPosition; void main() { vec4 worldPosition = modelMatrix * vec4( position, 1.0 ); vWorldPosition = worldPosition.xyz; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } </script> <script type="x-shader/x-fragment" id="fragmentShader"> uniform vec3 topColor; uniform vec3 bottomColor; uniform float offset; uniform float exponent; varying vec3 vWorldPosition; void main() { float h = normalize( vWorldPosition + offset ).y; gl_FragColor = vec4( mix( bottomColor, topColor, max( pow( h, exponent ), 0.0 ) ), 1.0 ); } </script> <script> var scene, camera, renderer; init(); animate(); function init() { scene = new THREE.Scene(); var WIDTH = window.innerWidth, HEIGHT = window.innerHeight; renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setSize(WIDTH, HEIGHT); document.body.appendChild(renderer.domElement); camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 10000); camera.position.set(50,150,100); scene.add(camera); window.addEventListener('resize', function() { var WIDTH = window.innerWidth, HEIGHT = window.innerHeight; renderer.setSize(WIDTH, HEIGHT); camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix(); }); var vertexShader = document.getElementById( 'vertexShader' ).textContent; var fragmentShader = document.getElementById( 'fragmentShader' ).textContent; var uniforms = { topColor: { type: "c", value: new THREE.Color(0x000000) }, bottomColor: { type: "c", value: new THREE.Color( 0x262626 ) }, offset: { type: "f", value: 100 }, exponent: { type: "f", value: 0.7 } } var skyGeo = new THREE.SphereGeometry( 2000, 32, 15 ); var skyMat = new THREE.ShaderMaterial( { vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: uniforms, side: THREE.BackSide } ); var sky = new THREE.Mesh( skyGeo, skyMat ); scene.add( sky ); var light = new THREE.PointLight(0xfffff3, 0.8); light.position.set(-100,200,100); scene.add(light); var sphereSize = 1; var pointLightHelper = new THREE.PointLightHelper( light, sphereSize ); scene.add( pointLightHelper ); var light2 = new THREE.PointLight(0xd7f0ff, 0.2); light2.position.set(200,200,100); scene.add(light2); var sphereSize = 1; var pointLightHelper2 = new THREE.PointLightHelper( light2, sphereSize ); scene.add( pointLightHelper2 ); var light3 = new THREE.PointLight(0xFFFFFF, 0.5); light3.position.set(150,200,-100); scene.add(light3); var sphereSize = 1; var pointLightHelper3 = new THREE.PointLightHelper( light3, sphereSize ); scene.add( pointLightHelper3 ); var loader = new THREE.ColladaLoader(); loader.options.convertUpAxis = true; loader.load( 'models/dummy1.dae', function ( collada ) { //dummy1.dae var dae = collada.scene; var skin = collada.skins[ 0 ]; dae.position.set(0,0,0);//x,z,y- if you think in blender dimensions ;) dae.scale.set(1.5,1.5,1.5); scene.add(dae); var axes = new THREE.AxisHelper(50); axes.position = dae.position; scene.add(axes); var gridXZ = new THREE.GridHelper(100, 10); gridXZ.setColors( new THREE.Color(0x8f8f8f), new THREE.Color(0x8f8f8f) ); gridXZ.position.set(0,0,0 ); scene.add(gridXZ); }); controls = new THREE.OrbitControls(camera, renderer.domElement); } function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); controls.update(); } </script> </body> </html>
Limitando o zoom
Por padrão o zoom é infinito. O problema é que depois de uma certa distância vamos perder o nosso modelo de vista.
Para resolver essa questão, acesse o script OrbitControls.js e localize o código abaixo. Os desenvolvedores do three.js oferecem um script bem documentado, isso facilita bastante para mudar os valores no código. Você pode alterar o zoom e a rotação. No meu caso bastou alterar o this.minDistance e o this.maxDistance.
Com algumas tentativas e erros consegui o resultado certo.
// This option actually enables dollying in and out; left as "zoom" for // backwards compatibility this.noZoom = false; this.zoomSpeed = 1.0; // Limits to how far you can dolly in and out this.minDistance = 0; this.maxDistance = Infinity;
Eu deixei algo assim:
// This option actually enables dollying in and out; left as "zoom" for // backwards compatibility this.noZoom = false; this.zoomSpeed = 1.0; // Limits to how far you can dolly in and out this.minDistance = 20; this.maxDistance = 300;
Publicando os arquivos no servidor
Então tudo que fizemos até aqui é um desenvolvimento offline. O próximo passo será publicar os seus arquivos no servidor web. Eu estou usando o fillezilla para publicar meus arquivos.
Existem servidores internacionais bastante baratos no mercado. Já vi servidores que custam $ 2,99 por mês mas devemos ficar atentos pois os serviços de hospedagens baratos não suportam muitos recursos e tecnologias e se precisar que um script funcione eles cobram a parte. E também não tem um suporte adequado.
O servidor que estou usando é Locaweb, como sou fornecedora do serviço pago um valor relativamente alto para oferecer aos meus clientes o serviço de hospedagem.
Levando em consideração que tenho um número de clientes que mantém meu servidor auto sustentável posso cobrar um valor muito baixo e oferecer todos recursos, segurança e suporte. Caso interessar é só entrar em contato. :)
Você pode publicar seus arquivos abrindo o Filezilla e conectando no seu web server. Tudo que você são os dados ftp, usuário e senha, em alguns caso a porta. Todas essas informações são fornecidas pelo seu provedor de hospedagem.
Eu criei uma subpasta chamada "_3D" e copiei todo o conteúdo da minha pasta de desenvolvimento incluindo a pasta models e js e colei na dentro da minha pasta "_3D". Se todo esse procedimento for feito corretamente e seu provedor de hospedagem oferecer suporte para a renderização 3D vai funcionar perfeitamente.
Clique aqui para ver o resultado final.
Boa parte do conteúdo desse tutorial foi traduzida do site Quaint.
Qualquer dúvida estou a disposição. Deixem um comentário e irei responder o mais breve possível.
Abraço!!
Jey









