我正在尝试使用React服务器端呈现来使Post-processing Outline Thee.js example工作。我的主要问题是这些行(47& 280)(来自示例):
<script src="js/postprocessing/OutlinePass.js"></script>
outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), scene, camera );
composer.addPass( outlinePass );
因为我不确定如何在React中包含OutlinePass。我安装了包postprocessing
(npm profile)但它没有OutlinePass。
我也尝试在ComponentDidMount
和ComponentWillMount
中导入脚本,如下所示:
const script = document.createElement("script");
script.src = require('!!url-loader!../../../assets/webgl/js/OutlinePass.js');
script.async = true;
document.body.appendChild(script);
但它显示错误:Uncaught ReferenceError: THREE is not defined
。
我也尝试过(一次一个):
import OutlinePass from '../../../assets/webgl/js/OutlinePass.js';
const OutlinePass = require('../../../assets/webgl/js/OutlinePass.js');
const OutlinePass = require('../../../assets/webgl/js/OutlinePass.js')(THREE);
这不起作用。
我的jsx(部分):
import * as THREE from 'three';
import * as OBJLoader from 'three-obj-loader';
componentWillMount() {
const width = window.innerWidth;
const height = window.innerHeight;
this.setState({
windowW: width,
windowH: height
});
// LOAD SCRIPTS
const script = document.createElement("script");
script.src = require('!!url-loader!../../../assets/webgl/js/OutlinePass.js');
script.async = true;
document.body.appendChild(script);
}
componentDidMount() {
const { windowH, windowW } = this.state;
const { THREE } = this;
const TrackballControls = require('three-trackballcontrols');
OBJLoader(THREE);
// WINDOW RESIZE
// window.addEventListener( 'resize', onWindowResize, false );
// POST-PROCESSING
const outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), scene, camera );
// Code for this not included to clear space
this.camera = camera;
this.controls = controls;
this.scene = scene;
this.renderer = renderer;
this.mount.appendChild(this.renderer.domElement);
this.start();
}
componentWillUnmount() {
this.stop();
this.mount.removeChild(this.renderer.domElement);
}
start() {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate);
}
}
stop() {
cancelAnimationFrame(this.frameId);
}
animate() {
this.renderScene();
this.frameId = window.requestAnimationFrame(this.animate);
this.controls.update();
}
renderScene() {
this.renderer.render(this.scene, this.camera);
}
答案 0 :(得分:0)
从我所看到的代码中,您使用的是ES6模块,对于一个重要的模块,模块需要采用正确的格式,换句话说,它需要具有导出默认值....更多信息 这http://exploringjs.com/es6/ch_modules.html#sec_basics-of-es6-modules
您尝试将不符合此格式的模块重要用于您的代码,这就是您遇到问题的原因,您可以使用脚本代码并使用窗口引用代码< / p>
<script src="js/postprocessing/OutlinePass.js"></script>
然后用window.THREE.OutlinePass
引用答案 1 :(得分:0)
我做到了!问题是我试图在加载脚本之前使用THREE.OutlinePass ,所以,我添加了一个按钮来加载触发loadScene()
的场景:
componentWillMount() {
const width = window.innerWidth;
const height = window.innerHeight;
this.setState({
windowW: width,
windowH: height
});
// LOAD SCRIPTS
const scriptOP = document.createElement("script");
scriptOP.src = require('!!url-loader!../../../assets/webgl/js/OutlinePass.js');
scriptOP.async = true;
document.body.appendChild(scriptOP);
}
componentDidMount() {
const { windowH, windowW } = this.state;
const { THREE } = window;
const TrackballControls = require('three-trackballcontrols');
OBJLoader(THREE);
MTLLoader(THREE);
// CAMERA
var camera = new THREE.PerspectiveCamera( 45, windowW / windowH, 1, 10000 );
camera.position.set( 0, 0, 1 );
// camera.lookAt(scene.position);
// camera.up = new THREE.Vector3(0, 0, 1);
// CONTROLS
const controls = new TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
// SCENE
const scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );
scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
// RENDERER
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( windowW, windowH );
renderer.setClearColor('#000000');
// POST-PROCESSING
const composer = null; <- this is important
this.camera = camera;
this.controls = controls;
this.scene = scene;
this.composer = composer;
this.renderer = renderer;
this.mount.appendChild(this.renderer.domElement);
this.start();
}
renderScene() {
this.renderer.autoClear = true;
this.renderer.setClearColor( 0xfff0f0 );
this.renderer.setClearAlpha( 0.0 );
if ( this.composer ) {
this.composer.render();
} else {
this.renderer.render(this.scene, this.camera);
}
}
loadScene() {
const { THREE, innerWidth, innerHeight } = window;
// POST-PROCESSING
this.composer = new THREE.EffectComposer( this.renderer );
const renderPass = new THREE.RenderPass( this.scene, this.camera );
this.composer.addPass( renderPass );
const outlinePass = new THREE.OutlinePass( new THREE.Vector2( innerWidth, innerHeight ), this.scene, this.camera);
// LOAD OBJECT
const onProgress = xhr => {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
}
const onError = error => {
console.log("Error! ", error);
}
const loader = new THREE.OBJLoader();
loader.load( obj,
object => {
this.scene.add(object);
const tempMat = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x050505 } );
object.traverse( function( child ) {
if ( child instance of THREE.Mesh ) {
child.material = tempMat.clone();
outlinePass.selectedObjects.push( child );
}
} );
},
onProgress,
onError
);
const effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
effectFXAA.uniforms['resolution'].value.set(1 / innerWidth, 1 / innerHeight );
effectFXAA.renderToScreen = true;
this.composer.addPass( effectFXAA );
}
我希望这有助于某人!