There was an error in parsing the JSON syntax while loading models using Three.js GLTFLoader

Discovering how to use Three.js has been an exciting journey for me, thanks to the tutorial available on discoverthreejs.com.

Creating meshes and geometry through three.js is a breeze for me.

However, things take a turn when I try to import models from Blender or other software.

I usually design my models in Blender 2.8 and export them as .glb files. After testing these files with a gltf viewer, everything seems to be in order.

https://i.sstatic.net/0Cq94.jpg

Unfortunately, the challenge arises when I attempt to bring these models into my website using Three.js, resulting in this error:

https://i.sstatic.net/cgPY7.png

https://i.sstatic.net/tL77m.png

I initially thought the issue was with my model; hence, I experimented with exporting it as either gltf or glb, but encountered the same error.

Even after downloading another model from the web, the problem persisted.

In my development process, I utilize parcel.js.


{
  "name": "cedric_grvl",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "clean": "rm -rf dist",
    "dev": "parcel src/index.html --host 192.168.0.37 --open Firefox"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "autoprefixer": "^9.7.3",
    "parcel-bundler": "^1.12.4",
    "postcss-custom-properties": "^9.0.2",
    "postcss-modules": "^1.4.1",
    "postcss-preset-env": "^6.7.0",
    "sass": "^1.23.7",
    "three": "^0.111.0"
  }
}

All elements are tested within my index.js file.

The following snippet showcases how I integrate Three.js: (no issues here)

*index.js*

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

Below are the functions pertaining to Three.js implementation (tutorial) - everything appears fine here too:

*index.js*

// The following variables need multiple function access, so we declare them initially
let container;
let camera;
let controls;
let renderer;
let scene;
let mesh;

function init() {

  container = document.querySelector( `[data-js="canvas"]` );

  scene = new THREE.Scene();
  scene.background = new THREE.Color( 0xFFFFFF );

  createCamera();
  createControls();
  createLights();
  createMeshes();
  createRenderer();

  // Start the animation loop
  renderer.setAnimationLoop( () => {

    update();
    render();

  } );

}

function createCamera() {

  camera = new THREE.PerspectiveCamera(
    35, // FOV
    container.clientWidth / container.clientHeight, // aspect 
    0.1, // near clipping plane
    100, // far clipping plane
  );

  camera.position.set( -4, 4, 10 );

}

function createControls() {

  controls = new OrbitControls( camera, container );

}

function createLights() {

  const ambientLight = new THREE.HemisphereLight(
    0xddeeff, // sky color
    0x202020, // ground color
    5, // intensity
  );

  const mainLight = new THREE.DirectionalLight( 0xffffff, 5 );
  mainLight.position.set( 10, 10, 10 );

  scene.add( ambientLight, mainLight );

}



function createMeshes() {

  const geometry = new THREE.BoxBufferGeometry( 2, 2, 2 );

  const material = new THREE.MeshStandardMaterial( { color: 0x800080 } );

  mesh = new THREE.Mesh( geometry, material );

  scene.add( mesh );

}

function createRenderer() {

  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setSize( container.clientWidth, container.clientHeight );

  renderer.setPixelRatio( window.devicePixelRatio );

  renderer.gammaFactor = 2.2;
  renderer.gammaOutput = true;

  renderer.physicallyCorrectLights = true;

  container.appendChild( renderer.domElement );

}

function update() {

  // Avoid heavy computation here

}

function render() {

  renderer.render( scene, camera );

}

function onWindowResize() {

  camera.aspect = container.clientWidth / container.clientHeight;

  camera.updateProjectionMatrix();

  renderer.setSize( container.clientWidth, container.clientHeight );

}

window.addEventListener('resize', onWindowResize);

init();

The root of the problem might lie in this segment:


const loader = new GLTFLoader();

const url = "./assets/models/test.glb";

const onLoad = ( gltf ) => {

  console.log( gltf );

};

loader.load( url, onLoad );

I've considered a potential issue with the file path and have tried variations like:

'/src/assets/models/test.glb'
'assets/models/test.glb'

Here is an overview of my folder structure:

https://i.sstatic.net/rM3JR.png

Thank you for taking the time to review my situation.

Answer №1

To include the model in your code, follow these steps:

import MODEL from './images/Horse.glb'

Replace 'Model' with the actual path to your glb asset and then use it for loading as shown below:

loader.load( MODEL, function ( glb ) {
    scene.add( glb.scene );
  }, undefined, function ( error ) {
    console.error( error );
});

Answer №2

I came across a helpful tip at discourse.threejs.org

const parcelPath = new URL('./public/models/hands.glb', import.meta.url);
         
loader.load( parcelPath.href  , function ( glb ) {
        that.scene.add( glb.scene );
});

Answer №3

Here is the recommended way to specify the file path:

const loader = new GLTFLoader();
loader.load(
    'FILE_PATH_HERE', (loaded_model) => {
        scene.add(loaded_model.scene);
    }
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having numerous bxsliders implemented in a Genesis child theme

I'm currently working on incorporating multiple bxsliders through custom fields in a wp genesis child theme. The initial slider was successfully implemented using the following function within the genesis child theme functions: add_action('genes ...

Simple steps for Mocking an API call (Get Todos) using ComponentDidMount in React with Typescript, Jest, and Enzyme

About the application This application serves as a basic To Do List. It retrieves tasks from an API located at https://jsonplaceholder.typicode.com/todos?&_limit=5. Objective of the project The main goal is to test an API call that triggers ...

Exploring the process of transferring a variable from Frontend to Backend via a GET API in ReactJS with an Express API

When working with my freight Shipment table, I need to access the email of the logged-in user in order to perform some frontend tasks. However, I am struggling to retrieve this information using the Axios.get() method and use it to query my MySQL DB. In t ...

Vue.js - updating npm to patch version with unclean git working directory

I recently followed a tutorial on how to publish packages to NpmJS. However, I encountered an error when trying to update the package after making changes to the README.MD: npm version patch npm ERR! Git working directory not clean. npm ERR! A .gitignore ...

How should dynamic route pages be properly managed in NextJS?

Working on my first project using NextJS, I'm curious about the proper approach to managing dynamic routing. I've set up a http://localhost:3000/trips route that shows a page with a list of cards representing different "trips": https://i.stack. ...

The preventDefault function fails to work in Firefox

My input is called shop_cat_edit and I've included the following code. However, it seems to work fine in IE but doesn't work in FireFox. Can anyone help me figure out what's wrong? $('[name=shop_cat_edit]').on('click',fu ...

minimize javascript syntax (stackoverflow 2022)

I'm struggling with this puzzle game. Sometimes, when I start a new game, the pieces get shuffled incorrectly. I tried adding a function to fix it, but it doesn't seem to be working. It's really frustrating and I want to simplify the code as ...

Is it possible to include personalized validations in Formik's YupValidationSchema?

Is it possible to include custom validations in Formik's YupValidationSchema as shown below? YupValidationSchema = () => { return Yup.object({ Email: Yup.string() .max(256, "Length exceed 256 chars") ...

A guide on breaking down the ID passed from the backend into three segments using React JS

I pulled the data from the backend in this manner. https://i.stack.imgur.com/vMzRL.png However, I now require splitting this ID into three separate parts as shown here. https://i.stack.imgur.com/iy7ED.png Is there a way to achieve this using react? Bel ...

CriOS unable to recognize OPTIONS request from Tomcat 8

My application uses POST requests with CORS for backend services (from www.mydomain.com to api.mydomain.com). The backend is served by a Tomact8 server, implementing a CORSResponseFilter as shown below: public class CORSResponseFilter implements Container ...

How can I determine the Windows service pack version directly from my web browser?

Is there a method to determine the installed service pack from the browser? It doesn't seem to be available in System.Web.HttpBrowserCapabilities in asp.net. I am looking for a solution to alert users about the necessity of updating to XP Service Pack ...

Implement styling based on user input - Transmit form data via PHP to designated email address

My form allows people to provide their details and share their current timetable. I then group them based on suitable times The PHP form currently prints either 'work' or 'free' into a table cell, based on user selection in the form, a ...

Progressing with JavaScript: Implementing Sound Controls and Dynamic Image Switching

I am looking to create a button that, when clicked, displays a small image and plays a sound. The button should change to a different image and stop the sound when clicked again. Essentially, it functions as a "start" button that loops the sound and change ...

Discover the ins and outs of utilizing the Google+ Hangout API specifically for chatting purposes

I am currently working on a webpage and I want to include a hangout button that will allow users to connect with me and start chatting automatically when clicked. Here is the code I have so far: <script src="https://apis.google.com/js/platform.js" asy ...

Creating a custom inline style button in Froala Editor

As a UX Designer with experience in frontend development, I am currently working on an online editor proof of concept for a usability study. One of the key findings so far is that users are requesting a button that can automatically apply the corporate fon ...

Modify the state from a listener that is enclosed in the useEffect function

Within my hook called useQueryEvents, I have a setup that involves fetching all past transactions for a user and listening to the network for incoming/outgoing transactions. These transactions are then passed into a function called addActionToActivity, whi ...

An undefined value error occurred while attempting to save data to a MongoDB collection through a node/express server

Anticipated Outcome I am looking to successfully save a new page to mongo db after server validation of input, without encountering any errors in the console. The issue seems to be originating from the post method in the routes in admin_pages.js and I&apos ...

Implementing pagination and filtering in a single MERN controller

Is it possible to implement pagination and filtering in the same controller? Filter service:- const filterPosts = async (filterData, token) => { const config = { headers: { Authorization: `Bearer ${token}`, }, data: { ...

Text field in React's material-ui causes the screen to shake

I am encountering an issue with a simple React code that includes a Material-UI Textfield. Whenever I try to enter data into the text field, the screen shakes. Additionally, when I click outside of the box after entering data, the screen shakes again. Ca ...

What is the best way to use CSS to ensure that dynamic, data-driven characters can be properly displayed within a div

I'm in the process of updating a data-centric website that relies on information from an automated database engine. In the HTML, there's a fixed-size button containing text pulled from the database. I'm looking to incorporate some CSS styles ...