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.
Let’s do the same recap as last time: to load GLTF, giving it a material, and render it we need to:
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.
GLTFLoader: We need to import the GLTF Library and load the GLTF through it.
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.
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.
Don’t forget to Add the model to the threejs scene.
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();