2017-10-17 169 views
2

我試圖建立一個簡單的對象,觀衆與流星作出反應,可以導入的obj和.mtl文件使用以下NPM模塊:反應,three.js所MTLLoader「material.onBeforeCompile是未定義」

  • 3(0.87.1)
  • 反應(15.6.1)
  • 三OBJ-加載程序(1.1.3)
  • 三MTL-加載程序(1.0.1)

所以遠遠我管理d使用OBJLoader顯示對象。 但是當我嘗試應用紋理與MTLLoader後呈現的對象,我從控制檯收到此錯誤:

Uncaught TypeError: Cannot read property 'toString' of undefined at WebGLPrograms.getProgramCode (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:50707) at initMaterial (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54628) at setProgram (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54820) at WebGLRenderer.renderBufferDirect (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:53883) at renderObject (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54613) at renderObjects (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54586) at WebGLRenderer.render (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:54350) at WebGlDisplay.renderScene (WebGlDisplay.jsx:86) at onClick (WebGlDisplay.jsx:90) at HTMLUnknownElement.boundFunc (modules.js?hash=eae498e3ee56e21f967b663c5bed3444c66eaef2:8794)

原因:material.onBeforeCompilegetProgramCode未定義

我的代碼如下像這樣:

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

儘量避免使用'=>'「箭頭函數」並使用更清晰明確的代碼......我不知道這個'=>'是如何精確地工作的,但是這對我來說似乎是另一個假想的彈性Javascript的語法...主要是在一個上下文中引用必須是可靠的和可靠的...我不是一個Javascript大師,但來自C/C++,這種事情給我的效果比火藥中的火柴雜誌。 – 2017-10-17 16:41:47

+0

嗯,你可以看看三個來源,看看它是否在材料上定義了'onBeforeCompile'?你確定你使用87? – pailhead

+0

是否有機會發布此代碼,以便我們可以追蹤它並查看發生了什麼?這看起來像一個錯誤,但沒有什麼突出顯而易見的。 – pailhead

回答

2

問題似乎是,三-mtl-loader NPM軟件包在它的package.json中引用了一個過時的three.js版本,所以即使你使用的是最新版本的三,插件也不是!

顯然,這不是一個可行的長期修復,但我在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://[email protected]/nascherman/three-mtl-loader.git", ... }

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'; 
相關問題