Threejs后期处理Bloom发光效果
前置知识
在做这个案例的时候,我们需要有一点前置知识:
- 什么是EffectComposer(效果组合器)
- 什么是RenderPass(渲染通道)
- 什么是OutlinePass、UnrealBloomPass和GlitchPass(高亮发光描边、Bloom发光和画面抖动效果)
- 什么是OutputPass(输出通道)
如果你已经了解了这四点,那么相信你已经知道了,这是一个后期处理的一个工作流程。
那么接下来的代码,你一定看得懂:
完整代码
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.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';export default (domId) => {/* ------------------------------初始化三件套--------------------------------- */const dom = document.getElementById(domId);const { innerHeight, innerWidth } = windowconst scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 2000);camera.position.set(0, 0, 10);camera.lookAt(scene.position);const renderer = new THREE.WebGLRenderer({antialias: true,// 抗锯齿alpha: false,// 透明度powerPreference: 'high-performance',// 性能logarithmicDepthBuffer: true,// 深度缓冲})// renderer.setClearColor(0x000000, 0);// 设置背景色// renderer.clear();// 清除渲染器renderer.shadowMap.enabled = true;// 开启阴影renderer.shadowMap.type = THREE.PCFSoftShadowMap;// 阴影类型renderer.outputEncoding = THREE.sRGBEncoding;// 输出编码renderer.toneMapping = THREE.ACESFilmicToneMapping;// 色调映射renderer.toneMappingExposure = 1;// 色调映射曝光renderer.physicallyCorrectLights = true;// 物理正确灯光renderer.setPixelRatio(devicePixelRatio);// 设置像素比renderer.setSize(innerWidth, innerHeight);// 设置渲染器大小dom.appendChild(renderer.domElement);// 重置大小window.addEventListener('resize', () => {const { innerHeight, innerWidth } = windowcamera.aspect = innerWidth / innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth, innerHeight);})/* ------------------------------初始化工具--------------------------------- */const controls = new OrbitControls(camera, renderer.domElement) // 相机轨道控制器controls.enableDamping = true // 是否开启阻尼controls.dampingFactor = 0.05// 阻尼系数controls.panSpeed = -1// 平移速度const axesHelper = new THREE.AxesHelper(10);scene.add(axesHelper);/* ------------------------------正题--------------------------------- */// 配置信息const options = {threshold: 0,// 发光阈值strength: 0.5,// 发光强度radius: 0.5,// 发光半径exposure: 0.5// 曝光}// 创建一个效果组合器const composer = new EffectComposer(renderer);// 创建一个渲染器通道const renderPass = new RenderPass(scene, camera);composer.addPass(renderPass);// 添加渲染器通道// 创建一个Bloom发光效果通道 (泛光所覆盖的场景大小, 泛光强度, 泛光模糊度, 泛光衰减)const bloomPass = new UnrealBloomPass(new THREE.Vector2(innerWidth, innerHeight), 1.5, 0.4, 0.85);bloomPass.threshold = options.threshold;// 发光阈值bloomPass.strength = options.strength;// 发光强度bloomPass.radius = options.radius;// 发光半径composer.addPass(bloomPass);// 添加Bloom发光效果通道const outputPass = new OutputPass(); // 创建一个输出通道composer.addPass(outputPass);// 添加输出通道// 添加环境光const light = new THREE.AmbientLight(0xcccccc);scene.add(light);const yellowBox = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1),new THREE.MeshBasicMaterial({ color: 0xffff00 }));scene.add(yellowBox);const redBox = new THREE.Mesh(new THREE.BoxGeometry(2, 1, 3),new THREE.MeshBasicMaterial({ color: 0xff0000 }))redBox.position.y = -2;scene.add(redBox);const animationRender = () => {renderer.setViewport(0, 0, innerWidth, innerHeight);// 设置渲染器视口大小renderer.autoClear = false;// 关闭自动清除renderer.clear();// 清除渲染器yellowBox.visible = false;composer.render();// 渲染后期效果renderer.clearDepth();// 清除深度缓存yellowBox.visible = true;renderer.render(scene, camera);// 渲染场景}/* ------------------------------动画函数--------------------------------- */const animation = () => {controls.update();// 如果不调用,就会很卡// renderer.render(scene, camera);animationRender()requestAnimationFrame(animation);}animation();
}