Render a custom glb from blender

Am I importing my .glb wrong? I finally figured out that I was typing GTLF instead of GLTF. :stuck_out_tongue: I’ll go through this carefully tomorrow, for I have reached critical exhaustion after getting my shape all fixed up in blender. However, upon reading someone else’s post, I might be in big trouble.

I made a many sided dice with a number on each face. Then, I converted each face into its own object (so that maybe I could make the faces clickable using raycaster in three). But, I also converted the numbers into to a meshes because I had to in order to import the thing. (text objects aren’t meshes by default in blender) Someone else’s post says that I can only import ONE mesh? I have sooo many! Maybe I’m dead in the water.

import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

//const loader = new GLTFLoader();
const canvas = document.querySelector('.webgl');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGL1Renderer({ 
  canvas: canvas
});

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

//THIS IS WHERE YOU CAN CHANGE THE BACKGROUND COLOR IF YOU WANT
//scene.background = renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)"));
 renderer.setSize(sizes.width, sizes.height);
 renderer.setClearColor(0x000000, 1.0);
 renderer.setPixelRatio(window.devicePixelRatio);
 renderer.shadowMap.enabled = true;
 renderer.shadowMap.type = THREE.PCFSoftShadowMap;

 document.body,appendChild(renderer.domElement);

camera.position.setX(5);
camera.position.setY(5);
camera.position.setZ(5);

camera.lookAt(0,0,0);

const ground = new THREE.PlaneGeometry (10,10);
const material = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
const plane = new THREE.Mesh(ground,material);
scene.add(plane);

//This listens to dom events on the mouse and updates the screen accordingly
const controls = new OrbitControls(camera, renderer.domElement);

const loader = new GLTFLoader().setPath('dice_v2_seperateFaces_backup.glb');

loader.load( 'dice_v2_seperateFaces_backup.glb', function ( glb ) {

	scene.add( glb.scene );

}, undefined, function ( error ) {

	console.error( error );

} );



 const directionalLight = new THREE.DirectionalLight("rgb(255,204,204)", 0.5);
 scene.add(directionalLight);

 const hemiLight = new THREE.HemisphereLight("rgb(255,204,204)", 0.5);
 scene.add(hemiLight);

 const spotlight = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
 spotlight.position.set(0,10,0);
 scene.add(spotlight);

 const gridHelper = new THREE.GridHelper(200,50);
 scene.add(gridHelper);



// scene.add(myCustomShape);

function animate() {
  
  // myCustomShape.rotation.x += 0.01;
  // myCustomShape.rotation.y += 0.005;
  // myCustomShape.rotation.z += 0.01;

 // myCustomShape.computeVertexNormals();

  controls.update();

  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

animate();

You are free to import as many meshes as you’d like - and the code looks ok. Does the model look alright when dropped in gltf viewer ?

(Also make sure that the model is loading at all - remove the .setPath part and check in devtools Network panel whether the file is correctly loaded.)

It’s not rendering, but I will start over with a project that renders and try changing it line by line as needed. Thanks for the input! I’ll try that.

Well, it’s mostly alright. I think there’s some shape hidden inside it that I can’t see in blender or 3DViewer.

This scene is fully functional and renders. Now, maybe I can add in the custom dice object.

//import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#background_canvas'),
});

//scene.background = renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)"));

//renderer.setClearColor(0xEEEEEE);
renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)", 1.0));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(30);
camera.position.setX(-3);

const cylinderGeometry = new THREE.CylinderGeometry(15, 15, 15, 7, 5, false);
//we changed from MeshBasicMaterial that does NOT require a lightsource to MeshStandardMaterial, that does.
const material = new THREE.MeshStandardMaterial({color: 0xffffff, wireframe: false});
const meshedSelector = new THREE.Mesh(cylinderGeometry, material);

// const ground = new THREE.PlaneGeometry (10,10);
// const material2 = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
// const plane = new THREE.Mesh(ground,material2);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

// var geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
// var mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
// var plane = new THREE.Mesh(geo, mat);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
const lightHelper1 = new THREE.DirectionalLightHelper(directionalLight);
directionalLight.position.set(25,25,25);
directionalLight.lookAt(0,0,0);
scene.add(directionalLight,lightHelper1);

//hemisphere light is functional
const hemiLight = new THREE.HemisphereLight("rgb(255,204,204)", 0.5);
const lightHelper2 = new THREE.HemisphereLightHelper(hemiLight);
hemiLight.position.set(35,25,10);
hemiLight.lookAt(0,0,0);
scene.add(hemiLight, lightHelper2);

//Spotlight is functional
const spotLight = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLight.position.set(25,15,10);
spotLight.lookAt(0,0,0);
const lightHelper3 = new THREE.SpotLightHelper(spotLight);
scene.add(spotLight, lightHelper3);


const gridHelper = new THREE.GridHelper(200,50);
scene.add(gridHelper);

//This listens to dom events on the mouse and updates the screen accordingly
const controls = new OrbitControls(camera, renderer.domElement);


scene.add(meshedSelector);

function animate() {
  requestAnimationFrame(animate);

  meshedSelector.rotation.x += 0.01;
  meshedSelector.y += 0.005;
  meshedSelector.z += 0.01;

  cylinderGeometry.computeVertexNormals();

  controls.update();

  renderer.render(scene, camera);
}

animate();

Next, I remove the polyhedron from the scene. Everything else still renders.
QUESTION: Where the heck is that terrible green background color coming from?
I see it. It is the setClearColor line.

//import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#background_canvas'),
});

//scene.background = renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)"));

//renderer.setClearColor(0xEEEEEE);
renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)", 1.0));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(30);
camera.position.setX(-3);

//const cylinderGeometry = new THREE.CylinderGeometry(15, 15, 15, 7, 5, false);
//we changed from MeshBasicMaterial that does NOT require a lightsource to MeshStandardMaterial, that does.
//const material = new THREE.MeshStandardMaterial({color: 0xffffff, wireframe: false});
//const meshedSelector = new THREE.Mesh(cylinderGeometry, material);

// const ground = new THREE.PlaneGeometry (10,10);
// const material2 = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
// const plane = new THREE.Mesh(ground,material2);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

// var geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
// var mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
// var plane = new THREE.Mesh(geo, mat);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
const lightHelper1 = new THREE.DirectionalLightHelper(directionalLight);
directionalLight.position.set(25,25,25);
directionalLight.lookAt(0,0,0);
scene.add(directionalLight,lightHelper1);

//hemisphere light is functional
const hemiLight = new THREE.HemisphereLight("rgb(255,204,204)", 0.5);
const lightHelper2 = new THREE.HemisphereLightHelper(hemiLight);
hemiLight.position.set(35,25,10);
hemiLight.lookAt(0,0,0);
scene.add(hemiLight, lightHelper2);

//Spotlight is functional
const spotLight = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLight.position.set(25,15,10);
spotLight.lookAt(0,0,0);
const lightHelper3 = new THREE.SpotLightHelper(spotLight);
scene.add(spotLight, lightHelper3);


const gridHelper = new THREE.GridHelper(200,50);
scene.add(gridHelper);

//This listens to dom events on the mouse and updates the screen accordingly
const controls = new OrbitControls(camera, renderer.domElement);


//scene.add(meshedSelector);

function animate() {
  requestAnimationFrame(animate);

  // meshedSelector.rotation.x += 0.01;
  // meshedSelector.y += 0.005;
  // meshedSelector.z += 0.01;

  //cylinderGeometry.computeVertexNormals();

  controls.update();

  renderer.render(scene, camera);
}

animate();

It helps, but it is not compulsory.

//import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#background_canvas'),
});

//scene.background = renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)"));

//renderer.setClearColor(0xEEEEEE);
renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)", 1.0));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

camera.position.setZ(30);
camera.position.setX(-3);

const loader = new GLTFLoader().setPath('dice_v2_seperateFaces_backup.glb');

loader.load( 'dice_v2_seperateFaces_backup.glb', function ( glb ) {

 	scene.add( glb.scene );

 }, undefined, function ( error ) {

 	console.error( error );

 } );

//const cylinderGeometry = new THREE.CylinderGeometry(15, 15, 15, 7, 5, false);
//we changed from MeshBasicMaterial that does NOT require a lightsource to MeshStandardMaterial, that does.
//const material = new THREE.MeshStandardMaterial({color: 0xffffff, wireframe: false});
//const meshedSelector = new THREE.Mesh(cylinderGeometry, material);

// const ground = new THREE.PlaneGeometry (10,10);
// const material2 = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
// const plane = new THREE.Mesh(ground,material2);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

// var geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
// var mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
// var plane = new THREE.Mesh(geo, mat);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
const lightHelper1 = new THREE.DirectionalLightHelper(directionalLight);
directionalLight.position.set(25,25,25);
directionalLight.lookAt(0,0,0);
scene.add(directionalLight,lightHelper1);

//hemisphere light is functional
const hemiLight = new THREE.HemisphereLight("rgb(255,204,204)", 0.5);
const lightHelper2 = new THREE.HemisphereLightHelper(hemiLight);
hemiLight.position.set(35,25,10);
hemiLight.lookAt(0,0,0);
scene.add(hemiLight, lightHelper2);

//Spotlight is functional
const spotLight = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLight.position.set(25,15,10);
spotLight.lookAt(0,0,0);
const lightHelper3 = new THREE.SpotLightHelper(spotLight);
scene.add(spotLight, lightHelper3);


const gridHelper = new THREE.GridHelper(200,50);
scene.add(gridHelper);

//This listens to dom events on the mouse and updates the screen accordingly
const controls = new OrbitControls(camera, renderer.domElement);


//scene.add(meshedSelector);

function animate() {
  requestAnimationFrame(animate);

  // meshedSelector.rotation.x += 0.01;
  // meshedSelector.y += 0.005;
  // meshedSelector.z += 0.01;

  //cylinderGeometry.computeVertexNormals();

  controls.update();

  renderer.render(scene, camera);
}

animate();

Ok. So, I get an error when I uncomment my loader. Let me think about this…

This error means the path to the model is incorrect.

You are my hero, mjurczyk!!!

It’s alive!!

Oh my gosh! It’s so beautiful. I got rid of the green and added lights and spinning. Its wonderful! Thank you all so much for your help.

Now, to add clickability…

//import './style.css';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#background_canvas'),
});

THREE.ColorManagement.enabled = true;
//renderer.setClearColor(color, opacity);

renderer.setClearColor(new THREE.Color("rgb(100, 100, 100)"), 0.2);
//renderer.setClearColor(new THREE.Color("rgb(118, 165, 175)", 1.0));
//renderer.setClearColorHex( 0xffffff, 1 );
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);


//const axesHelper = new THREE.AxesHelper( 5 );
//scene.add( axesHelper );

//The X axis is red. The Y axis is green. The Z axis is blue.
camera.position.setX(3);
camera.position.setY(3);
camera.position.setZ(-2);

//const loader = new GLTFLoader();
//Absolute Path C:\Users\HP\Desktop\apps-threeJSImport\vite-project\dice_v2_seperateFaces_backup.glb
//Relative Path of custom object vite-project/dice_v2_seperateFaces_backup.glb
// Relative path of main.JS vite-project/main.js

//loader.load( './dice_v2_seperateFaces_backup.glb', function ( glb ) {
  //const loader = new GLTFLoader().setPath('dice_v2_seperateFaces_backup.glb');
const loader = new GLTFLoader();

let loadedModel;
//vite-project\Dice
//
//vite-project\main.js
//C:\Users\HP\Desktop\apps-threeJSImport_backup\vite-project\main.js
loader.load( './dice_v2_seperateFaces_backup.glb', function ( glb ) {
  
    loadedModel = glb;
    glb.castShadow = true;
   	scene.add( glb.scene );
    

     glb.scene.traverse(obj => {
      if (obj.isMesh) {
        console.log(obj.geometry);
        console.log(obj.name);
        console.log(obj.id);
        console.log("----------------");
      }
   });
  
   }, undefined, function ( error ) {
  
   	console.error( error );
  
   } );

//const cylinderGeometry = new THREE.CylinderGeometry(15, 15, 15, 7, 5, false);
//we changed from MeshBasicMaterial that does NOT require a lightsource to MeshStandardMaterial, that does.
//const material = new THREE.MeshStandardMaterial({color: 0xffffff, wireframe: false});
//const meshedSelector = new THREE.Mesh(cylinderGeometry, material);

// const ground = new THREE.PlaneGeometry (10,10);
// const material2 = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
// const plane = new THREE.Mesh(ground,material2);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

//You have used MeshBasicMaterial for your plane mesh which is a unlit material. So it does not receive shadows. 
//Using a lit material like MeshStandardMaterial solves the issue.

const boxGeometry = new THREE.BoxGeometry(10,0.2,10);
const boxMaterial = new THREE.MeshStandardMaterial({color: 0x000082});
const box = new THREE.Mesh(boxGeometry, boxMaterial);
box.position.set(0, -4, 0);
box.receiveShadow = true
scene.add(box);


// const planeGeometry = new THREE.PlaneGeometry(30,30);
// const planeMaterial = new THREE.MeshBasicMaterial({color: 0x0000ff});
// const plane = new THREE.Mesh(planeGeometry, planeMaterial);
// plane.position.set(25,15,10);
// scene.add(plane);

// var geo = new THREE.PlaneBufferGeometry(2000, 2000, 8, 8);
// var mat = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide });
// var plane = new THREE.Mesh(geo, mat);
// plane.rotateX( - Math.PI / 2);
// scene.add(plane);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
//const lightHelper1 = new THREE.DirectionalLightHelper(directionalLight);
directionalLight.position.set(25,25,25);
directionalLight.lookAt(0,0,0);
directionalLight.castShadow = true;
//scene.add(directionalLight,lightHelper1);
scene.add(directionalLight);

//hemisphere light is functional - this one has rose colored light like in the eavening
// It makes the metallic polyhedron have a rosy hue - more of a brown.
const hemiLight = new THREE.HemisphereLight("rgb(255,204,204)", 0.5);
//const lightHelper2 = new THREE.HemisphereLightHelper(hemiLight);
hemiLight.position.set(35,25,10);
hemiLight.castShadow = true;
hemiLight.lookAt(0,0,0);
//scene.add(hemiLight, lightHelper2);
scene.add(hemiLight);

// //hemisphere light is functional - this one has white light
// const hemiLight = new THREE.HemisphereLight(0xffffff, 0.5);
// //const lightHelper2 = new THREE.HemisphereLightHelper(hemiLight);
// hemiLight.position.set(35,25,10);
// hemiLight.lookAt(0,0,0);
// //scene.add(hemiLight, lightHelper2);
// scene.add(hemiLight);

//Spotlight is functional
const spotLight = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLight.position.set(25,15,10);
spotLight.lookAt(0,0,0);
spotLight.castShadow = true;
//const lightHelper3 = new THREE.SpotLightHelper(spotLight);
//scene.add(spotLight, lightHelper3);
scene.add(spotLight);

//Spotlight is functional
const spotLightOnFace1 = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLightOnFace1.position.set(-5,-5,-5);
spotLightOnFace1.castShadow = true;
spotLightOnFace1.lookAt(0,0,0);
//const lightHelper4 = new THREE.SpotLightHelper(spotLightOnFace1);
//scene.add(spotLightOnFace1, lightHelper4);
scene.add(spotLight);

//Spotlight is functional
const spotLight2 = new THREE.SpotLight(0xffffff, 3, 100, 0.2, 0.5);
spotLight2.position.set(2,5,2);
spotLight2.castShadow = true;
spotLight2.lookAt(0,0,0);
spotLight2.castShadow = true;
//const lightHelper4 = new THREE.SpotLightHelper(spotLightOnFace1);
//scene.add(spotLightOnFace1, lightHelper4);
scene.add(spotLight2);

const pointLight_face1 = new THREE.PointLight( 0x0000ff, 1, 100);
pointLight_face1.position.set(0,-1, -1);
pointLight_face1.lookAt(0,0,0);
//const lightHelper5 = new THREE.PointLightHelper(pointLight_face1);
//scene.add(pointLight_face1, lightHelper5);
scene.add(pointLight_face1);

const pointLight_face9 = new THREE.PointLight( 0x0000ff, 1, 100);
pointLight_face9.position.set(0,1,1);
pointLight_face9.lookAt(0,0,0);
//const lightHelper6 = new THREE.PointLightHelper(pointLight_face9);
//scene.add(pointLight_face9, lightHelper6);
scene.add(pointLight_face9);

//THIS IS THE BIG 2D Mesh (grid) that shows you space.
//const gridHelper = new THREE.GridHelper(200,50);
//scene.add(gridHelper);

//This listens to dom events on the mouse and updates the screen accordingly
const controls = new OrbitControls(camera, renderer.domElement);


//scene.add(meshedSelector);

function animate() {
  requestAnimationFrame(animate);

  // https://www.youtube.com/watch?v=WBe3xrV4CPM
  if(loadedModel){
      var isophereMesh = loadedModel.geometry;
      console.log("isosphere is mesh?" + isophereMesh);
      //isophere.rotation.x += 0.01;

      loadedModel.scene.rotation.x += 0.01;
      loadedModel.scene.rotation.y += 0.005;
      //loadedModel.scene.roation.z += 0.01;

  }

  // meshedSelector.rotation.x += 0.01;
  // meshedSelector.y += 0.005;
  // meshedSelector.z += 0.01;

  //https://stackoverflow.com/questions/47589370/three-js-unable-to-access-imported-object-property-outside-loader-load
  //parent.position.x = ....
  
  //parent.getObjectById(27).rotation.x += 0.01;
  //cylinderGeometry.computeVertexNormals();
 // var myCustomObject = parent.getObjectByID(28);
 //var myCustomObject = getObjectByID(28);


  controls.update();

  renderer.render(scene, camera);
}

animate();