three.js 外发光

1,003 阅读1分钟

threejs是我的感兴趣的方向,以后我会分享自己three的学习过程下面是官网外发光案例 threejs 的官网属性不是很好查找,自己敲了一遍,在我认为有新知识的地方大家加上注释。

import Stats from 'three/examples/jsm/libs/stats.module.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
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'
import glb from './PrimaryIonDrive.glb?url'
//初始变量
let camera, stats
let composer, renderer, mixer, clock
const params = {
  exposure: 1,
  bloomStrength: 1.5,
  bloomThreshold: 0,
  bloomRadius: 0,
}
//所有定义都在init方法里面
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) //renderpass 通道:它只会渲染场景,但是不会输出到屏幕上
  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)
  //加载glb文件
  new GLTFLoader().load(glb, (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是自己定义变量,‘’里面的是对象里的属性,一个onchang事件传一个回调参数,用来修改属性
  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)
  }
  const animate = () => {
    requestAnimationFrame(animate)
    const delta = clock.getDelta()
    mixer.update(delta)
    composer.render()
    stats.update()
  }
}