昨天我问了这个问题(Uncaught TypeError: THREE.MTLLoader is not a constructor 2.0),我以为我终于开始工作了,但现在新的问题却出现了:
我已经使用 npm 安装了“三-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
编辑 我现在已经尝试了很多不同的方法,但还没有一个有效,所以我将在这里总结这些问题,希望有人能看到哪里出了问题:
上面提到的方法,并在评论中解释了为什么它不起作用。我更新到了三个的最新版本,现在我得到了相同的错误,但仅作为警告,并且对象仍然不可见。现在错误似乎来自其他地方。如果我在 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
仅使用三对象加载器就可以正常工作(如下所述:Uncaught TypeError:THREE.MTLLoader不是构造函数)
复制 OBJLoader 和 MTLLoader (https://github.com/mrdoob/ Three.js/blob/master/examples/js/loaders/OBJLoader.js 和https://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中加载它们的示例(<script src="js/loaders/OBJLoader.js"></script>
)。我对打字稿还很陌生,所以我不确定是否应该创建一个参考路径,或者如何实现这一点。
如果我尝试使用 OBJLoader2 也会出现同样的问题。
export { OBJLoader } from '../examples/js/loaders/OBJLoader.js'
但这给出了相同的“不是构造函数” ' 错误
`虽然有点晚了,但您可以通过利用 webpack 的 imports loader 来解决对替代 Three.js loader 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 一起使用。
我使用了以下包和代码来使用加载器
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);
};
});