Error message: The object is not visible due to the removal of .shading in THREE.MeshPhongMaterial by three-mtl-loader

Yesterday I posted a question on StackOverflow about an issue with my code (Uncaught TypeError: THREE.MTLLoader is not a constructor 2.0). Initially, I thought I had solved the problem but now new questions have surfaced:

Even though I have installed 'three-mtl-loader' using npm, the object doesn't seem to be visible, despite being able to confirm its existence through console.log.

Now, I am encountering the following error, which might be the reason for the object's invisibility:

 THREE.MeshPhongMaterial: .shading has been removed. Use the boolean .flatShading instead.
 get                                @   three.js:43339
 WebGLPrograms.getParameters        @   three.js:17838
 initMaterial                       @   three.js:21734
 setProgram                         @   three.js:21929
 WebGLRenderer.renderBufferDirect   @   three.js:20964
 renderObject                       @   three.js:21722
 renderObjects                      @   three.js:21695
 WebGLRenderer.render               @   three.js:21463
 render                             @   main.ts:163
 requestAnimationFrame (async)      
 render                             @   main.ts:162 
 requestAnimationFrame (async)      
 render                             @   main.ts:162
 requestAnimationFrame (async)  
 ...    

The current state of my code is as follows:

import * as THREE from 'three'
import * as OBJLoader from 'three-obj-loader'
OBJLoader(THREE)
import * as MTLLoader from 'three-mtl-loader'

//create global variables so models can be accessed outside loader functions
var model1, model2;

var mtlLoader = new MTLLoader();
mtlLoader.setPath('http://blabla/objects/');
mtlLoader.load('bla.obj.mtl', function(materials){

  materials.preload();

  var objLoader = new THREE.OBJLoader();  
  objLoader.setMaterials(materials);
  objLoader.setPath('http://blabla/objects/');
  objLoader.load('bla.obj', function(object){

      var object1 = object.clone();
      model1 = object;     
      model2 = object1; 

      scene.add(model1);
      scene.add(model2)

  });
});

I'm unsure if this is similar to another issue discussed here: https://github.com/sohamkamani/three-object-loader/issues/9. For instance, when trying the code snippet:

 let child;
 for(let i = 0; i < object.children.length; i++) {
    child = object.children[i];
    scene.add(new THREE.Mesh(child.geometry, new THREE.MeshPhongMaterial({ })));
}

A white mesh is inserted, but incorporating the mtl-file color like they do in the example seems time-consuming for each mesh individually due to cloning the model for two separate instances. Can object.traverse possibly aid without manual loader modifications?

Any assistance is greatly appreciated :D

EDIT After attempting various solutions unsuccessfully, summarizing the issues below may provide insight into what's missing or misconfigured:

  1. The method mentioned previously isn't solving the problem as delineated in comments. Steps were taken to update to the latest version of three resulting in a persisting error flagged only as a warning, while objects remain unseen. Adjusting to flatshading within the OBJloader resolves the warnings yet visibility remains elusive - sans alterations to file configurations.

    THREE.MeshPhongMaterial: .shading has been removed. Use the boolean .flatShading instead
    set @   three.js:43344
    parse   @   index.js:628
    (anonymous) @   index.js:58
    (anonymous) @   three.js:30483
    XMLHttpRequest.send (async)     
    load    @   three.js:30563
    load    @   index.js:56
    (anonymous) @   main.ts:117
    (anonymous) @   index.js:36
    (anonymous) @   three.js:30090
    XMLHttpRequest.send (async)     
    load    @   three.js:30146
    load    @   index.js:34
    s   @   _prelude.js:1
    e   @   _prelude.js:1
    (anonymous) @   _prelude.js:1
    
  2. Utilizing solely the three-obj-loader functions correctly as demonstrated in this post: Uncaught TypeError: THREE.MTLLoader is not a constructor

  3. Duplicating both the OBJLoader and MTLLoader scripts (https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js and https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/MTLLoader.js) into the three/src/loaders directory alongside including these exports in three.js:

    export { MTLLoader} from './loaders/MTLLoader.js' export { OBJoader} from './loaders/OBJLoader.js'

Subsequently loading them as depicted below:

import {MTLLoader} from 'three'
import {OBJLoader} from 'three'

Results in a

Uncaught TypeError: THREE.MTLLoader is not a constructor
, wherein checks of console.log(MTLLoader) and console.log(OBJLoader) return undefined statuses. Perhaps, they're incorrectly integrated within the framework since web-based reference scenarios are abundant (
<script src="js/loaders/OBJLoader.js"></script>
). Being relatively new to TypeScript, pondering whether establishing a reference path or another methodology can rectify this conundrum.

Faced with similar hurdles while implementing OBJLoader2.

  1. As a last resort, experimentations encompassed integrating the Three examples’ obj and mtl loaders by referencing them directly within three.js:
    export { OBJLoader } from '../examples/js/loaders/OBJLoader.js'
    leading to analogous 'not a constructor' setback`

Answer №1

Joining the party a bit late, but there's a clever workaround to avoid using alternative three.js loader npm packages. You can achieve this by utilizing the imports loader in conjunction with webpack.

// It seems unnecessary to declare this as `const`, but I haven't confirmed
const THREE = require('three');

import {
  OBJLoader,
  MTLLoader
} from 'three';

require('imports-loader?THREE=three!three/examples/js/loaders/OBJLoader.js');
require('imports-loader?THREE=three!three/examples/js/loaders/MTLLoader.js');

The idea behind this approach is to use import for TypeScript compatibility, while explicitly require the loaders so that we can provide them with the necessary global THREE object. In case you encounter a dependency that requires multiple imports, like FBXLoader, you can list them separated by commas before the !path-to-file.js.

Although it may seem unconventional, this method allows us to work without depending on custom packages that may not align with your current version of three.js. I have successfully implemented this technique with both MTLLoader and OBJLoader in a React application developed with TypeScript 2.9.2.

Answer №2

Below is the package and code I used to implement the loaders:

npm install -D @types/three
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
...
const mtlLoader = new MTLLoader();
mtlLoader.load('example.mtl', (mtl) => {
  const objLoader = new OBJLoader();
  objLoader.setMaterials(mtl);
  objLoader.load('example.obj', (obj) => {
      scene.add(obj);
  };
});

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

How to Add a Rule to an Existing Application Load Balancer Listener using AWS CDK

When I inherited a project, I discovered an application load balancer with a HTTPS Listener that was set up before I began using CDK. This listener currently has 13 rules in place that route requests based on hostname to different fargate instances, with ...

Creating a file logging system with log4js to capture Console logs

Is there a way to automatically log all console logs, including failed expectations and exceptions, to a file without using try and catch in JavaScript? In Java's LOG4j, the rootlogger feature does this by default. Is there a similar functionality ava ...

How can I provide type annotations for search parameters in Next.js 13?

Within my Next.js 13 project, I've implemented a login form structure as outlined below: "use client"; import * as React from "react"; import { zodResolver } from "@hookform/resolvers/zod"; import { signIn } from "n ...

When using the Composition API in Vue 3, the "Exclude" TypeScript utility type may result in a prop validation error

Currently, I am utilizing Vue 3 alongside the Composition API and TypeScript, all updated to their latest stable versions. If we take a look at the types below: export interface Person { name: string; } export type Status = Person | 'UNLOADED&ap ...

Error encountered: YouCompleteMe is unable to locate the necessary executable 'npm' for the installation of TSServer

While attempting to install YouCompleteMe for vim and enable support for Java and Javascript, I followed the instructions provided here. My command was: sudo /usr/bin/python3.6 ./install.py --java-completer --ts-completer Unfortunately, I encountered an ...

Creating a Dynamic Table with Angular 6 - Automating the Population of Content Values

I have a task of populating a table with data from a JSON file. Take a look at the following code snippet: <table> <thead> <tr> <th *ngFor="let datakeys of listData[0] | keys">{{ datakeys }}</th> </tr> < ...

Finding the current URL in React Router can be achieved by using specific methods and properties provided by

Currently, I'm diving into the world of react-redux with react-router. On one of my pages, it's crucial to know which page the user clicked on to be directed to this new page. Is there a method within react-router that allows me to access inform ...

Working with TypeScript to set a value for an object's field

I have two objects of the same model: interface Project { _id?: string title: string description: string goal: string tasks?: Task[] createdAt?: Date updatedAt?: Date } The first object contains all fields from the interface, while the secon ...

A guide on resolving deprecated warnings for typographical errors

Every time I try to npm install I am bombarded with numerous errors. typings WARN deprecated 9/9/2016: "registry:dt/node#6.0.0+20160831021119" is deprecated (updated, replaced or removed) My experiences with typescript have been nothing but a series ...

angular2 ngif does not effectively conceal HTML elements when set to false

In the HTML file, I have the following code: <p *ngIf="!checklistsready"> not ready </p> <p *ngIf="checklistsready"> Ready </p> And in my TypeScript file, it looks like this: checklistsready: boolean = false; constructor( ...

What is the best way to test chained function calls using sinon?

Here is the code I am currently testing: obj.getTimeSent().getTime(); In this snippet, obj.getTimeSent() returns a Date object, followed by calling the getTime() method on that Date. My attempt to stub this functionality looked like this: const timeStu ...

Vue HeadlessUI Error: The function vue.defineComponent is not recognized

Trying to incorporate @headlessui/vue into my nuxt project has been a challenge. My attempt at using it looks like this: <template> <Menu> <MenuItems> <MenuItem>Item</MenuItem> </MenuItems> </Menu&g ...

Is there a way for me to retrieve the bodyHeight attribute of ag-grid using public variables or data?

Working on a project using ag-grid community react. The main feature is a scrollable section filled with data, which can range from one piece to millions of pieces. I'm also incorporating a footer component for the grid that needs to adjust its height ...

Modifying the date format of the ag-Grid date filter

On my Angular 5.2.11 application, I utilize ag-grid to showcase a table. The date column is configured with the default date filter agDateColumnFilter as per the documentation. After enabling browserDatePicker: true, the Datepicker displays dates in the ...

Tips for showcasing unique keywords in Ace Editor within the Angular framework

Can anyone help me with highlighting specific keywords in Angular using ace-builds? I've tried but can't seem to get it right. Here's the code snippet from my component: Check out the code on Stackblitz import { AfterViewInit, Component, ...

How is it possible that my code is continuing to run when it is supposed to be

My API has a limitation of 50 requests per minute for any endpoint. In the code snippet below, I filter objects called orders based on their URLs and store the ones that return data in successfulResponses within my app.component.ts. Promise.all( orders.ma ...

Error encountered while installing Material UI in Next.js with TypeScript and pure JavaScript configurations

I'm brand new to React and Next.js, so please forgive me for asking what may seem like a silly question. I'm attempting to install Material UI in a fresh Next.js application that I created using "npx create-next-app@latest". I've been refere ...

Restrict the properties of an object to match the properties of a different object

I am currently developing an Object patching utility function with the following code snippet class Test{ a:number; b:number; } var c:Test={a:0,b:1} function patchable<T>(obj:T){ return { patch:function<K>(prop:K){ return patc ...

Connect the keys from one enum to either keys or values in another enum

When working with the code below, it is important that the keys of PropertiesNamesInDataBase align with those in User.Keys. While the values of PropertiesNamesInDataBase are used in the backend, it is crucial for uniformity that the names match in the fron ...

Tips for effectively transmitting data while utilizing a declarative/reactive data access method with RxJS in Angular?

Angular typically follows a classic pattern for data access that looks like this: Traditional Data Access Pattern getProducts(): Observable<Product[]> { return this.http.get<Product[]>(this.productsUrl) .pipe( tap(data => consol ...