<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          threejs做特效:實現(xiàn)物體的發(fā)光效果-EffectComposer詳解!

          共 35748字,需瀏覽 72分鐘

           ·

          2024-08-05 09:15

          點擊上方 前端Q,關注公眾號

          回復加群,加入前端Q技術交流群

          簡介與效果概覽

          各位大佬給個贊,感謝呢!

          threejs的開發(fā)中,實現(xiàn)物體發(fā)光效果是一個常見需求,比如實現(xiàn)樓體的等待照明

          要想實現(xiàn)這樣的效果,我們只需要了解一個效果合成器概念:EffectComposer。

          效果合成器能夠合成各種花里胡哨的效果,好比是一個做特效的AE,本教程,我們將使用它來實現(xiàn)一個簡單的發(fā)光效果。

          如圖,這是我們將導入的一個模型

          .

          我們要給他賦予靈魂,實現(xiàn)下面的發(fā)光效果

          順帶的,我們要實現(xiàn)物體的自動旋轉、一個簡單的性能監(jiān)視器、一個發(fā)光參數(shù)調節(jié)的面板

          技術方案

          原生html框架搭建

          借助threejs實現(xiàn)一個物體發(fā)光效果非常簡單,首先我們使用html搭建一個簡單的開發(fā)框架

          參考官方起步文檔:three.js中文網(wǎng)

          <!DOCTYPE html>
          <html lang="en">

          <head>
            <title>three.js物體發(fā)光效果</title>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
            <link type="text/css" rel="stylesheet" href="./main.css" />
            <style>
              #info>* {
                max-width650px;
                margin-left: auto;
                margin-right: auto;
              }
            
          </style>
          </head>

          <body>
            <div id="container"></div>
            <script type="importmap">
                {
                  "imports": {
                    "three""https://unpkg.com/[email protected]/build/three.module.js",
                    "three/addons/""https://unpkg.com/[email protected]/examples/jsm/"
                  }
                }
              
          </script>

            <script type="module">
              import * as THREE from "three";
              import { OrbitControls } from "three/addons/controls/OrbitControls.js";
              import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

            
          </script>
          </body>

          </html>

          上述代碼中,我們采用type="importmap"的方式引入了threejs開發(fā) 的一些核心依賴,"three"是開發(fā)的最基本依賴;在Three.js中,"addons" 通常指的是一些附加功能或擴展模塊,它們提供了額外的功能,可以用于增強或擴展Three.js的基本功能。

          type="module"中,我們引入了threejs的一些基礎依賴,OrbitControls軌道控制器和GLTFLoader模型加載器。

          實現(xiàn)模型的加載

          我們將下載好的模型放在文件根目錄

          http://www.yanhuangxueyuan.com/threejs/examples/models/gltf/PrimaryIonDrive.glb

          基于threejs的基礎知識,我們先實現(xiàn)模型的加載與渲染

          <script type="module">
          import * as THREE from "three";
          import { OrbitControls } from "three/addons/controls/OrbitControls.js";
          import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

          init()
          function init({
            const container = document.getElementById("container");

            // WebGL渲染器   
            // antialias是否執(zhí)行抗鋸齒。默認為false.
            renderer = new THREE.WebGLRenderer({ antialiastrue });
            // 設置設備像素比。通常用于避免HiDPI設備上繪圖模糊
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            // 設置色調映射  這個屬性用于在普通計算機顯示器或者移動設備屏幕等低動態(tài)范圍介質上,模擬、逼近高動態(tài)范圍(HDR)效果。
            renderer.toneMapping = THREE.ReinhardToneMapping;
            container.appendChild(renderer.domElement);

            // 創(chuàng)建新的場景對象。
            const scene = new THREE.Scene();
            // 創(chuàng)建透視相機
            camera = new THREE.PerspectiveCamera(
              40,
              window.innerWidth / window.innerHeight,
              1,
              100
            );
            camera.position.set(-52.5-3.5);
            scene.add(camera);
            // 創(chuàng)建軌道控制器
            const controls = new OrbitControls(camera, renderer.domElement);
            controls.maxPolarAngle = Math.PI * 0.5;
            controls.minDistance = 3;
            controls.maxDistance = 8;
            // 添加了一個環(huán)境光
            scene.add(new THREE.AmbientLight(0xcccccc));
            // 創(chuàng)建了一個點光源
            const pointLight = new THREE.PointLight(0xffffff100);
            camera.add(pointLight);

            // 模型加載
            new GLTFLoader().load("./PrimaryIonDrive.glb"function (gltf{
              const model = gltf.scene;
              scene.add(model);
              const clip = gltf.animations[0];
              renderer.render(scene, camera);
            });
          }
          </script>

          現(xiàn)在,我們的頁面中就有了下面的場景

          接下來,我們實現(xiàn)模型的發(fā)光效果添加。

          模型發(fā)光效果添加

          實現(xiàn)模型的發(fā)光效果,實際是EffectComposer效果合成器實現(xiàn)的。

          官方定義:用于在three.js中實現(xiàn)后期處理效果。該類管理了產(chǎn)生最終視覺效果的后期處理過程鏈。 后期處理過程根據(jù)它們添加/插入的順序來執(zhí)行,最后一個過程會被自動渲染到屏幕上。

          簡單來說,EffectComposer效果合成器只是一個工具,它可以將多種效果集成,進行渲染。我們來看一個偽代碼:

          import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";

          // 創(chuàng)建效果合成器
          composer = new EffectComposer(renderer);
          composer.addPass(發(fā)光效果);
          composer.addPass(光暈效果);
          composer.addPass(玻璃磨砂效果
                           
          // 渲染
          composer.render();

          它的實現(xiàn)過程大致如上述代碼。要實現(xiàn)發(fā)光效果,我們需要先熟悉三個Pass。

          import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
          import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
          import { OutputPass } from "three/addons/postprocessing/OutputPass.js";
          • RenderPass: 渲染通道是用于傳遞渲染結果的對象。RenderPass是EffectComposer中的一個通道,用于將場景渲染到紋理上。(固定代碼,相當于混合效果的開始)
          • UnrealBloomPass: 這是一個用于實現(xiàn)逼真的輝光效果的通道。它模擬了逼真的輝光,使得場景中的亮部分在渲染后產(chǎn)生耀眼的輝光效果。(不同效果有不同的pass)
          • OutputPass: OutputPass是EffectComposer中的一個通道,用于將最終渲染結果輸出到屏幕上。(固定代碼,相當于混合效果的結束)

          現(xiàn)在,我們完整的實現(xiàn)發(fā)光效果

            <script type="module">
              import * as THREE from "three";     

              import { OrbitControls } from "three/addons/controls/OrbitControls.js";
              import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
              import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
              import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
              import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
              import { OutputPass } from "three/addons/postprocessing/OutputPass.js";

              let camera;
              let composer, renderer;

              const params = {
                threshold0,
                strength1,
                radius0,
                exposure1,
              };

              init();

              function init({
                const container = document.getElementById("container");

                // WebGL渲染器   
                // antialias是否執(zhí)行抗鋸齒。默認為false.
                renderer = new THREE.WebGLRenderer({ antialiastrue });
                // 設置設備像素比。通常用于避免HiDPI設備上繪圖模糊
                renderer.setPixelRatio(window.devicePixelRatio);
                renderer.setSize(window.innerWidth, window.innerHeight);
                // 設置色調映射  這個屬性用于在普通計算機顯示器或者移動設備屏幕等低動態(tài)范圍介質上,模擬、逼近高動態(tài)范圍(HDR)效果。
                renderer.toneMapping = THREE.ReinhardToneMapping;
                container.appendChild(renderer.domElement);
              
                // 創(chuàng)建新的場景對象。
                const scene = new THREE.Scene();
                // 創(chuàng)建透視相機
                camera = new THREE.PerspectiveCamera(
                  40,
                  window.innerWidth / window.innerHeight,
                  1,
                  100
                );
                camera.position.set(-52.5-3.5);
                scene.add(camera);
                // 創(chuàng)建軌道控制器
                const controls = new OrbitControls(camera, renderer.domElement);
                controls.maxPolarAngle = Math.PI * 0.5;
                controls.minDistance = 3;
                controls.maxDistance = 8;
                // 添加了一個環(huán)境光
                scene.add(new THREE.AmbientLight(0xcccccc));
                // 創(chuàng)建了一個點光源
                const pointLight = new THREE.PointLight(0xffffff100);
                camera.add(pointLight);

                // 創(chuàng)建了一個RenderPass對象,用于將場景渲染到紋理上。
                const renderScene = new RenderPass(scene, camera);

                // 創(chuàng)建了一個UnrealBloomPass對象,用于實現(xiàn)輝光效果。≈
                const bloomPass = new UnrealBloomPass(
                  new THREE.Vector2(window.innerWidth, window.innerHeight),
                  1.5,
                  0.4,
                  0.85
                );
                // 設置發(fā)光參數(shù),閾值、強度和半徑。
                bloomPass.threshold = params.threshold;
                bloomPass.strength = params.strength;
                bloomPass.radius = params.radius;

                // 創(chuàng)建了一個OutputPass對象,用于將最終渲染結果輸出到屏幕上。
                const outputPass = new OutputPass();

                // 創(chuàng)建了一個EffectComposer對象,并將RenderPass、UnrealBloomPass和OutputPass添加到渲染通道中。
                composer = new EffectComposer(renderer);
                composer.addPass(renderScene);
                composer.addPass(bloomPass);
                composer.addPass(outputPass);
           
                // 模型加載
                new GLTFLoader().load("./PrimaryIonDrive.glb"function (gltf{
                  const model = gltf.scene;
                  scene.add(model);
                  const clip = gltf.animations[0];
                  animate();
                });
              }

              function animate({
                requestAnimationFrame(animate);
                // 通過調用 render 方法,將場景渲染到屏幕上。
                composer.render();
              }
            </script>

          現(xiàn)在,我們就實現(xiàn)發(fā)光的基本效果了!

          實現(xiàn)物體的自動旋轉動畫

          現(xiàn)在,我們實現(xiàn)一下物體自身的旋轉動畫

          AnimationMixer是three中的動畫合成器,使用AnimationMixer可以解析到模型中的動畫數(shù)據(jù)

          // 模型加載
          new GLTFLoader().load("./PrimaryIonDrive.glb"function (gltf{
            const model = gltf.scene;
            scene.add(model);
            //創(chuàng)建了THREE.AnimationMixer 對象,用于管理模型的動畫。
            mixer = new THREE.AnimationMixer(model);
            //從加載的glTF模型文件中獲取動畫數(shù)據(jù)。
            //這里假設模型文件包含動畫數(shù)據(jù),通過 gltf.animations[0] 獲取第一個動畫片段。
            const clip = gltf.animations[0];
            // 使用 mixer.clipAction(clip) 創(chuàng)建了一個動畫操作(AnimationAction),并立即播放該動畫
            mixer.clipAction(clip.optimize()).play();

            animate();
          });

          實現(xiàn)動畫更新

          let clock;
          clock = new THREE.Clock();

          function animate({
            requestAnimationFrame(animate);
            //使用了 clock 對象的 getDelta() 方法來獲取上一次調用后經(jīng)過的時間,即時間間隔(delta)。
            const delta = clock.getDelta();
            //根據(jù)上一次更新以來經(jīng)過的時間間隔來更新動畫。
            //這個方法會自動調整動畫的播放速度,使得動畫看起來更加平滑,不受幀率的影響
            mixer.update(delta);

            // 通過調用 render 方法,將場景渲染到屏幕上。
            composer.render();
          }

          完整代碼

          <script type="module">
          import * as THREE from "three";

          import { OrbitControls } from "three/addons/controls/OrbitControls.js";
          import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
          import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
          import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
          import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
          import { OutputPass } from "three/addons/postprocessing/OutputPass.js";

          let camera, stats;
          let composer, renderer, mixer, clock;

          const params = {
            threshold0,
            strength1,
            radius0,
            exposure1,
          };

          init();

          function init({
            const container = document.getElementById("container");

            clock = new THREE.Clock();

            // WebGL渲染器   
            // antialias是否執(zhí)行抗鋸齒。默認為false.
            renderer = new THREE.WebGLRenderer({ antialiastrue });
            // .....

            // 模型加載
            new GLTFLoader().load("./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();
            });
          }

          function animate({
            requestAnimationFrame(animate);
            const delta = clock.getDelta();
            mixer.update(delta);
            // 通過調用 render 方法,將場景渲染到屏幕上。
            composer.render();
          }
          </script>

          優(yōu)化屏幕縮放邏輯

          init{
            // ....

            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);
          }

          添加參數(shù)調節(jié)面板

          在Three.js中,GUI是一個用于創(chuàng)建用戶界面(UI)控件的庫。具體來說,GUI庫允許你在Three.js應用程序中創(chuàng)建交互式的圖形用戶界面元素,例如滑塊、復選框、按鈕等,這些元素可以用于控制場景中的對象、相機、光源等參數(shù)。

          我們借助這個工具實現(xiàn)如下發(fā)光效果調試面板

          import { GUI } from "three/addons/libs/lil-gui.module.min.js";


          init{
            // ....

          // 創(chuàng)建一個GUI實例
          const gui = new GUI();

          // 創(chuàng)建一個名為"bloom"的文件夾,用于容納調整泛光效果的參數(shù)
          const bloomFolder = gui.addFolder("bloom");

          // 在"bloom"文件夾中添加一個滑塊控件,用于調整泛光效果的閾值參數(shù)
          bloomFolder
            .add(params, "threshold"0.01.0)
            .onChange(function (value{
              bloomPass.threshold = Number(value);
            });

          // 在"bloom"文件夾中添加另一個滑塊控件,用于調整泛光效果的強度參數(shù)
          bloomFolder
            .add(params, "strength"0.03.0)
            .onChange(function (value{
              bloomPass.strength = Number(value);
            });

          // 在根容器中添加一個滑塊控件,用于調整泛光效果的半徑參數(shù)
          gui
            .add(params, "radius"0.01.0)
            .step(0.01)
            .onChange(function (value{
              bloomPass.radius = Number(value);
            });

          // 創(chuàng)建一個名為"tone mapping"的文件夾,用于容納調整色調映射效果的參數(shù)
          const toneMappingFolder = gui.addFolder("tone mapping");

          // 在"tone mapping"文件夾中添加一個滑塊控件,用于調整曝光度參數(shù)
          toneMappingFolder
            .add(params, "exposure"0.12)
            .onChange(function (value{
              renderer.toneMappingExposure = Math.pow(value, 4.0);
            });
            
          window.addEventListener("resize", onWindowResize);
          }

          添加性能監(jiān)視器

          import Stats from "three/addons/libs/stats.module.js";

          init{
            stats = new Stats();
            container.appendChild(stats.dom);
            // ...
          }

          function animate({
            requestAnimationFrame(animate);
            const delta = clock.getDelta();
            mixer.update(delta);

            stats.update();
            // 通過調用 render 方法,將場景渲染到屏幕上。
            composer.render();
          }

          在Three.js中,Stats是一個性能監(jiān)視器,用于跟蹤幀速率(FPS)、內存使用量和渲染時間等信息。

          完整demo代碼

          html

          <!DOCTYPE html>
          <html lang="en">

          <head>
            <title>three.js物體發(fā)光效果</title>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
            <link type="text/css" rel="stylesheet" href="./main.css" />
            <style>
              #info>* {
                max-width650px;
                margin-left: auto;
                margin-right: auto;
              }
            
          </style>
          </head>

          <body>
            <div id="container"></div>
            <script type="importmap">
                {
                  "imports": {
                    "three""https://unpkg.com/[email protected]/build/three.module.js",
                    "three/addons/""https://unpkg.com/[email protected]/examples/jsm/"
                  }
                }
              
          </script>

            <script type="module">
              import * as THREE from "three";

              import Stats from "three/addons/libs/stats.module.js";
              import { GUI } from "three/addons/libs/lil-gui.module.min.js";

              import { OrbitControls } from "three/addons/controls/OrbitControls.js";
              import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
              import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
              import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
              import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
              import { OutputPass } from "three/addons/postprocessing/OutputPass.js";

              let camera, stats;
              let composer, renderer, mixer, clock;

              const params = {
                threshold0,
                strength1,
                radius0,
                exposure1,
              };

              init();

              function init({
                const container = document.getElementById("container");

                stats = new Stats();
                container.appendChild(stats.dom);

                clock = new THREE.Clock();

                // WebGL渲染器   
                // antialias是否執(zhí)行抗鋸齒。默認為false.
                renderer = new THREE.WebGLRenderer({ antialiastrue });
                // 設置設備像素比。通常用于避免HiDPI設備上繪圖模糊
                renderer.setPixelRatio(window.devicePixelRatio);
                renderer.setSize(window.innerWidth, window.innerHeight);
                // 設置色調映射  這個屬性用于在普通計算機顯示器或者移動設備屏幕等低動態(tài)范圍介質上,模擬、逼近高動態(tài)范圍(HDR)效果。
                renderer.toneMapping = THREE.ReinhardToneMapping;
                container.appendChild(renderer.domElement);
              
                // 創(chuàng)建新的場景對象。
                const scene = new THREE.Scene();
                // 創(chuàng)建透視相機
                camera = new THREE.PerspectiveCamera(
                  40,
                  window.innerWidth / window.innerHeight,
                  1,
                  100
                );
                camera.position.set(-52.5-3.5);
                scene.add(camera);
                // 創(chuàng)建軌道控制器
                const controls = new OrbitControls(camera, renderer.domElement);
                controls.maxPolarAngle = Math.PI * 0.5;
                controls.minDistance = 3;
                controls.maxDistance = 8;
                // 添加了一個環(huán)境光
                scene.add(new THREE.AmbientLight(0xcccccc));
                // 創(chuàng)建了一個點光源
                const pointLight = new THREE.PointLight(0xffffff100);
                camera.add(pointLight);

                // 創(chuàng)建了一個RenderPass對象,用于將場景渲染到紋理上。
                const renderScene = new RenderPass(scene, camera);

                // 創(chuàng)建了一個UnrealBloomPass對象,用于實現(xiàn)輝光效果。≈
                const bloomPass = new UnrealBloomPass(
                  new THREE.Vector2(window.innerWidth, window.innerHeight),
                  1.5,
                  0.4,
                  0.85
                );
                // 設置發(fā)光參數(shù),閾值、強度和半徑。
                bloomPass.threshold = params.threshold;
                bloomPass.strength = params.strength;
                bloomPass.radius = params.radius;

                // 創(chuàng)建了一個OutputPass對象,用于將最終渲染結果輸出到屏幕上。
                const outputPass = new OutputPass();

                // 創(chuàng)建了一個EffectComposer對象,并將RenderPass、UnrealBloomPass和OutputPass添加到渲染通道中。
                composer = new EffectComposer(renderer);
                composer.addPass(renderScene);
                composer.addPass(bloomPass);
                composer.addPass(outputPass);
           
                // 模型加載
                new GLTFLoader().load("./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();

                const bloomFolder = gui.addFolder("bloom");

                bloomFolder
                  .add(params, "threshold"0.01.0)
                  .onChange(function (value{
                    bloomPass.threshold = Number(value);
                  });

                bloomFolder
                  .add(params, "strength"0.03.0)
                  .onChange(function (value{
                    bloomPass.strength = Number(value);
                  });

                gui
                  .add(params, "radius"0.01.0)
                  .step(0.01)
                  .onChange(function (value{
                    bloomPass.radius = Number(value);
                  });

                const toneMappingFolder = gui.addFolder("tone mapping");

                toneMappingFolder
                  .add(params, "exposure"0.12)
                  .onChange(function (value{
                    renderer.toneMappingExposure = Math.pow(value, 4.0);
                  });

                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();
                // 通過調用 render 方法,將場景渲染到屏幕上。
                composer.render();
              }
            
          </script>
          </body>

          </html>

          main.css

          body {
           margin0;
           background-color#000;
           color#fff;
           font-family: Monospace;
           font-size13px;
           line-height24px;
           overscroll-behavior: none;
          }

          a {
           color#ff0;
           text-decoration: none;
          }

          a:hover {
           text-decoration: underline;
          }

          button {
           cursor: pointer;
           text-transform: uppercase;
          }

          #info {
           position: absolute;
           top0px;
           width100%;
           padding10px;
           box-sizing: border-box;
           text-align: center;
           -moz-user-select: none;
           -webkit-user-select: none;
           -ms-user-select: none;
           user-select: none;
           pointer-events: none;
           z-index1/* TODO Solve this in HTML */
          }

          abuttoninputselect {
           pointer-events: auto;
          }

          .lil-gui {
           z-index2 !important/* TODO Solve this in HTML */
          }

          @media all and ( max-width: 640px ) {
           .lil-gui.root { 
            right: auto;
            top: auto;
            max-height50%;
            max-width80%;
            bottom0;
            left0;
           }
          }

          #overlay {
           position: absolute;
           font-size16px;
           z-index2;
           top0;
           left0;
           width100%;
           height100%;
           display: flex;
           align-items: center;
           justify-content: center;
           flex-direction: column;
           backgroundrgba(0,0,0,0.7);
          }

           #overlay button {
            background: transparent;
            border0;
            border1px solid rgb(255255255);
            border-radius4px;
            color#ffffff;
            padding12px 18px;
            text-transform: uppercase;
            cursor: pointer;
           }

          #notSupported {
           width50%;
           margin: auto;
           background-color#f00;
           margin-top20px;
           padding10px;
          }

          總結

          通過本教程,我想現(xiàn)在你對效果合成器一定有了更深入的了解,現(xiàn)在,我們在看看官網(wǎng)的定義:

          用于在three.js中實現(xiàn)后期處理效果。該類管理了產(chǎn)生最終視覺效果的后期處理過程鏈。 后期處理過程根據(jù)它們添加/插入的順序來執(zhí)行,最后一個過程會被自動渲染到屏幕上

          結合代碼,我想現(xiàn)在理解其它非常容易

          <script type="module">
              import * as THREE from "three";     

              import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
              import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
              import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
              import { OutputPass } from "three/addons/postprocessing/OutputPass.js";

              function init({
                // 1【渲染開始】創(chuàng)建了一個RenderPass對象,用于將場景渲染到紋理上。
                const renderScene = new RenderPass(scene, camera);

                // 2【需要合成的中間特效】創(chuàng)建了一個UnrealBloomPass對象,用于實現(xiàn)輝光效果。≈
                const bloomPass = new UnrealBloomPass(
                  new THREE.Vector2(window.innerWidth, window.innerHeight),
                  1.5,
                  0.4,
                  0.85
                );
                // 【特效設置】設置發(fā)光參數(shù),閾值、強度和半徑。
                bloomPass.threshold = params.threshold;
                bloomPass.strength = params.strength;
                bloomPass.radius = params.radius;

                // 3【效果輸出】創(chuàng)建了一個OutputPass對象,用于將最終渲染結果輸出到屏幕上。
                const outputPass = new OutputPass();

                // 4【特效合并】創(chuàng)建了一個EffectComposer對象,并將RenderPass、UnrealBloomPass和OutputPass添加到渲染通道中。
                composer = new EffectComposer(renderer);
                composer.addPass(renderScene);
                composer.addPass(bloomPass);
                composer.addPass(outputPass);
              }

              function animate({
                requestAnimationFrame(animate);
                // 5【渲染特效】通過調用 render 方法,將場景渲染到屏幕上。
                composer.render();
              }
            </script>


          往期推薦


          源碼視角,Vue3為什么推薦使用ref而不是reactive
          幾行代碼,優(yōu)雅的避免接口重復請求!同事都說好!
          某一線前端小組長的 Code Review 分享

          最后


          • 歡迎加我微信,拉你進技術群,長期交流學習...

          • 歡迎關注「前端Q」,認真學前端,做個專業(yè)的技術人...

          點個在看支持我吧

          瀏覽 220
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产成人久久精品77777综合 | 激情综合网在线观看 | 亚洲无码婷婷国产 | 一区二区视频在线播放 | AA久久a|