我试图在React with Meteor中构建一个简单的对象查看器,它可以使用以下npm模块导入.obj和.mtl文件:
到目前为止,我已设法使用OBJLoader显示对象。 但是当我尝试使用MTLLoader应用纹理后渲染对象时,我从控制台收到此错误:
未捕获的TypeError:无法读取属性' toString'未定义的 在WebGLPrograms.getProgramCode(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:50707) 在initMaterial(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:54628) at setProgram(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:54820) 在WebGLRenderer.renderBufferDirect(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:53883) 在renderObject(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:54613) 在renderObjects(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:54586) 在WebGLRenderer.render(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:54350) 在WebGlDisplay.renderScene(WebGlDisplay.jsx:86) at onClick(WebGlDisplay.jsx:90) 在HTMLUnknownElement.boundFunc(modules.js?hash = eae498e3ee56e21f967b663c5bed3444c66eaef2:8794)
原因: getProgramCode 中的 material.onBeforeCompile 未定义
我的代码如下所示:
import React, { Component } from 'react'
import THREE from 'three'
const MTLLoader = require('three-mtl-loader');
const OBJLoader = require('three-obj-loader')(THREE);
export default class WebGlDisplay extends Component {
constructor(props) {
super(props)
}
//init canvas
init(){
const width = this.mount.clientWidth;
const height = this.mount.clientHeight;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setClearColor('#000000', 0.2);
renderer.setSize(width, height);
camera.position.set(3,4,6);
camera.lookAt(new THREE.Vector3());
this.scene = scene;
this.camera = camera;
this.renderer = renderer;
this.mount.appendChild(this.renderer.domElement);
}
//load & render object
drawOBJ(){
const mtlLoader = new MTLLoader();
let onProgress = function(e){console.log("rendering:" + e)};
let onError = function(e){console.log("error:" + e)};
mtlLoader.load("eagle.mtl", materials => {
materials.preload();
// OBJ Loader
const objLoader = new THREE.OBJLoader();
this.materials = materials;
objLoader.setMaterials(materials);
objLoader.load("eagle.obj", object => {
this.object = object;
this.scene.add(object);
}, onProgress, onError);
}, onProgress,onError);
this.renderScene();
}
componentDidMount() {
this.init();
this.drawOBJ();
}
renderScene() {
this.renderer.render(this.scene, this.camera)
}
render() {
return (
<div onClick={(e) => this.renderScene()}
style={{ width: '800px', height: '600px' }}
ref={(mount) => { this.mount = mount }}
/>
)
}
}
有谁知道我为什么会收到此错误? 我尝试使用不同的.obj-和.mtl文件,但错误仍然存在(每当我尝试调用 renderScene()时)。
无论如何,这可能是模块版本的问题,还是加载时的一些时序问题?
任何帮助都将不胜感激。
答案 0 :(得分:2)
问题似乎是三mtl-loader NPM包在它的package.json中引用了一个过时的three.js版本,所以即使你使用的是最新版本的三个,插件也不是! / p>
显然这不是一个可行的长期修复,但是我将node_modules/three-mtl-loader/package.json
中的三个版本更改为0.87.1并删除了目录node_modules/three-mtl-loader/node_modules
以获得良好的衡量标准并运行了我的示例直接工作,纹理和所有。
显然,插件需要更新。我还看到了插件中的源和三个示例文件夹(case语句中的'Tr'与'tr')之间至少有一个功能差异,并且它不遵循与其他加载器插件相同的初始化行为(具体而言)它没有通过调用require("three-mtl-loader")(THREE)
)来初始化,因此有一些工作可以使它成为船形。
或者,似乎作者已将其版本号更新为其回购中的0.86.0(足够高),但尚未对NPM进行部署。所以,如果你觉得很勇敢,你可以改变你的package.json来获得行
"dependencies": {
...
"three-mtl-loader": "git+https://git@github.com/nascherman/three-mtl-loader.git",
...
}
答案 1 :(得分:0)
作为一种解决方法,我最终做的是获取最新MTLLoader Version的本地副本并略微修改它,因为它似乎是@ user1691694指出的problem with the version。 如果有人在这里需要这个我导入它的方式:
在MTLLoader文件中,在顶部添加以下行:
import THREE from 'three';
在底部:
module.exports.default = THREE.MTLLoader
像question post中的drawOBJ函数一样使用它,并将其导入目标文件中,如下所示:
import MTLLoader from './MTLLoader.js';