three.js后期处理-使用UnrealBloomPass通道在场景中添加泛光效果,三维物体表面发光效果(vue中使用three.js85)

1.demo效果

在这里插入图片描述
在这里插入图片描述

2. 重要知识点

2.1 回顾要点

上一篇文章中我们介绍了如何使用后期处理,同时也介绍了几个简单的后期处理通道:FilmPass(类似电视效果)、DotScreenPass(将场景输出成点集)、GlitchPass(电磁风暴效果)
这里在回顾一下使用后期处理的步骤

  1. 创建效果组合器
    使用 EffectComposer 类创建一个效果组合器实例,之后就可以向这个实例中添加各种后期处理通道

  2. 添加通道
    有了上一步创建的效果组合器,这里要添加各种需要的后期处理通道,renderPass 通道 必须要添加上,然后添加各种需要的处理通道,包括可以使用自定义的Shader创建高级的后期处理的ShaderPass 通道

  3. 更新通道
    在render循环中,调用效果组合器的render函数,效果组合器会依次使用添加的处理通道来处理场景将最终的结果输出

2.2 UnrealBloomPass通道介绍

UnrealBloomPass通道可以在场景的物体中产生泛光效果,使得场景中明亮区域变得更显著,比较暗的区域也会变得稍亮。
创建UnrealBloomPass对象需要输入四个参数,具体如下

  • resolution:表示泛光所覆盖的场景大小,是Vector2类型的向量
  • strength:表示泛光的强度,值越大明亮的区域越亮,较暗区域变亮的范围越广
  • radius:表示泛光散发的半径
  • threshold:表示产生泛光的光照强度阈值,如果照在物体上的光照强度大于该值就会产生泛光

3. 实现要点

3.1 相关文件引入

这里要引入三个文件,EffectComposer 效果组合器, RenderPass 处理通道,以及demo中产生泛光效果的 UnrealBloomPass 泛光通道

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

3.2 创建效果组合器并添加通道

createComposer() {
  //使用场景和相机创建RenderPass通道
  const renderPass = new RenderPass(this.scene, this.camera)

  //创建UnrealBloomPass泛光通道
  this.unrealBloomPass = new UnrealBloomPass(
    new THREE.Vector2(256, 256),
    1,
    1.1,
    0.18
  )
  this.unrealBloomPass.renderToScreen = true

  //创建效果组合器
  this.composer = new EffectComposer(this.renderer)

  //将创建的通道添加到EffectComposer(效果组合器)对象中
  this.composer.addPass(renderPass)
  this.composer.addPass(this.unrealBloomPass)
}

3.3 render中更新效果组合器

render() {
  const delta = this.clock.getDelta() // 获取自上次调用的时间差
  this.orbitControls.update(delta) // 相机控制更新

  this.renderer.render(this.scene, this.camera)

  /********** 更新效果组合器一定要在渲染器更新后,否则通道无法产生效果************/
  this.composer.render(delta) //效果组合器更新

  requestAnimationFrame(this.render)
}

4. demo代码

<template>
  <div id="container" />
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'

export default {
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      orbitControls: null,
      clock: null,
      composer: null,
      unrealBloomPass: null
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.createScene() // 创建场景
      this.createModels() // 创建模型
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.createComposer()
      this.render() // 渲染
    },
    // 创建场景
    createScene() {
      this.scene = new THREE.Scene()
    },
    createCube() {
      const cubeSize = Math.ceil(Math.random() * 3)
      const cubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize)
      const material = new THREE.MeshLambertMaterial({
        color: Math.random() * 0xffffff
      })
      const cube = new THREE.Mesh(cubeGeometry, material)

      // 给方块设置随机坐标
      cube.position.x = -30 + Math.round(Math.random() * 60)
      cube.position.y = Math.round(Math.random() * 5)
      cube.position.z = -20 + Math.round(Math.random() * 40)
      // 将生成的方块添加到场景
      this.scene.add(cube)
    },
    createSphere() {
      const sphereSize = Math.ceil(Math.random() * 1)
      const sphereGeometry = new THREE.SphereGeometry(sphereSize, 50, 50)
      const material = new THREE.MeshLambertMaterial({
        color: Math.random() * 0xffffff
      })
      const mesh = new THREE.Mesh(sphereGeometry, material)

      // 设置随机坐标
      mesh.position.x = -30 + Math.round(Math.random() * 60)
      mesh.position.y = Math.round(Math.random() * 5)
      mesh.position.z = -20 + Math.round(Math.random() * 40)
      // 将生成的球添加到场景
      this.scene.add(mesh)
    },
    // 创建模型
    createModels() {
      for (let i = 0; i < 10; i++) {
        this.createCube()
        this.createSphere()
      }
    },

    // 创建光源
    createLight() {
      // 环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.3) // 创建环境光
      this.scene.add(ambientLight) // 将环境光添加到场景

      const directionLight = new THREE.DirectionalLight(0xffffff)
      directionLight.position.set(550, 100, 550)
      directionLight.intensity = 0.8
      this.scene.add(directionLight)
    },
    // 创建相机
    createCamera() {
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
      this.camera.position.set(30, 30, 30) // 设置相机位置

      this.camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向
    },
    // 创建渲染器
    createRender() {
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      this.renderer.shadowMap.enabled = true // 显示阴影
      this.renderer.setClearColor(0x000000, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },

    createComposer() {
      //使用场景和相机创建RenderPass通道
      const renderPass = new RenderPass(this.scene, this.camera)

      //创建UnrealBloomPass泛光通道
      this.unrealBloomPass = new UnrealBloomPass(
        new THREE.Vector2(256, 256),
        1,
        1.1,
        0.18
      )
      this.unrealBloomPass.renderToScreen = true

      //创建效果组合器
      this.composer = new EffectComposer(this.renderer)

      //将创建的通道添加到EffectComposer(效果组合器)对象中
      this.composer.addPass(renderPass)
      this.composer.addPass(this.unrealBloomPass)
    },

    render() {
      const delta = this.clock.getDelta() // 获取自上次调用的时间差
      this.orbitControls.update(delta) // 相机控制更新

      this.renderer.render(this.scene, this.camera)

      /********** 更新效果组合器一定要在渲染器更新后,否则通道无法产生效果************/
      this.composer.render(delta) //效果组合器更新

      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls() {
      this.clock = new THREE.Clock() // 创建THREE.Clock对象,用于计算上次调用经过的时间
      this.orbitControls = new OrbitControls(
        this.camera,
        this.renderer.domElement
      )
    }
  }
}
</script>

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

可以使用Three.js提供的SphereGeometry和MeshPhongMaterial创建一个具有光泽感的球体。以下是一个示例代码: ``` <template> <div id="container"></div> </template> <script> import * as THREE from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' export default { mounted() { const container = document.getElementById('container') const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera( 75, container.clientWidth / container.clientHeight, 0.1, 1000 ) camera.position.z = 5 const renderer = new THREE.WebGLRenderer() renderer.setSize(container.clientWidth, container.clientHeight) container.appendChild(renderer.domElement) const controls = new OrbitControls(camera, renderer.domElement) const sphereGeometry = new THREE.SphereGeometry(1, 32, 32) const sphereMaterial = new THREE.MeshPhongMaterial({ color: 0xffffff, specular: 0x222222, shininess: 25 }) const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial) scene.add(sphere) const ambientLight = new THREE.AmbientLight(0x404040) scene.add(ambientLight) const pointLight = new THREE.PointLight(0xffffff, 1, 100) pointLight.position.set(10, 10, 10) scene.add(pointLight) const animate = function () { requestAnimationFrame(animate) sphere.rotation.x += 0.01 sphere.rotation.y += 0.01 renderer.render(scene, camera) } animate() } } </script> ``` 这个代码在Vue.js项目使用Three.js创建了一个带有OrbitControls(鼠标交互控制)的场景。可以根据需要修改球体的大小、材质等属性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值