Skip to content

后处理

对 threejs 的渲染结果进行后期处理,比如添加发光、抖动效果

后处理创建(发光描边)

1. 引入扩展库EffectComposer.js

js
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";

const renderer = new THREE.WebGLRenderer();
// 创建后处理对象EffectComposer,WebGL渲染器作为参数
const composer = new EffectComposer(renderer);

2. 创建渲染器通道RenderPass

EffectComposer(renderer)指定了需要后处理的渲染器 WebGLRenderer渲染器通道 RenderPass 指定后处理对应的相机 camera 和场景 scene

js
// 引入渲染器通道RenderPass
import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
// 创建一个渲染器通道,场景和相机作为参数
const renderPass = new RenderPass(scene, camera);
// 设置renderPass通道
composer.addPass(renderPass);

3. OutlinePass发光通道

给指定的某个模型对象添加一个高亮发光描边效果

  1. 引入并创建

    js
    // 引入OutlinePass通道
    import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";
    // OutlinePass第一个参数v2的尺寸和canvas画布保持一致
    const v2 = new THREE.Vector2(window.innerWidth, window.innerHeight);
    // const v2 = new THREE.Vector2(800, 600);
    const outlinePass = new OutlinePass(v2, scene, camera);
  2. 指定发光模型.selectedObjects

    js
    // 一个模型对象
    outlinePass.selectedObjects = [mesh];
    // 多个模型对象
    outlinePass.selectedObjects = [mesh1, mesh2, group];
  3. 设置 OutlinePass 通道

    js
    composer.addPass(outlinePass);

4. 渲染循环执行EffectComposer.render()

后处理 EffectComposer 执行.render(),会调用 webgl 渲染器执行.render()

js
// 渲染循环
function render() {
  composer.render();
  // renderer.render(scene, camera);
  requestAnimationFrame(render);
}
render();

描边样式 OutlinePass

描边颜色.visibleEdgeColor

js
//模型边缘高亮边框颜色,默认白色
outlinePass.visibleEdgeColor.set(0xffff00);

描边厚度.edgeThickness

js
//高亮发光描边的厚度,默认值1
outlinePass.edgeThickness = 4.0;

描边亮度.edgeStrength

js
//高高亮描边的发光强度,默认值3
outlinePass.edgeStrength = 6;

描边闪烁.pulsePeriod

js
// 描边的闪烁频率,默认0不闪烁
outlinePass.pulsePeriod = 2;

Bloom 发光通道

使模型产生高光发亮效果

1. 引入创建

js
// 引入UnrealBloomPass通道
import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
// canvas画布宽高度window.innerWidth, window.innerHeight
const v2 = new THREE.Vector2(window.innerWidth, window.innerHeight);
const bloomPass = new UnrealBloomPass(v2);

2. 设置发光强度

js
//bloom发光强度, 默认1.0
bloomPass.strength = 2.0;

3. 添加发光通道

js
composer.addPass(bloomPass);

多通道组合

添加多个通道处理, 组合使用进行后期处理

1. 引入扩展库创建渲染通道

js
// 引入后处理扩展库EffectComposer.js
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
// 引入渲染器通道RenderPass
import { RenderPass } from "three/addons/postprocessing/RenderPass.js";

// 创建后处理对象EffectComposer,WebGL渲染器作为参数
const composer = new EffectComposer(renderer);
// 1. 创建一个渲染器通道,场景和相机作为参数
const renderPass = new RenderPass(scene, camera);
// 设置renderPass通道
composer.addPass(renderPass);

2. 创建 OutlinePass 通道

js
import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";

const v2 = new THREE.Vector2(window.innerWidth, window.innerHeight);
const outlinePass = new OutlinePass(v2, scene, camera);
outlinePass.selectedObjects = [mesh];
//...样式配置
composer.addPass(outlinePass);

3. 设置 glitchPass 闪屏通道

js
import { GlitchPass } from "three/addons/postprocessing/GlitchPass.js";

const glitchPass = new GlitchPass();
composer.addPass(glitchPass);

gltf 后处理颜色异常(伽马校正)

加载 gltf 模型,如果使用 EffectComposer 添加后处理功能,模型颜色可能会出现异常, 需要借助其它通道进行处理

提示

  • threejs 并没有直接提供伽马校正的后处理通道, 只提供了一个伽马校正的 Shader 对象 GammaCorrectionShader
  • 需要把 Shader 对象作为 ShaderPass 的参数创建一个通道
js
// 伽马校正后处理Shader
import { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js";
// ShaderPass功能:使用后处理Shader创建后处理通道
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";

// 创建伽马校正通道
const gammaPass = new ShaderPass(GammaCorrectionShader);
composer.addPass(gammaPass);

抗锯齿后处理

使用了后处理可能会导致模型产生锯齿, 需要借助其它通道来解决

FXAA 抗锯齿通道

  1. 引入

    js
    // ShaderPass功能:使用后处理Shader创建后处理通道
    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    // FXAA抗锯齿Shader
    import { FXAAShader } from "three/addons/shaders/FXAAShader.js";
  2. 像素配置

    js
    // 设置设备像素比,避免canvas画布输出模糊
    renderer.setPixelRatio(window.devicePixelRatio);
    // .getPixelRatio()获取设备像素比
    const pixelRatio = renderer.getPixelRatio();
  3. 设置 FAXX 抗锯齿通道

    js
    const FXAAPass = new ShaderPass(FXAAShader);
    // width、height是canva画布的宽高度
    FXAAPass.uniforms.resolution.value.x = 1 / (width * pixelRatio);
    FXAAPass.uniforms.resolution.value.y = 1 / (height * pixelRatio);
    composer.addPass(FXAAPass);

SMAA 抗锯齿通道

相对于 FXAA 效果会更好一些

  1. 引入

    js
    // SMAA抗锯齿通道
    import { SMAAPass } from "three/addons/postprocessing/SMAAPass.js";
  2. 创建 SMAAPass 抗锯齿通道

    js
    //获取.setPixelRatio()设置的设备像素比
    const pixelRatio = renderer.getPixelRatio();
    // width、height是canva画布的宽高度
    const smaaPass = new SMAAPass(width * pixelRatio, height * pixelRatio);
    composer.addPass(smaaPass);