后处理导入问题threejs + reactjs

问题描述

我花了多个小时试图解决这个问题。基本上,我将Threejs场景格式化为react组件(这意味着场景的初始化是在ComponentDidMount()中完成的,动画功能和调整大小均绑定到“ this”。场景本身被渲染到画布中,并由网页使用​​)作为一个组件。)

我认为我遇到的主要问题是打字稿导入。尝试导入后处理模块时遇到各种错误。 这是我尝试过的: (这些错误是在我从npm安装了官方的三个软件包和后处理软件包之后发生的)

1:Three.js的官方文档 (我只是从导入中获得了错误,这意味着在尝试使用导入时出现了更多的错误

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/examples/jsm/postprocessing/GlitchPass.js';

这产生了:

Module not found: Can't resolve 'three/examples/jsm/postprocessing/EffectComposer.js' in 'C:\Users\Jan\Documents\GitHub\mm\src\components'

所以我尝试使用节点模块文件夹中的相对路径(没有webpack)

2:使用相对路径:

import { EffectComposer } from "../../node_modules/three/examples/js/postprocessing/EffectComposer.js";
import { RenderPass } from "../../node_modules/three/examples/js/postprocessing/RenderPass.js";
import { GlitchPass } from "../../node_modules/three/examples/js/postprocessing/GlitchPass.js";

这很好地导入了,所以我尝试在官方threejs网站上的简单用例中使用导入。 (这是在所有其他初始化之后):

var composer = new EffectComposer(renderer);
var renderPass = new RenderPass(scene,camera);
composer.addPass(renderPass);

不幸的是,我得到了这个错误(我认为是打字稿/香草问题,但我可能是错的):

ReferenceError: THREE is not defined
./node_modules/three/examples/js/postprocessing/EffectComposer.js
C:/Users/Simon/Documents/GitHub/mm/node_modules/three/examples/js/postprocessing/EffectComposer.js:4
  1 | /**
  2 |  * @author alteredq / http://alteredqualia.com/
  3 |  */
> 4 | THREE.EffectComposer = function (renderer,rendertarget) {
  5 |   this.renderer = renderer;
  6 | 
  7 |   if (rendertarget === undefined) {

最后,我尝试以导入threejs的相同方式来导入npm模块后处理:

3:从后处理中导入后处理:

import * as THREE from "three"; //how i usually import three
import * as POSTPROCESSING from "postprocessing";

这会产生此错误(注意:我不在代码中的任何地方使用LinearMipmapLinearFilter):

./node_modules/postprocessing/build/postprocessing.esm.js
Attempted import error: 'LinearMipmapLinearFilter' is not exported from 'three'.

4:我还尝试将postprocessing.min.js文件放在我的根文件夹中并从那里加载,但这给了我成千上万个错误,因为三个错误从未导入其中。

任何建议或示例将不胜感激。有没有一种解决方法,还是应该修改这三个程序包以使“ 2:使用相对路径”起作用?我是在做完全错误的事情吗?谢谢。

类似问题: https://discourse.threejs.org/t/shaderpass-post-processing-in-effectcomposer-removes-alpha-channel-of-objects-in-the-scene/9481/7

供参考,这是我的整个ComponentDidMount函数

  componentDidMount() {
    const width = this.mount.clientWidth;
    const height = this.mount.clientHeight;
    const scene = new THREE.Scene();
    scene.fog = new THREE.FogExp2(0x03544e,0.001);
    const camera = new THREE.PerspectiveCamera(75,width / height,0.1,2000);
    counter = 0;
    camera.position.z = 100;

    const renderer = new THREE.Webglrenderer({ antialias: true,alpha: true });
    var stColor = new THREE.Color("hsl(201.6,50%,50%)");
    renderer.setClearColor(0x111111);
    var orangeLight = new THREE.PointLight(stColor,50,450,2);
    orangeLight.position.set(200,300,100);
    scene.add(orangeLight);
    var redLight = new THREE.PointLight(stColor,2);
    redLight.position.set(100,100);
    scene.add(redLight);
    var blueLight = new THREE.PointLight(stColor,6);
    blueLight.position.set(0,300);
    scene.add(blueLight);
    var greenLight = new THREE.PointLight(stColor,2);
    greenLight.position.set(200,-300);
    scene.add(greenLight);
    var cloudParticles = [];
    let loader = new THREE.TextureLoader();
    loader.load(smokeTex,function (texture) {
      var cloudGeo = new THREE.PlaneBufferGeometry(500,500);
      var cloudMaterial = new THREE.MeshLAmbertMaterial({
        map: texture,transparent: true,depthWrite: false,size: 0.2,});

      for (let p = 0; p < 40; p++) {
        let cloud = new THREE.Mesh(cloudGeo,cloudMaterial);
        cloud.position.set(
          Math.random() * 600 - 300,Math.random() * 300 - 600
        );
        cloud.rotation.x = 0.02;
        cloud.rotation.z = Math.random() * 2 * Math.PI;
        cloud.material.opacity = 0.55;
        cloudParticles.push(cloud);
        scene.add(cloud);
      }
    });
    var tubePoints = [];

    var incrm = 0;
    for (var i = 0; i < 5; i += 1) {
      var xC = 4 - i;
      incrm = xC * xC - xC;
      tubePoints.push(new THREE.Vector3(0,incrm / 3,3 * (i / 4)));
    }

    var curve = new THREE.CatmullRomCurve3(tubePoints);
    curve.type = "catmullrom";

    var tubeGeo = new THREE.Geometry();
    tubeGeo.vertices = curve.getPoints(70);
    var tubeTex = loader.load(gal,function (tubeTex) {
      tubeTex.wrapS = THREE.MirroredRepeatWrapping;
      tubeTex.wrapT = THREE.MirroredRepeatWrapping;
      tubeTex.repeat.set(2,2);
    });
    var tubeMaterial = new THREE.MeshBasicMaterial({
      side: THREE.BackSide,map: tubeTex,opacity: 1,});
    var tubeGeometry = new THREE.TubeGeometry(curve,70,0.3,30,false);
    tubeGeometry.verticesNeedUpdate = true;
    tubeGeometry.dynamic = true;
    var tubeMesh = new THREE.Mesh(tubeGeometry,tubeMaterial);
    scene.add(tubeMesh);
    tubeMesh.position.z = 96.9;
    scene.add(tubeMesh);
    var speedMat = -0.001;
    // var composer = new EffectComposer(renderer);
    // var renderPass = new RenderPass(scene,camera);
    // composer.addPass(renderPass);
    // var glitchPass = new GlitchPass();
    // composer.addPass(glitchPass);
    this.speedMat = speedMat;
    this.tubeMesh = tubeMesh;
    this.scene = scene;
    this.camera = camera;
    this.tubeGeometry = tubeGeometry;
    this.cloudParticles = cloudParticles;
    this.tubeMaterial = tubeMaterial;
    this.renderer = renderer;
    this.blueLight = blueLight;
    this.redLight = redLight;
    this.orangeLight = orangeLight;
    this.greenLight = greenLight;
    this.mount.appendChild(this.renderer.domElement);
    this.start();

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)