three.js實現分模塊添加夢幻bloom輝光光暈方案--詳細注釋版本~~方案三版本~~


先上圖對比方案1-2-3不同點,本文是方案3

方案1(旋轉場景情況下發光體不應該遮住另一個,但是遮住了)

方案2(層次正常,發光正常)

方案3(層次正常,發光正常,但是轉動場景時候部分輝光會被遮擋,但是還算OK)

上代碼,與方案1代碼只有兩行是不一樣的哦

<!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>bloomPass</title>
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }

    #container {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <div id="container"></div>
  <button onclick="getC()" style="position: absolute; top: 50px;">getC</button>
  <!-- <script src="js/three.min.js"></script> -->
  <script src="js/tween.js"></script>
  <!-- <script src="js/stats.min.js"></script> -->
  <!-- <script src="js/OrbitControls.js"></script> -->
  <!-- 后期處理js -->
  <!--  -->
  <!-- <script src="js/shaders/ConvolutionShader.js"></script> -->
  <!-- <script> -->
  <script type="module">
    import * as THREE from '../build/three.module.js';
    import Stats from './jsm/libs/stats.module.js';
    import { GUI } from './jsm/libs/dat.gui.module.js';
    import { OrbitControls } from './jsm/controls/OrbitControls.js';
    import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; // EffectComposer(效果組合器)對象
    import { RenderPass } from './jsm/postprocessing/RenderPass.js'; // RenderPass/該通道在指定的場景和相機的基礎上渲染出一個新場景
    import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; // ShaderPass/使用該通道你可以傳入一個自定義的着色器,用來生成高級的、自定義的后期處理通道
    import { CopyShader } from './jsm/shaders/CopyShader.js'; // 傳入了CopyShader着色器,用於拷貝渲染結果
    import { BloomPass } from './jsm/postprocessing/BloomPass.js';
    import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js'; // BloomPass/形成泛光的效果
    // 需要用官方版本的tween.js
    let container = document.getElementById('container');
    let camera, scene, renderer;
    let cubeGroup, labelGroup = [];
    let stats, controls;
    let renderOrder = 1
		let bloomPass
    var params = {
			exposure: 1,
			bloomStrength: 1.5,
			bloomThreshold: 0,
			bloomRadius: 0
		};
    let bloomComposer = null
    init();
    update();
    function init() {
      // scene
      scene = new THREE.Scene();
      // camera
      let frustumSize = 150;
      let aspect = container.clientWidth / container.clientHeight;
      camera = new THREE.PerspectiveCamera(
        45,
        window.innerWidth / window.innerHeight,
        1,
        50000
      )
      camera.position.set(306, 1126, 7976);
      camera.lookAt(new THREE.Vector3(0, 0, 0));
      var ambientLight = new THREE.AmbientLight('#ffffff', 0.7) // offline
      scene.add(ambientLight)
      // renderer
      renderer = new THREE.WebGLRenderer();
      renderer.autoClear = false
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setPixelRatio(window.devicePixelRatio);
      container.appendChild(renderer.domElement);
      renderer.render(scene, camera);
      addCubes()
      addBloomPass()
      stats = new Stats();
      container.appendChild(stats.dom);
      controls = new OrbitControls(camera, renderer.domElement);
      window.addEventListener('resize', onWindowResize, false);
    }
    function update() {
      // controls.update();
      stats.update();
      // 渲染器清除顏色、深度或模板緩存. 此方法將顏色緩存初始化為當前顏色
      renderer.clear()
      camera.layers.set(1)
      if (bloomComposer) { bloomComposer.render() }
      // 清除深度緩存
      renderer.clearDepth()
      camera.layers.set(0)
      renderer.render(scene, camera)
      requestAnimationFrame(update);
    }
    function getC() {
      console.log(camera)
    }
    function onWindowResize() {
      let frustumSize = 200;
      let aspect = container.clientWidth / container.clientHeight;
      camera.left = frustumSize * aspect / -2;
      camera.right = frustumSize * aspect / 2;
      camera.top = frustumSize / 2;
      camera.bottom = frustumSize / -2;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }
    
    function addBloomPass() {
      // RenderPass這個通道會渲染場景,但不會將渲染結果輸出到屏幕上
      const renderScene = new RenderPass(scene, camera)
      const effectCopy = new ShaderPass(CopyShader); //傳入了CopyShader着色器,用於拷貝渲染結果
      effectCopy.renderToScreen = true;
      // THREE.BloomPass(strength, kernelSize, sigma, Resolution)
      // strength 定義泛光效果的強度,值越高,明亮的區域越明亮,而且滲入較暗區域的也就越多
      // kernelSize 控制泛光的偏移量
      // sigma 控制泛光的銳利程度,值越高,泛光越模糊
      // Resolution 定義泛光的解析圖,如果該值太低,結果的方塊化就會越嚴重
      // const bloomPass = new BloomPass(2, 25, 4.0, 256); //BloomPass通道效果
      //創建效果組合器對象,可以在該對象上添加后期處理通道,通過配置該對象,使它可以渲染我們的場景,並應用額外的后期處理步驟,在render循環中,使用EffectComposer渲染場景、應用通道,並輸出結果。
      bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4,
				0.85);
			bloomPass.renderToScreen = true;
			bloomPass.threshold = params.bloomThreshold;
			bloomPass.strength = params.bloomStrength;
			bloomPass.radius = params.bloomRadius;
      
      bloomComposer = new EffectComposer(renderer)
      bloomComposer.setSize(window.innerWidth, window.innerHeight);
      bloomComposer.addPass(renderScene);
      bloomComposer.addPass(bloomPass);
      bloomComposer.addPass(effectCopy);
      bloomComposer.render()
    }
    function addCubes() {
      // 創建兩個box, 將box進行layers進行分層是重要代碼,camera默認渲染0層
      let texture = new THREE.TextureLoader().load("./img/backav9.jpg")
      let texture1 = new THREE.TextureLoader().load("./img/py.png")
      var geometry1 = new THREE.BoxGeometry(400, 400, 400);
      var material1 = new THREE.MeshBasicMaterial({
        map: texture
      });
      var cube1 = new THREE.Mesh(geometry1, material1);
      // 重要代碼,將當前創建的box分配到0層
      // cube1.layers.set(1) // 和方案一僅僅只有這里不同
			cube1.layers.enable(1); // 分層
      cube1.position.set(1200, 0, 0)
      scene.add(cube1);
      var geometry2 = new THREE.BoxGeometry(400, 400, 400);
      var material2 = new THREE.MeshBasicMaterial({
        map: texture1
      });
      var cube2 = new THREE.Mesh(geometry2, material2);
      // 重要代碼,將當前創建的box分配到1層
      // cube2.layers.set(0) // 和方案一僅僅只有這里不同
			cube2.layers.enable(0); // 分層
      cube2.position.set(600, 0, 0)
      scene.add(cube2);
    }
    function initGui() {
      var 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);
			});
		}
    initGui()
  </script>
</body>

</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM