【发布时间】:2018-03-28 23:15:54
【问题描述】:
我正在尝试在 React with Meteor 中构建一个简单的对象查看器,它可以使用以下 npm 模块导入 .obj 和 .mtl 文件:
- 三个(0.87.1)
- 反应(15.6.1)
- 三个obj-loader(1.1.3)
- 三-mtl-loader(1.0.1)
到目前为止,我已经设法使用 OBJLoader 显示一个对象。 但是当我在使用 MTLLoader 应用纹理后尝试渲染对象时,我从控制台收到此错误:
未捕获的类型错误:无法读取未定义的属性“toString” 在 WebGLPrograms.getProgramCode (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:50707) 在 initMaterial (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54628) 在 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) 在 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() 时)。
有没有可能是模块版本的问题,或者加载时的一些时间问题?
任何帮助将不胜感激。
【问题讨论】:
-
尽量避免这个
=>“箭头函数”并使用更清晰和明确的代码......我不知道这个=>是如何工作的,但这在我看来是另一个错误的好- 弹性Javascript语法的想法......主要是在引用必须一致且可靠的上下文中......我不是Javascript大师,但来自C / C ++,这种事情对我的影响与火药杂志上的火柴。 -
嗯,你能看看这三个的来源,看看它是否在材质上定义了
onBeforeCompile?你确定你使用的是 87 吗? -
您是否有机会发布此代码,以便我们追踪它并查看发生了什么?这看起来像一个错误,但没有什么比这更明显。
-
箭头函数现在是完全正常的 JavaScript。 @Sedenion 我建议你学习它们。他们不会消失。他们绝对没有错。它们是在现代 JavaScript 中做很多事情的推荐方式。
-
是的,版本肯定是 87 @pailhead。到目前为止,我还不能真正理解这三个来源。我没有找到 onBeforeCompile 的任何直接定义,除了 Material.js 中 Object.assign 中的一个空函数(我什至不明白它是否在某处被调用)。对不起,我在这里似乎不是很有帮助。有没有一种方法可以在不自己托管的情况下将该节点/反应的东西放到网上? (我不知道合适的方法,但无论如何我对这一切都很陌生)