DEV Community

Cover image for Começando com Three.js, imersão com 3D no navegador
baltz
baltz

Posted on • Edited on

Começando com Three.js, imersão com 3D no navegador

Este artigo é a segunda parte do tutorial, recomendo que veja a primeira caso ainda não tenha visto - Parte 1

Abaixo vou deixar um spoiler do que vamos desenvolver agora:

Continuando do estado em que terminamos a primeira parte:

index.html

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="utf-8" />
    <title>Meu primeiro 3D</title>
    <style>
      body {
        margin: 0;
      }
    </style>
  </head>
  <body>
    <canvas id="c"></canvas>
    <script type="module" src="/main.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode
import * as THREE from "three";

function main() {
  const canvas = document.querySelector("#c");
  const renderer = new THREE.WebGLRenderer({ antialias: true, canvas });

  const camera = new THREE.PerspectiveCamera(75, 2, 0.1, 5);
  camera.position.z = 2;

  const scene = new THREE.Scene();
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshBasicMaterial({ color: 0x44aa88 });
  const cube = new THREE.Mesh(geometry, material);

  scene.add(cube);
  renderer.render(scene, camera);
}

main();
Enter fullscreen mode Exit fullscreen mode

Já possuímos um modelo 3D renderizado no navegador. Agora, vamos adicionar uma camada de imersão para aprimorar nossa experiência. Ao final deste artigo, teremos um novo projeto 3D imersivo pronto para ser adicionado aos nossos destaques no GitHub.

Para começar, vamos tornar nosso Canvas responsivo a qualquer tamanho de tela. Isto pode ser feito adicionando o seguinte estilo:

index.html

<style>
      body, html {
        margin: 0;
        height: 100vh;
      }

      #c {
        position: absolute;
        height: 100%;
        width: 100%;
        display: block;
      }
</style>
Enter fullscreen mode Exit fullscreen mode

Vamos adicionar a propriedade "alpha" ao nosso Renderer e definir um tamanho ao Canvas usando o método setSize. Além disso, vamos ajustar a perspectiva da nossa câmera:

main.js

  const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true, canvas: canvas });
  renderer.setSize(window.innerWidth, window.innerHeight);

  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
Enter fullscreen mode Exit fullscreen mode

Agora que temos um canvas responsivo que renderiza nosso modelo 3D corretamente em qualquer tamanho de tela, podemos começar a adicionar imersão à nossa experiência. Para isso, vamos começar a interagir com os movimentos do mouse:

main.js

  function render() {
    document.addEventListener("mousemove", (event) => {
      let mouseX = event.clientX;
      let mouseY = event.clientY;

      cube.rotation.x = mouseY * 0.008;
      cube.rotation.y = mouseX * 0.0036;
    });

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
Enter fullscreen mode Exit fullscreen mode

Ótimo! Agora temos uma experiência imersiva com um modelo 3D. Conquistamos nossa pequena vitória do dia, e como bônus, vamos um pouco além (mas não fique mal acostumado). Vamos tornar nosso projeto mais atraente e digno de destaque no nosso GitHub, adicionando iluminação e explorando formas e materiais mais complexos.

main.js

import * as THREE from "three";

function main() {
  const canvas = document.querySelector("#c");
  const renderer = new THREE.WebGLRenderer({
    antialias: true,
    canvas,
    alpha: true,
  });
  renderer.setSize(window.innerWidth, window.innerHeight);

  const fov = 75;
  const near = 0.1;
  const far = 1000;
  const camera = new THREE.PerspectiveCamera(
    fov,
    window.innerWidth / window.innerHeight,
    near,
    far
  );

  camera.position.z = 30;

  const scene = new THREE.Scene();
  const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);

  const material = new THREE.MeshPhysicalMaterial({
    metalness: 0, // High metalness for ruby-like shine
    roughness: 0, // Low roughness for smooth, glossy surface
    clearcoat: 0,
    clearcoatRoughness: 1,
    transmission: 0,
    color: 0xaa1133,
  });

  const cube = new THREE.Mesh(geometry, material);

  scene.add(cube);

  renderer.render(scene, camera);

  function render() {
    document.addEventListener("mousemove", (event) => {
      let mouseX = event.clientX;
      let mouseY = event.clientY;

      cube.rotation.x = mouseY * 0.008;
      cube.rotation.y = mouseX * 0.0036;
    });

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

  const light = new THREE.SpotLight(0xff22aa, 300, 1000);
  light.position.set(1, 1, 10);
  light.angle = 0.1;
  light.penumbra = 10;
  scene.add(light);
}

main();

Enter fullscreen mode Exit fullscreen mode

e vamos aproveitar para atualizar nossa index.html

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="utf-8" />
    <title>Meu primeiro 3D</title>
    <style>
      html,
      body {
        margin: 0;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #111;
        font-size: 2em;
        font-family: sans-serif;
      }
      #c {
        position: absolute;
        height: 100%;
        width: 100%;
        display: block;
        opacity: 0.6;
      }
    </style>
  </head>
  <body>
    <canvas id="c"></canvas>
    <h1>Meu primeiro 3D</h1>
    <script type="module" src="/main.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Espero que tenham gostado 🤙

Top comments (0)