【问题标题】:three-mtl-loader error: THREE.MeshPhongMaterial: .shading has been removed -> object not visible三-mtl-loader 错误:THREE.MeshPhongMaterial:.shading 已被移除 -> 对象不可见
【发布时间】:2018-05-25 00:17:06
【问题描述】:

昨天我问了这个问题(Uncaught TypeError: THREE.MTLLoader is not a constructor 2.0),我以为我终于开始工作了,但现在却出现了新的问题:

我已经使用 npm 安装了“three-mtl-loader”,但现在该对象似乎不可见,尽管我可以通过console.log 看到该对象存在。

由于某种原因,它现在吐出以下错误,我猜这就是它不可见的原因:

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

我现在的代码如下所示:

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

//create global variables such that we can work with models outside of loader: 
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;     //save in global variables and add those to the scene
      model2 = object1; 

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

  });
});

我不太确定这是否与以下问题类似:https://github.com/sohamkamani/three-object-loader/issues/9,因为如果我例如插入:

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

插入了一个白色网格 - 但我不知道如何将 mtl 文件插入为颜色,因为在示例中他们使用 getHex()。如果我必须单独为每个网格做这件事,这似乎也需要很长时间(我正在克隆模型,因为我需要两个)。或者我可以以某种方式使用 object.traverse - 我不想手动更改加载器。

非常感谢任何帮助:D

编辑 我现在已经尝试了很多不同的方法,但都没有工作,所以我将在这里总结问题,希望有人能看到它的错误:

  1. 上面提到的方法,并解释了为什么它在 cmets 中不起作用。我更新到三个的最新版本,现在我得到了同样的错误,但只是一个警告,对象仍然不可见。这个错误现在似乎来自别的东西。如果我在 OBJloader 中将其更改为平面阴影,警告会消失,但对象仍然不可见 - 我真的不想更改文件。

    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. 仅使用三个 obj-loader 即可正常工作(如此处所述:Uncaught TypeError: THREE.MTLLoader is not a constructor

  3. 复制 OBJLoader 和 MTLLoader (https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.jshttps://github.com/mrdoob/three.js/blob/master/examples/js/loaders/MTLLoader.js) 并将它们放在文件夹 three/src/loaders 中,然后在 three.js 中包含以下内容:

    从 './loaders/MTLLoader.js' 导出 { MTLLoader} 从 './loaders/OBJLoader.js' 导出 { OBJoader}

然后尝试像这样加载它们:

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

并以与上述相同的方式使用它们会产生Uncaught TypeError: THREE.MTLLoader is not a constructor,而当尝试使用console.log(MTLLoader)console.log(OBJLoader) 时,它们都是未定义的。所以我不确定它们是否正确加载到框架中,因为我只能找到在 html (&lt;script src="js/loaders/OBJLoader.js"&gt;&lt;/script&gt;) 中加载它们的示例。我对打字稿很陌生,所以我不确定是否应该创建一个参考路径,或者如何实现这一点。

如果我尝试使用 OBJLoader2,也会出现同样的问题。

  1. 我尝试做的最后一件事是加载实际上在三个示例中的 obj 和 mtl 加载器,我在 three.js 文件中引用它:export { OBJLoader } from '../examples/js/loaders/OBJLoader.js' 但给出了相同的“不”构造函数的错误 `

【问题讨论】:

  • 您能否发布您收到的整个错误信息?在进行任何猜测之前,我想看看错误来自哪里(哪个文件)。
  • 当然是 - 1 秒
  • three-obj-loader 是导致警告的原因(这不是错误),three-mtl-loader 是后面的版本。这让我担心这些软件包中还有什么不是最新的。知道这个包也可能落后于曲线,请尝试npmjs.com/package/wwobjloader2 并告诉我们它是否有所作为?
  • 我很想,但我不太确定如何使用它?我尝试以与上述类似的方式使用它:import * as OBJLoader2 from 'wwobjloader2'; OBJLoader2(THREE);,然后改用new THREE.OBJLoader2() - 但我在 OBJLoader2.js 的第一个 if 语句中收到错误 Uncaught ReferenceError: THREE is not defined
  • 这可能意味着 npm 中的版本与 threejs 存储库中的版本相比已经过时了 :(threejs 生态系统不是很好。作为健全性检查,您可以尝试从三个源中复制一个并查看如果可行。在这种情况下,我不得不在 npm 上托管我自己的三个库版本,这并非易事

标签: typescript three.js webgl


【解决方案1】:

聚会有点晚了,但您可以通过利用 imports loader 和 webpack 来解决替代 three.js 加载器 npm 包的需求。

// I'm not positive that we even need to declare this `const` but I haven't tested
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');

这里的要点是我们 import 来满足 TypeScript,但我们明确地 require 加载程序,因此我们有机会为他们提供他们需要的全局 THREE。如果您遇到需要两个导入的依赖项,例如FBXLoader,您可以在!path-to-file.js 之前用逗号分隔它们。

这有点傻,但它让我们无需依赖可能与您当前版本的三个不匹配的自定义包即可工作。我在使用 TypeScript 2.9.2 构建的 React 应用程序中成功地将其与 MTLLoader 和 OBJLoader 一起使用。

【讨论】:

  • 我正在尝试使用 Parcel 捆绑器而不是 Webpack 来执行类似的操作,因此“imports-loader”包不适用。我尝试直接“要求”或“导入”three/examples/js/loaders/OBJLoader.js,但我收到一个运行时错误,提示未定义三个,即使与您的示例类似,我在尝试导入 OBJLoader 之前已经导入了三个。有什么想法吗?
猜你喜欢
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 2016-06-19
相关资源
最近更新 更多