3JS #01 – Loading GLTF in three.js and mouse interaction

After a few months of rest, I’m finally able to continue my threejs journey. Devoured the first few lessons and delved right into importing a blender file.

For me the most important part of learning threejs is to be able to load blender files and to emulate the materials. Although I was successful in loading the model, I just don’t think the material for a reflective metallic feel is just there yet. Not sure if it’s because of the poor lighting or I need to explore the different material functions in threejs. However, I like what I’ve technically achieved.

Been enjoying learning threejs and a few web tricks along the way is always an added bonus. Having always pondered on how to amalgamate my multidisciplinary knowledge, I feel enliven through these exercises having sketched out a few end results. Hope to get to them.

I also learned a few more tricks in Blender on converting text to mesh and making them feel more soft.

Let’s do the same recap as last time: to load GLTF, giving it a material, and render it we need to:

  1. Lights: To see our loaded files, we first need to set up lights. Ambient Light & Directional Light. The key light would be the directional light as it’ll need to hit the loaded object.

  2. GLTFLoader: We need to import the GLTF Library and load the GLTF through it.

  3. Find the Object: Inside the load() function, the easiest way is to load the scene but we can get specific with the children array or find objects by name.

  4. Assign Material: Still inside the load() function, we can set the material by assigning a new material, here we used MeshStandardMaterial then changed it’s properties.

  5. Don’t forget to Add the model to the threejs scene.

  6. Update GLTF: to update it we call it inside a boolean condition, still unsure why, but this let’s javascript recognize the loaded object.

Hopefully, this can be a good reminder for me, should I try to load a few more files into it.

import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

/**
 * Cursor // Pure Javascript
 */

const cursor = {
  x: 0,
  y: 0
};

window.addEventListener("mousemove", (event) => {
  cursor.x = event.clientX / sizes.width - 0.5;
  cursor.y = -(event.clientY / sizes.height - 0.5);
});

// Canvas
const canvas = document.querySelector("canvas.webgl");

// Sizes
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight
};

// Scene
const scene = new THREE.Scene();

const ambientLight = new THREE.AmbientLight(0x333333, 1);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(1, 3, 4);
scene.add(directionalLight);

// Loader
let text = null;
const gltfLoader = new GLTFLoader();

gltfLoader.load(
  "models/sample-3d.glb",
  (gltf) => {
    console.log("success");
    console.log(gltf);
    text = gltf.scene.children[0];
    text.position.x = -2;
    text.position.z = 1;
    text.rotation.z = Math.PI * 0.1;

    // Material
    text.material = Object.assign(
      new THREE.MeshStandardMaterial({
        color: 0x9fcae0,
        roughness: 0.05,
        metalness: 0.95,
        emissive: 0x1a1919
      }),
      {}
    );

    scene.add(text);
  },
  (progress) => {
    console.log("progress");
    console.log(progress);
  },
  (error) => {
    console.log("error");
    console.log(error);
  }
);

// Camera
let fov = 105;
const camera = new THREE.PerspectiveCamera(
  fov,
  sizes.width / sizes.height,
  0.1,
  100
);

camera.position.x = -10;
camera.position.z = 3.5;
scene.add(camera);

// Renderer
const renderer = new THREE.WebGLRenderer({
  canvas: canvas,
  alpha: true
});
renderer.setSize(sizes.width, sizes.height);

// Animate
const clock = new THREE.Clock();

const tick = () => {
  const elapsedTime = clock.getElapsedTime();

  // Update objects
  camera.position.x = cursor.x + 1;
  camera.position.y = cursor.y;

  // Update gltf
  if (!!text) {
    text.position.y = Math.sin(elapsedTime * 1) * 0.1 - 0.1; // console.log(text.position.y)
  }

  // Render
  renderer.render(scene, camera);

  // Call tick again on the next frame
  window.requestAnimationFrame(tick);
};

tick();
 
Previous
Previous

3JS #02 – Rabbit Hole in the Old Net

Next
Next

BLE #01 – 90s Design on Blender3D