Three.js 进阶之旅:后期处理-3D瑞克与莫蒂 🛸


theme: smartblue

本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!

声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。

摘要

专栏上篇文章《Three.js 进阶之旅:Shader着色器基础图案-旷野之息神庙铁球》中我们使用 Shader 绘制基础图案,并使用图案简单应用 UnrealBloomPass 辉光后期效果创建了一个会发光的球体。本文内容就接着上文内容详细讲解一下 Three.js 后期处理的基本知识。最后,通过结合文章讲解的知识内容,将开发一个《瑞克与莫蒂》发光传送门效果的 3D 页面。

通过阅读学习本文和实践本文提供的案例,你将学到的知识包括:Three.js 后期处理基本原理;Three.js 后期处理代码实现流程;Three.js 中内置的各种后期处理通道的含义及其用法;使用后期处理知识开发一个创意 3D 页面;只对页面上的某个图层应用后期效果而不是全局应用;使用正余弦函数实现简单的大小、角度、位移等的往返动画等。

poster.png

动画美剧《瑞克与莫蒂》

效果

在学习后期处理原理前,我们先来看看本文示例页面最终实现效果。如下图所示,页面主体由 3D 传送门 🌌瑞克与莫蒂 🛸 的模型构成,同时传送门具有旋转和由远及近缩小放大的效果,人物模型也拥有前后摆动动画效果。

preview.gif

打开以下链接中的任意一个,在线预览效果,大屏访问效果更佳。

本专栏系列代码托管在 Github 仓库【threejs-odessey】后续所有目录也都将在此仓库中更新

🔗 代码仓库地址:git@github.com:dragonir/threejs-odessey.git

码上掘金

代码片段

原理

后期处理

后期处理通常是指在 2D 图像上使用特效或者滤镜,比如我们熟知的 Photoshop 滤镜、Instagram 滤镜、各种美图软件滤镜等。在 Three.js 中,我们也是将场景 scene 中的三维网格模型 mesh 渲染成 2D 图像在屏幕上输出。一般来说,图像直接被渲染成 canvas 在浏览器中展示的,但是在转化成 canvas 之前,我们可以通过另外的 render target 设置一些渲染滤镜效果,这一过程发生在主场景渲染过程之后,因此称为后期处理 Post Processing

Three.js 中内置了很多类专门用于创建一个后期通道 processing pipeline,它的工作方式是首先需要创建一个 EffectComposer,然后在它上面添加很多通道 Pass 对象,然后调用 EffectComposer.render,它将会把你的场景渲染到一个 render target 上,并应用各种 Pass

每个 Pass 通道都能添加一些后期效果,比如贴图、模糊、光晕、噪点、调整色相、饱和度、对比度等,最终会将这些特效渲染到 canvas 中。

理解 EffectComposer 的工作原理是非常重要的,它创建两个 render targets,我们暂时称它们为 rtArtB。接着你需要调用 EffectComposer.addPass 方法来按自己需要的顺序添加 pass 通道,然后它们就将会像下图一样被应用。

pass.png

首先,传入的 RenderPass 场景将被渲染到 rtA,接着 rtA 将被传递给下一个 pass,无论它的内容是什么。下一个 pass 将使用它作为输入并执行一些操作后将它写入到 rtB。然后 rtB 传到下一个 pass,将 rtB 作为输入并执行一些操作然后写回到 rtA,这一过程将在整个 pass 过程中持续发生。

每个 pass 都有 4 个基础选项:

  • enabled: 是否使用这个 pass
  • needsSwap: 完成这个 pass 后是否交换 rtArtB
  • clear:在渲染这个 pass 之前是否需要清除
  • renderToScreen: 是否将当前的内容渲染到画布上。通常来说你需要在你最后添加的pass 设置这一项为 true

基本用法

结合上述所讲内容,我们来写一个简单的后期处理例子。首先,我们需要在文件顶部引入以下几个类,其中 EffectComposer.jsRenderPass.js 是后期渲染必需的,另外两个是我们需要添加的后期通道。

import {EffectComposer} from '/examples/jsm/postprocessing/EffectComposer.js';
import {RenderPass} from '/examples/jsm/postprocessing/RenderPass.js';
import {BloomPass} from '/examples/jsm/postprocessing/BloomPass.js';
import {FilmPass} from '/examples/jsm/postprocessing/FilmPass.js';

我们使用《Three.js 进阶之旅:基础入门(上)》中的方法创建一个基础场景,在上面添加三个正方体,然后通过以下方式创建一个 EffectComposer

const composer = new EffectComposer(renderer);

接着添加一个 RenderPass 作为第一个 pass,它会将我们的场景 scene 和相机 camera 渲染到第一个渲染目标。

composer.addPass(new RenderPass(scene, camera));

然后,添加一个 BloomPass。一个 BloomPass 将它的输入放入一个通常来说更小的 render target 然后对这个结果的表面进行模糊处理,使得场景产生辉光效果

const bloomPass = new BloomPass(1, 25, 4, 256);
composer.addPass(bloomPass);

我们再添加一个 FilmPass 来生成噪点和扫描线效果,由于FilmPass是最后一次传递,我们需要将其renderToScreen属性设置为true,来告诉它渲染到画布。如果不设置,它将渲染到下一个渲染目标。

const filmPass = new FilmPass(0.35, 0.025, 648, false);
filmPass.renderToScreen = true;
composer.addPass(filmPass);

📌 BloomPassFilmPass 的具体参数含义可查看文章末尾附录

最后,在页面重绘动画方法中,我们需要使用 EffectComposer.render 替代 WebGLRenderer.render 并使 EffectComposer 匹配画布大小,整个辉光后期处理流程就完成了:

const tick = () => {
  const canvas = renderer.domElement;
  camera.aspect = canvas.clientWidth / canvas.clientHeight;
  camera.updateProjectionMatrix();
  composer.setSize(canvas.width, canvas.height);
  composer.render();
  requestAnimationFrame(tick);
}

sample.gif

🔗 示例地址:https://threejs.org/manual/examples/postprocessing.html

Three.js 后期处理通道汇总

下面列举了 Three.js 中内置的一些后期处理通道,我们在开发完页面优化过程中,可以选择合适的通道给页面场景添加后期滤镜。它们的具体用法可以查看本文最后的附录,在附录中我总结汇总了它们的构造函数、参数含义、属性、示例等基本用法。不幸的是,Three.js 对大多数后期处理效果都没有给出详细的使用文档,如果想要完全了解它们,就必须仔细阅读官网文档提供的示例或者源码,可以在文档中通过 postprocessing 进行检索。

  • AdaptiveToneMappingPass:该通道可以根据场景的光照度自动调节场景的亮度。
  • BloomPass:该通道通过增强场景中明亮的区域来模拟真实世界中的摄像机。
  • BokehPass:该通道可以实现类似大光圈镜头的景深效果。
  • ClearPass:该通道清空当前纹理缓存。
  • CubeTexturePass:用于渲染天空盒。
  • DotScreenPass:将黑点图层应用于屏幕的原始图片上。
  • FilmPass:通过扫描线和失真来模拟电视屏幕效果。
  • GlitchPass:随机在屏幕上显示电脉冲。
  • HalftonePass:用于模拟传统印刷术的半色调效果。
  • MaskPass:在图片上显示掩码,后续通道只会影响到掩码区域。
  • OutlinePass:勾勒出场景中的物体轮廓。
  • RenderPass:在当前场景和摄像机的基础上渲染出一个新场景。
  • SAOPass:实现实时环境光遮挡效果。
  • SMAAPass:全屏反锯齿效果。
  • SSAARenderPass:使用另一种算法实现全屏反锯齿效果。
  • SSAOPass:使用另一种算法实现实时环境光遮挡效果
  • SavePass:该通道执行时会赋值当前渲染结果,在后续步骤中可以使用。
  • ShaderPass:自定义着色器通道,可以传入自定义着色器作为参数,以生成一个高级、自定义的后期处理通道。
  • TAARenderPass:也是一个全屏反锯齿效果。
  • TexturePass:将合成器的当前状态保存为纹理,然后将其作为参数传入到其他的 EffectComposer 组合器中。
  • UnrealBloomPass:该通道与 Bloom 类似,但是它实现的效果更接近于虚幻引擎的 Bloom 效果。

实现

了解了后期处理的基本原理后,现在我们就来根据上述讲解的知识进行实践,开发一个《瑞克与莫蒂》主题 3D 页面 🛸

资源引入

首先我们来看看开发示例所示页面,需要引入哪些资源:dat.gui 用于动态调整传送门的样式,是可选的;OrbitControls:用于相机镜头轨道控制;DRACOLoaderGLTFLoader 用于加载经过压缩的瑞克与莫蒂人物模型;EffectComposerRenderPassUnrealBloomPass 用于给传送门添加辉光后期效果portalVertexShaderportalFragmentShader 则是用于生成传送门形状和样式的着色器

import * as THREE from 'three';
import * as dat from 'dat.gui';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
import portalVertexShader from './shaders/portal/vertex.glsl';
import portalFragmentShader from './shaders/portal/fragment.glsl';

场景初始化

如同《Three.js 进阶之旅:基础入门(上)》所讲的内容,我们先进行三维场景初始化的基本流程,每段代码具体含义可前往对应文章查看,本文不再赘述。唯一需要注意的是,需要设置 renderer.autoClear = false,不然后续添加的后期处理效果无法生效。

// 初始化渲染器
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('canvas.webgl'),
  antialias: true,
  alpha: true
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
// 注意
renderer.autoClear = false;
renderer.setClearAlpha(0);
renderer.physicallyCorrectLights = true;
renderer.toneMapping = THREE.CineonToneMapping;
renderer.toneMappingExposure = 2;

// 初始化场景
const scene = new THREE.Scene();

// 初始化相机
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 10000)
camera.position.set(0, 1, 5);
scene.add(camera);

// 添加直射光
const directionalLight = new THREE.DirectionalLight('#ffffff', 4);
directionalLight.castShadow = true;
directionalLight.shadow.camera.far = 15;
directionalLight.shadow.mapSize.set(1024, 1024);
directionalLight.shadow.normalBias = 0.05
directionalLight.position.set(.25, 3, -1.25);
scene.add(directionalLight);

// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 1.2);
scene.add(ambientLight);

// 添加镜头控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;
// 限制垂直旋转角度
controls.minPolarAngle = .5;
controls.maxPolarAngle = 2.5;
// 限制水平旋转角度
controls.minAzimuthAngle = -1;
controls.maxAzimuthAngle = 1;

// 页面缩放事件监听
window.addEventListener('resize', () => {
  sizes.width = window.innerWidth;
  sizes.height = window.innerHeight;
  // 更新渲染
  renderer.setSize(sizes.width, sizes.height);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  // 更新相机
  camera.aspect = sizes.width / sizes.height;
  camera.updateProjectionMatrix();
});

创建传送门

接着,我们按以下步骤,来实现一个可以发光的传送门 🌌

① 创建平面

使用 PlaneBufferGeometry 创建一个平面几何体,我们需要使用着色器实现传送门的纹理,因此平面材质使用着色器材质 ShaderMaterial。将创建好的平面网格添加到场景中,就会看到一个如下图所示的的红色平面。

const portalGeometry = new THREE.PlaneBufferGeometry(8, 8, 1, 1);
const portalMaterial = new THREE.ShaderMaterial({});
const portal = new THREE.Mesh(portalGeometry, portalMaterial);
scene.add(portal);

step_0.png

② 添加着色器

在着色器材质中,我们添加如下所示的统一变量uniformstime 是个非常小的时间值,用于设置 uv 的旋转频率;perlinnoisesparknoisewaterturbulencenoiseTex 是用于生成着色器材质的噪声纹理贴图、colors 是颜色值、resolution 是屏幕宽高作为参数的二维向量,用于识别屏幕分辨率。portalFragmentShader 是片元着色器,portalVertexShader 是顶点着色器。着色器参考自Three.js 官网论坛,详细实现可查看源码。

var options = {
  exposure: 2.8,
  bloomStrength: 2.39,
  bloomThreshold: 0,
  bloomRadius: 0.38,
  color0: [1, 5, 1],
  color1: [2, 20, 2],
  color2: [44, 97, 15],
  color3: [14, 28, 5],
  color4: [255, 255, 255],
  color5: [74, 145, 0],
};
const textureLoader = new THREE.TextureLoader();
const portalMaterial = new THREE.ShaderMaterial({
  uniforms: {
    time: {
      type: 'f',
      value: 0.0,
    },
    perlinnoise: {
      type: 't',
      value: textureLoader.load('/images/perlinnoise.png'),
    },
    sparknoise: {
      type: 't',
      value: textureLoader.load('/images/sparknoise.png'),
    },
    waterturbulence: {
      type: 't',
      value: textureLoader.load('/images/waterturbulence.png'),
    },
    noiseTex: {
      type: 't',
      value: textureLoader.load('/images/noise.png'),
    },
    color5: {
      value: new THREE.Vector3(...options.color5),
    },
    color4: {
      value: new THREE.Vector3(...options.color4),
    },
    color3: {
      value: new THREE.Vector3(...options.color3),
    },
    color2: {
      value: new THREE.Vector3(...options.color2),
    },
    color1: {
      value: new THREE.Vector3(...options.color1),
    },
    color0: {
      value: new THREE.Vector3(...options.color0),
    },
    resolution: {
      value: new THREE.Vector2(sizes.width, sizes.height)
    }
  },
  fragmentShader: portalFragmentShader,
  vertexShader: portalVertexShader
});

平面网格模型添加完整的着色器材质后,会得到如下所示的圆形螺旋状图案,传送门 🌌 的雏形就出来了。

step_1.png

③ 添加动画

为了使传送门生成旋转流动的效果,可以通过在页面重绘方法 requestAnimationFrame 中调用下面的函数 updateShaderMaterial,用来更新着色器材质的 timecolor 等统一变量。

const updateShaderMaterial = deltaTime => {
  portalMaterial.uniforms.time.value = deltaTime / 5000;
  portalMaterial.uniforms.color5.value = new THREE.Vector3(...options.color5);
  portalMaterial.uniforms.color4.value = new THREE.Vector3(...options.color4);
  portalMaterial.uniforms.color3.value = new THREE.Vector3(...options.color3);
  portalMaterial.uniforms.color2.value = new THREE.Vector3(...options.color2);
  portalMaterial.uniforms.color1.value = new THREE.Vector3(...options.color1);
  portalMaterial.uniforms.color0.value = new THREE.Vector3(...options.color0);
}

step_2.gif

④ 添加后期处理

上面实现的着色器材质在外形上已经非常接近动画中的传送门 🌌 样式了,现在我们应用本文学习的 Three.js 后期处理知识,利用 UnrealBloomPass 给传送门增加辉光效果,使其看起来更加真实。初始化 UnrealBloomPass,它的 4 个参数依次对应辉光效果的作用范围、光晕强度、光晕半径、以及光晕阈值,其中光晕阈值,值越小,效果越明显。为了在屏幕上渲染后期处理效果,需要将 EffectComposerrenderToScreen 属性设置为 true

需要注意的是 💥 ,我们在场景中还需要加载其他任务模型,其他模型不需要渲染辉光效果,只需要给传送门添加辉光效果,因此我们需要将传送门与其他模型设置为不同的层级,辉光效果渲染的时候只需要渲染到有传送门的层级,若不设置层级,辉光后期效果将在全局生效。可以通过 mesh.layers.set(layer_number) 的方式设置网格模型的层级。

const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, .4, .85);
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = true;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
// 设置层级
portal.layers.set(1);

添加辉光后期效果后,传送门变得更加炫酷逼真了!

step_3.gif

⑤ 调整合适的着色器参数和后期效果

为了调试出自己满意的效果,我们可以添加 dat.GUI,然后在页面上动态调整着色器的颜色参数和辉光后期通道的属性值。

// 将着色器通道的属性设置成变量
bloomPass.threshold = options.bloomThreshold;
bloomPass.strength = options.bloomStrength;
bloomPass.radius = options.bloomRadius;
// 添加 dat。GUI
const gui = new dat.GUI();
const bloom = gui.addFolder('bloom');
bloom.add(options, 'bloomStrength', 0.0, 5.0).name('bloomStrength').listen();
bloom.add(options, 'bloomRadius', .1, 2.0).name('bloomRadius').listen();
const colors = gui.addFolder('Colors');
colors.addColor(options, 'color0').name('layer0');
colors.addColor(options, 'color1').name('layer1');
colors.addColor(options, 'color2').name('layer2');
colors.addColor(options, 'color3').name('layer3');
colors.addColor(options, 'color4').name('layer4');
colors.addColor(options, 'color5').name('layer5');

gui.png

准备模型资源

后面的内容就非常简单了。为了打造完整的《瑞克与莫蒂》 3D 场景 🛸,我们从网上下载一个免费的瑞克与莫蒂 3D 模型,然后在 Blender 中删除模型多余的部分并转化成 Three.js 支持的 .glb 格式压缩导出。经过压缩的模型,从原来的 50M 左右变为 2M 左右,有利于节省空间、提高页面加载运行性能。

model.png

🔗 模型来源:sketchfab.com

加载模型

使用 DRACOLoaderGLTFLoader 加载经过压缩的模型,然后将模型添加到场景中,记得要将模型层级设置成与传送门不同的层级,以避免被设置辉光效果。

// 使用 dracoLoader 加载用blender压缩过的模型
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
dracoLoader.setDecoderConfig({ type: 'js' });
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);

// 加载模型
loader.load('/models/rickAndMorty.glb', mesh => {
  if (mesh.scene) {
    mesh.scene.scale.set(.02, .02, .02);
    mesh.scene.position.x = -.5;
    mesh.scene.rotation.y = Math.PI;
    scene.add(mesh.scene);
    // 设置层级
    mesh.scene.layers.set(0);
  }
});

step_4.png

添加动画

requestAnimationFrame 页面重绘方法中,我们先渲染具有辉光通道的传送门图层,将摄像机的层级设置成与它相同的层级,然后再使用 renderer.clearDepth() 方法清除深度缓冲区,将摄像机设置为与模型相同的层级,最后再渲染场景和相机。这样就能实现只在传送门所在的层级添加辉光后期处理效果了。由于下载的模型没有骨骼动画,直接叠加在页面上看起来比较生硬,我们在这里给使用正余弦函数给模型 🛸 旋转角度 rotation 和传送门 🌌 的大小 scale 分别设置动画效果,让页面动起来。

const clock = new THREE.Clock()
const tick = deltaTime => {
  updateShaderMaterial(deltaTime);
  // 传送门所在层级
  renderer.clear();
  camera.layers.set(1);
  bloomComposer.render();
  // 模型所在层级
  renderer.clearDepth();
  camera.layers.set(0);
  renderer.render(scene, camera);
  // 添加模型动画
  const elapsedTime = clock.getElapsedTime()
  const ghost1Angle = elapsedTime * 0.5
  if (model) {
    model.rotation.x = Math.cos(ghost1Angle) * .2
    model.rotation.z = Math.sin(ghost1Angle) * .1
    model.position.z += Math.cos(ghost1Angle) * .005
  }
  // 添加传送门动画
  const scale = Math.cos(ghost1Angle) * 2 + 3;
  portal && portal.scale.set(scale, scale, scale);
  // 页面重绘时调用自身
  controls && controls.update();
  window.requestAnimationFrame(tick);
}
tick();

step_5.gif

页面优化

最后,我们调整一下 CSS 样式,给页面添加一张星空氛围感的背景图片、加上 Rick And Morty 字样的 logo 装饰图片等,炫酷的 3D 场景就完成了,赶快亲自动手试试吧!

step_6.png

到此,本文主体内容就结束了,后文附录中列举整理了 Three.js 中其他常用的后期处理通道的用法,大家在实践的时候可以都尝试看看效果有何不同,根据自己的页面内容选择合适的后期处理效果,可以让我们的 3D 场景看起来更加真实,起到锦上添花的作用!🌺

🔗 源码地址:https://github.com/dragonir/threejs-odessey

总结

本文中主要包含的知识点包括:

  • Three.js 后期处理基本原理
  • Three.js 后期处理代码实现流程
  • Three.js 中内置的各种后期处理通道的含义及其用法
  • 使用后期处理知识开发一个创意 3D 页面
  • 只对页面上的某个图层应用后期效果而不是全局应用
  • 使用正余弦函数实现简单的大小、角度、位移等的往返动画

想了解其他前端知识或其他未在本文中详细描述的Web 3D开发技术相关知识,可阅读我往期的文章。如果有疑问可以在评论中留言,如果觉得文章对你有帮助,不要忘了一键三连哦 👍

附录

下面列举了几个常用的 Three.js 后期处理通道包,完整用法和示例大家可前往Three.js 官方示例文档搜索关键字postprocessing

RenderPass

该通道会在当前场景和摄像机的基础上渲染出一个新场景,和普通的 webGLRenderer 一样。

参数

  • scene:场景对象
  • camera:相机对象

属性

  • enabled:开启通道,默认为 true,设置为 false 则通道关闭,一般通道都有该属性。
  • clear:清除渲染,默认为 true,设置 false 可以避免影响其他后通道的使用。

示例

const renderPass = new THREE.RenderPass(scene,camera);
composer.addPass(renderPass);
renderPass.enabled = false;

ShaderPass

该通道接受自定义的着色器作为参数,以生成一个高级、自定义的后期处理通道, 产生各种模糊效果和高级滤镜。

参数

各种 Three.js 内置着色器包或自定义着色器:

  • THREE.DotScreenShader:输出灰度点集
  • THREE.MirrorShader:创建镜面效果
  • THREE.HueSaturationShader:改变颜色的色调和饱和度
  • THREE.VignetteShader:添加晕映效果
  • THREE.ColorCorrectionShader:调整颜色的分布
  • THREE.RGBShiftShader:将红绿蓝三种颜色分开
  • THREE.BrightnessContrastShader:改变亮度和对比度
  • THREE.ColorifyShader:将某种颜色覆盖到整个屏幕
  • THREE.SepiaShader:创建类似于乌贼墨的效果
  • THREE.KaleidoShader:类似于万花筒的效果
  • THREE.LuminosityShader:提高亮度
  • THREE.TechnicolorShader:模拟类似老电影里面的两条彩色效果
  • THREE.HorizontalBlurShaderTHREE.VerticalBlurShader:可以向水平和垂直方向创建模糊效果
  • THREE.HorizontalTiltShiftShaderTHREE.VerticalTileShiftShader:可以在水平和垂直方向创建倾斜平移的效果
  • THREE.TriangleBlurShader:基于三角形的方法创造一种模糊效果
  • THREE.BleachBypassShader:创造一种镀银的效果
  • THREE.EdgeShader:找到图片的边界并显示
  • THREE.FXAAShader:添加抗锯齿的效果
  • THREE.FocusShader:创建中间比较尖锐,周围比较模糊的效果。

GlitchPass

该通道会随机在屏幕上显示电脉冲,使用时需要引入对应的着色器包 DigitalGlitch

属性

  • goWild:默认为 false,设置为 true 则会持续显示全屏电子脉冲。

用法

glitchPass=new THREE.GlitchPass();  //该通道需要添加着色器依赖包
composer.addPass(glitchPass);
glitchPass.goWild = true;           //持续全屏电子脉冲

pass_glitch.png

🔗 官网示例:https://threejs.org/examples/?q=post#webgl_postprocessing_glitch

OutlinePass

该通道可以为场景中被添加到通道中的物体边缘添加一个描边发光效果。

参数

  • vector2:二维向量作用范围。
  • scene:场景对象。
  • camera:相机对象。

属性

  • edgeStrength:边缘强度 ,默认 3.0,最基础的属性,后面 4 个配置项都基于该项。
  • edgeGlow:边缘流, 默认 0.0
  • edgeThickness:边缘厚度,默认 1.0
  • pulsePeriod:闪烁频率 ,默认 0,值越大频率越低。
  • usePatternTexture:选中对象使用图案纹理,默认 false,不使用。
  • visibleEdgeColor:边缘可见部分发光颜色,默认 #FFFFFF
  • hiddenEdgeColor:边缘遮挡部分发光颜色,默认 #190A05
  • selectedObjects:一个对象数组,表示使用该效果的对象。

示例

const outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
composer.addPass(outlinePass);
// 添加纹理
new THREE.TextureLoader().load('disturb.jpg', function(texture) {
  outlinePass.patternTexture=texture;
  texture.wrapS=texture.wrapT=THREE.RepeatWrapping;
});
// 添加物体对象
outline_objects.push(mesh);
outlinePass.selectedObjects = outline_objects;

pass_outline.png

🔗 官网示例:https://threejs.org/examples/?q=outline#webgl_postprocessing_outline

MaskPass

该通道可以在当前图像上添加掩码,后续的通道只会影响掩蔽区域,并且使用完后必须清除掩码区域。

参数

  • scene:场景对象。
  • camera:相机对象。

示例

const maskPass = new THREE.MaskPass(scene, camera);
composer.addPass(maskPass);

pass_mask.png

🔗 官网示例:https://threejs.org/examples/?q=post#webgl_postprocessing_masking

TexturePass

纹理贴图通道,如设置背景贴图。

参数

  • texture:纹理对象。

属性

  • map:等同于直接在构造函数中赋值。
  • opacity:贴图透明度,默认 1

示例

const texturePass = new THREE.TexturePass(texture);
composer.addPass(texturePass);

AfterimagePass

该通道可以让通道场景内的物体在运动时,产生残影效果。使用时需要引入相对应的着色器包 AfterimageShader

示例

const afterimagePass = new THREE.AfterimagePass();
composer.addPass(afterimagePass);

UnrealBloomPass

该通道会产生类似于虚幻引擎的辉光效果,需搭配对应的着色器包 LuminosityHighPassShader 使用。

参数

  • vector2:二维向量作用范围。
  • strength:光晕强度,默认为 1
  • radius:光晕半径。
  • threshold:光晕阈值,值越小,效果越明显。

示例

const unrealBloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.0, 0.5, 0.1);
composer.addPass(unrealBloomPass);

ClearPass

清除背景通道,设置背景颜色等。

参数

  • clearColor:背景颜色,默认 0
  • clearAlpha:背景透明度,默认 0

示例

const clearPass = new THREE.ClearPass('white', 1.0);
composer.addPass(clearPass);

CubeTexturePass

天空盒子贴图通道,设置全景贴图。

参数

  • camera:相机对象

属性

  • envmap:全景贴图,六张图片
  • opacity:透明度
  • enabled:是否开启通道,默认为 true

示例

const cubeTexturePass = new THREE.CubeTexturePass(camera);
composer.addPass(cubeTexturePass);
new THREE.CubeTextureLoader().setPath('textures/cube/').load(
  ['px.png', 'nx.png', 'py.png','ny.png', 'pz.png', 'nz.png'],
  function(map) {
    cubeTexturePass.envMap=map;
  }
);

BokehPass

该通道可以设置背景虚化程度,类似相机变焦产生的效果。

参数

  • scene:场景对象。
  • camera:相机对象。
  • options
    • focus:焦距,调整远近,对焦时才会清晰。
    • apertrue:孔径,类似相机孔径调节。
    • maxblur:最大模糊程度。

示例

const bokehPass = new THREE.BokehPass(scene, camera, {
  focus: 500,
  aperture: .05,
  maxblur: 1.0,
  width: window.innerWidth,
  height: window.innerHeight
});
composer.addPass(bokehPass);

HalftonePass

该通道可以给场景添加 RGB 三色效果,并且可以设置参数调节,需搭配对应着色器使用 js/shaders/HalftoneShader.js

参数

  • width:覆盖宽度,
  • height:覆盖长度
  • params:各配置项

示例

const halftonePass = new THREE.HalftonePass(window.innerWidth, window.innerHeight, params);
composer.addPass(halftonePass);

FilmPass

该通道会使用扫描线和失真来模拟电视屏幕效果。

参数

  • noiseIntensity:场景的粗糙程度。
  • scanlinesIntensity:扫描线的显著程度。
  • scanLinesCount:扫描线的数量。
  • gratScale:是否使用灰度图输出。

示例

const filmPass = new FilmPass(0.35, 0.025, 648, false);
composer.addPass(filmPass);

BloomPass

该通道会增强场景中的亮度,产生辉光效果。

参数

  • strength:光的强度。
  • kernelSize:光的偏移。
  • sigma:光的锐利程度。
  • resolution:光的精确度,值越低,光的方块化越严重。

示例

const bloomPass = new THREE.BloomPass(3, 25, 5.0, 256);
composer.addPass(bloomPass);

参考

阅读更多

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
相关推荐
  • 暂无相关文章
  • 评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容