文章数量
36
访客量
4952
访问量
9817

threejs使用outlinePass实现呼吸灯效果

阅读量:1380
更新时间:2023-02-05 19:54:02

效果预览:效果预览
源码下载:关注公众号【RMRF】,回复【three3】可获取源码

一、安装

npm install three

二、App.vue

<template>
  <div class="breathingLamp">
    <div id="container"></div>
  </div>
</template>
<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';

export default {
  data() {
    return {
      scene: null, // 场景
      camera: null, // 相机
      renderer: null, // 初始渲染
      composer: null,
      cube: null
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    // 初始化
    init() {
      const el = document.getElementById('container');
      this.initScene();
      this.initCamera();
      this.initRenderer(el);
      this.initCube();
      this.initOutlinePass();
      this.initOrbitControls();
      this.render();
      this.requestAnimationFrame();
    },
    // 场景
    initScene() {
      this.scene = new THREE.Scene();
      this.scene.background = new THREE.Color('#000000');
    },
    // 相机
    initCamera() {
      this.camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        1000
      );
      this.camera.position.set(2, 5, 2);
    },
    // 渲染器
    initRenderer(el) {
      this.renderer = new THREE.WebGLRenderer({
        antialias: true
      });
      this.renderer.setPixelRatio(window.devicePixelRatio)

      this.renderer.setSize(window.innerWidth, window.innerHeight);
      el.appendChild(this.renderer.domElement);
    },
    // 立方体
    initCube() {
      const geometry = new THREE.BoxGeometry(2, 2, 2);
      const material = new THREE.MeshBasicMaterial({ color: 0x00ffff });
      this.cube = new THREE.Mesh(geometry, material);
      this.scene.add(this.cube);
      this.camera.position.z = 5;
    },
    // 呼吸光
    initOutlinePass() {
      let renderScene = new RenderPass(this.scene, this.camera);
      let outlinePass = new OutlinePass(
        new THREE.Vector2(window.innerWidth, window.innerHeight),
        this.scene,
        this.camera,
        [this.cube]
      );
      // 将此通道结果渲染到屏幕
      outlinePass.renderToScreen = true
      outlinePass.edgeGlow = 1 // 发光强度
      outlinePass.usePatternTexture = false // 是否使用纹理图案
      outlinePass.edgeThickness = 2 // 边缘浓度
      outlinePass.edgeStrength = 5 // 边缘的强度,值越高边框范围越大
      outlinePass.pulsePeriod = 2// 闪烁频率,值越大频率越低
      outlinePass.visibleEdgeColor.set('#ffff00') // 呼吸显示的颜色
      outlinePass.hiddenEdgeColor.set('#ff0000') // 不可见边缘的颜色
      // 将通道加入组合器
      this.composer = new EffectComposer(this.renderer);
      this.composer.addPass(renderScene);
      this.composer.addPass(outlinePass);
    },
    // 缩放
    initOrbitControls() {
      let controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.maxDistance = 10;
      controls.addEventListener('change', this.render);
    },
    requestAnimationFrame() {
      this.composer.render();
      requestAnimationFrame(this.requestAnimationFrame);
    },
    // 渲染
    render() {
      this.renderer.render(this.scene, this.camera);
    }
  }
};
</script>