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.)

1 Like

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.

1 Like

//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.

1 Like

You are my hero, mjurczyk!!!

It’s alive!!

1 Like

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();