【问题标题】:ThreeJS How to use Bloom Post-Processing Without NPM in VanillaJSThreeJS 如何在 VanillaJS 中使用没有 NPM 的 Bloom 后处理
【发布时间】:2021-05-15 14:09:22
【问题描述】:

当使用ThreeJS Example 中所示的自发光贴图时,我希望我的场景具有绽放效果。

我试着稍微理解一下代码,但我基本上被卡住了。这些示例都是用 NPM 制作的,我的项目中没有使用这种方法。我确信在没有这个帮助的情况下也有可能产生绽放效果,但我很难理解这一切。

至于我已经拥有的,只是使用 StandarMeshMaterial 进行的基本设置:

scene = new THREE.Scene();
loader = new THREE.TextureLoader()
camera = new THREE.PerspectiveCamera( 47, (window.innerWidth/window.innerHeight) / (windowHeight*heightRatio), 0.01, 10000 );
renderer = new THREE.WebGLRenderer( { canvas: document.getElementById( canvasElement ), antialias: true, alpha: true } );
controls = new THREE.OrbitControls( camera, renderer.domElement );

ect..

function animate() {
    requestAnimationFrame( animate );           
    controls.update();              
    renderer.render( scene, camera );           
};  
        
ect..

我真的只是想应用一些后期处理效果,让我的发光材料看起来实际上是发光的,这不是目前发生的事情,但我就是不知道是怎么回事..

获得此结果的最简单方法是什么?

【问题讨论】:

    标签: javascript three.js post-processing bloom


    【解决方案1】:

    示例不是用 npm 制作的。

    这是下面运行的示例。唯一改变的是模块的路径和模型的 url。

    #info > * {
      max-width: 650px;
      margin-left: auto;
      margin-right: auto;
    }
    <link type="text/css" rel="stylesheet" href="https://threejs.org/examples/main.css">
    <div id="container"></div>
    
    <div id="info">
      <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Bloom pass by <a href="http://eduperiment.com" target="_blank" rel="noopener">Prashant Sharma</a> and <a href="https://clara.io" target="_blank" rel="noopener">Ben Houston</a>
      <br/>
      Model: <a href="https://blog.sketchfab.com/art-spotlight-primary-ion-drive/" target="_blank" rel="noopener">Primary Ion Drive</a> by
      <a href="http://mjmurdock.com/" target="_blank" rel="noopener">Mike Murdock</a>, CC Attribution.
    </div>
    
    <script type="module">
      import * as THREE from 'https://threejs.org/build/three.module.js';
    
      import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';
      import { GUI } from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js';
    
      import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
      import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js';
      import { EffectComposer } from 'https://threejs.org/examples/jsm/postprocessing/EffectComposer.js';
      import { RenderPass } from 'https://threejs.org/examples/jsm/postprocessing/RenderPass.js';
      import { UnrealBloomPass } from 'https://threejs.org/examples/jsm/postprocessing/UnrealBloomPass.js';
    
      let camera, stats;
      let composer, renderer, mixer, clock;
    
      const params = {
        exposure: 1,
        bloomStrength: 1.5,
        bloomThreshold: 0,
        bloomRadius: 0
      };
    
      init();
    
      function init() {
    
        const container = document.getElementById( 'container' );
    
        stats = new Stats();
        container.appendChild( stats.dom );
    
        clock = new THREE.Clock();
    
        renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.setPixelRatio( window.devicePixelRatio );
        renderer.setSize( window.innerWidth, window.innerHeight );
        renderer.toneMapping = THREE.ReinhardToneMapping;
        container.appendChild( renderer.domElement );
    
        const scene = new THREE.Scene();
    
        camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
        camera.position.set( - 5, 2.5, - 3.5 );
        scene.add( camera );
    
        const controls = new OrbitControls( camera, renderer.domElement );
        controls.maxPolarAngle = Math.PI * 0.5;
        controls.minDistance = 1;
        controls.maxDistance = 10;
    
        scene.add( new THREE.AmbientLight( 0x404040 ) );
    
        const pointLight = new THREE.PointLight( 0xffffff, 1 );
        camera.add( pointLight );
    
        const renderScene = new RenderPass( scene, camera );
    
        const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
        bloomPass.threshold = params.bloomThreshold;
        bloomPass.strength = params.bloomStrength;
        bloomPass.radius = params.bloomRadius;
    
        composer = new EffectComposer( renderer );
        composer.addPass( renderScene );
        composer.addPass( bloomPass );
    
        new GLTFLoader().load( 'https://threejs.org/examples/models/gltf/PrimaryIonDrive.glb', function ( gltf ) {
    
          const model = gltf.scene;
    
          scene.add( model );
    
          mixer = new THREE.AnimationMixer( model );
          const clip = gltf.animations[ 0 ];
          mixer.clipAction( clip.optimize() ).play();
    
          animate();
    
        } );
    
        const gui = new GUI();
    
        gui.add( params, 'exposure', 0.1, 2 ).onChange( function ( value ) {
    
          renderer.toneMappingExposure = Math.pow( value, 4.0 );
    
        } );
    
        gui.add( params, 'bloomThreshold', 0.0, 1.0 ).onChange( function ( value ) {
    
          bloomPass.threshold = Number( value );
    
        } );
    
        gui.add( params, 'bloomStrength', 0.0, 3.0 ).onChange( function ( value ) {
    
          bloomPass.strength = Number( value );
    
        } );
    
        gui.add( params, 'bloomRadius', 0.0, 1.0 ).step( 0.01 ).onChange( function ( value ) {
    
          bloomPass.radius = Number( value );
    
        } );
    
        window.addEventListener( 'resize', onWindowResize );
    
      }
    
      function onWindowResize() {
    
        const width = window.innerWidth;
        const height = window.innerHeight;
    
        camera.aspect = width / height;
        camera.updateProjectionMatrix();
    
        renderer.setSize( width, height );
        composer.setSize( width, height );
    
      }
    
      function animate() {
    
        requestAnimationFrame( animate );
    
        const delta = clock.getDelta();
    
        mixer.update( delta );
    
        stats.update();
    
        composer.render();
    
      }
    
    </script>

    您需要做的是使用&lt;script type="module"&gt; 以便modern import statements work

    然后您应该像这样将三个.js 文件复制为树

    someFolder
     |
     ├-build
     | |
     | +-three.module.js
     |
     +-examples
       |
       +-jsm
         |
         +-controls
         | |
         | +-OrbitControls.js
         | +-TrackballControls.js
         | +-...
         |
         +-loaders
         | |
         | +-GLTFLoader.js
         | +-...
         |
         ...
    

    并根据需要调整路径

    this article

    【讨论】:

    • 啊,我明白了。我一直认为import 声明的意思是,它是用 NPM 制作的,但我现在意识到我的错误。我不知道原生支持模块,这当然很棒,我一定也会尝试一下,非常感谢!
    • 我最终接受了@Brakebein 的第一个答案,因为您的答案都非常相似。但是任何尝试使用 ThreeJS 做某事的人绝对应该考虑使用 jsm 的模块化方法,而不是我做事的粗略修补方式,它会让你的项目更有条理。在我网站的未来更新中,我可能也会切换到jsm,因为它显然是更好的方法。感谢您的帮助!
    【解决方案2】:

    首先,NPM 不是一个框架。它是一个包管理器,可以安装您的项目所依赖的库,而无需手动下载脚本并将其复制到您的项目文件夹中。我从您的问题中了解到的是您不熟悉该模块方法。您想插入脚本,并且所有与three.js 相关的东西都应该在全局命名空间THREE 下可用?

    假设您已将three.js 下载到名为three 的文件夹中,您可以按如下方式导入脚本。确保从 examples/js 而不是 examples/jsm 加载脚本。

    <script src="three/build/three.min.js"></script>
    <script src="three/examples/js/controls/OrbitControls.js"></script>
    <script src="three/examples/js/loaders/GLTFLoader.js"></script>
    <script src="three/examples/js/postprocessing/EffectComposer.js"></script>
    <script src="three/examples/js/postprocessing/RenderPass.js"></script>
    <script src="three/examples/js/postprocessing/UnrealBloomPass.js"></script>
    

    现在,您可以在 THREE 命名空间下使用这些类。

    const renderScene = new THREE.RenderPass( scene, camera );
    
    const bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
    

    按照example code,删除import 语句并在缺少的地方添加THREE

    【讨论】:

    • 您好,感谢您的帮助!我知道 NPM 不是一个框架,我只是说没有框架或其他任何东西,而不仅仅是普通的 javascript。但我理解你的困惑。至于你的回答,这很有帮助。我要尽快试试这个!一旦成功,我会接受你的回答。
    • 顺便说一句。在提出这个问题之前,我试图让它工作,但我使用的是examples/jsm,也许这就是它没有成功的原因..
    • 你不应该使用 js 版本,它们已被弃用。
    • 这行得通,我仍然有问题要让绽放效果看起来不错,但至少有点效果,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-07-03
    • 2020-10-18
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 2018-09-02
    相关资源
    最近更新 更多