目录
EffectComposer( renderer : WebGLRenderer, renderTarget : WebGLRenderTarget )
.readBuffer : WebGLRenderTarget
.writeBuffer : WebGLRenderTarget
用于在three.js中实现后期处理效果。该类管理了产生最终视觉效果的后期处理过程链。 后期处理过程根据它们添加/插入的顺序来执行,最后一个过程会被自动渲染到屏幕上。
例如淡入淡出效果crossfade:

小故障效果(glitch) :

虚幻光晕效果:

除此之外,Three官方还提供许多已定义的后期效果,供用户使用,例如抗锯齿、上帝光线等。
renderer -- 用于渲染场景的渲染器。
renderTarget -- (可选)一个预先配置的渲染目标,内部由 EffectComposer 使用。
一个用于表示后期处理过程链(包含顺序)的数组。
内部读缓冲区的引用。过程一般从该缓冲区读取先前的渲染结果。
内部渲染器的引用。
最终过程是否被渲染到屏幕(默认帧缓冲区)。
内部写缓冲区的引用。过程常将它们的渲染结果写入该缓冲区。
.addPass ( pass : Pass ) : undefined
pass -- 将被添加到过程链的过程
将传入的过程添加到过程链。
.insertPass ( pass : Pass, index : Integer ) : undefined
pass -- 将被插入到过程链的过程。
index -- 定义过程链中过程应插入的位置。
将传入的过程插入到过程链中所给定的索引处。
.isLastEnabledPass ( passIndex : Integer ) : Boolean
passIndex -- 被用于检查的过程
如果给定索引的过程在过程链中是最后一个启用的过程,则返回true。 由EffectComposer所使用,来决定哪一个过程应当被渲染到屏幕上。
.removePass ( pass : Pass ) : undefined
pass -- The pass to remove from the pass chain.
Removes the given pass from the pass chain.
.render ( deltaTime : Float ) : undefined
deltaTime -- The delta time value.
执行所有启用的后期处理过程,来产生最终的帧,
.reset ( renderTarget : WebGLRenderTarget ) : undefined
renderTarget -- (可选)一个预先配置的渲染目标,内部由 EffectComposer 使用。
重置所有EffectComposer的内部状态。
.setPixelRatio ( pixelRatio : Float ) : undefined
pixelRatio -- 设备像素比
设置设备的像素比。该值通常被用于HiDPI设备,以阻止模糊的输出。 因此,该方法语义类似于WebGLRenderer.setPixelRatio()。
.setSize ( width : Integer, height : Integer ) : undefined
width -- EffectComposer的宽度。
height -- EffectComposer的高度。
考虑设备像素比,重新设置内部渲染缓冲和过程的大小为(width, height)。 因此,该方法语义类似于WebGLRenderer.setSize()。
.swapBuffers () : undefined
交换内部的读/写缓冲。
1)导入three框架自带效果
- // three框架本身自带效果
- import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
- import { DotScreenPass } from "three/examples/jsm/postprocessing/DotScreenPass";
- import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass";
- import { SSAARenderPass } from "three/examples/jsm/postprocessing/SSAARenderPass";
- import { GlitchPass } from "three/examples/jsm/postprocessing/GlitchPass";
- import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass";
- import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
2)实例化合成效果并设置效果窗口尺寸
- // 合成效果
- const effectComposer = new EffectComposer(renderer);
- effectComposer.setSize(window.innerWidth, window.innerHeight);
3) 添加渲染通道
- const renderPass = new RenderPass(scene, camera);
- effectComposer.addPass(renderPass);
4)添加效果
- // 点效果
- const dotScreenPass = new DotScreenPass();
- dotScreenPass.enabled = false;
- effectComposer.addPass(dotScreenPass);
-
- // // 抗锯齿
- const smaaPass = new SMAAPass();
- effectComposer.addPass(smaaPass);
-
- // // 发光效果
- const unrealBloomPass = new UnrealBloomPass();
- effectComposer.addPass(unrealBloomPass);
- unrealBloomPass.strength = 1;
- unrealBloomPass.radius = 0;
- unrealBloomPass.threshold = 1;
- // // 屏幕闪烁效果
- const glitchPass = new GlitchPass();
- effectComposer.addPass(glitchPass)
5)将effectComposer挂载至生命函数中
- function animate(t) {
- controls.update();
- const time = clock.getElapsedTime();
- requestAnimationFrame(animate);
- //挂载效果合成器
- effectComposer.render();
- }
-
- animate();
6)实现效果:
未添加效果前:

添加效果后:

1)导入所需效果
- import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
- import { DotScreenPass } from "three/examples/jsm/postprocessing/DotScreenPass";
- import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass";
- import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass";
- import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
2)设置合成效果
- // 合成效果
- const effectComposer = new EffectComposer(renderer);
- effectComposer.setSize(window.innerWidth, window.innerHeight);
-
- // 添加渲染通道
- const renderPass = new RenderPass(scene, camera);
- effectComposer.addPass(renderPass);
-
- // 点效果
- const dotScreenPass = new DotScreenPass();
- dotScreenPass.enabled = false;
- effectComposer.addPass(dotScreenPass);
-
- // 抗锯齿
- const smaaPass = new SMAAPass();
- effectComposer.addPass(smaaPass);
-
- // 发光效果
- const unrealBloomPass = new UnrealBloomPass();
- effectComposer.addPass(unrealBloomPass);
- unrealBloomPass.strength = 1;
- unrealBloomPass.radius = 0;
- unrealBloomPass.threshold = 1;
3)编写着色器渲染通道
- //定义颜色参数
- const colorParams = {
- r: 0,
- g: 0,
- b: 0,
- };
- // 着色器写渲染通道
- const shaderPass = new ShaderPass({
- uniforms: {
- tDiffuse: {
- value: null,
- },
- uColor: {
- value: new THREE.Color(colorParams.r, colorParams.g, colorParams.b),
- },
- },
- vertexShader: `
- varying vec2 vUv;
- void main(){
- vUv = uv;
- gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
- }
- `,
- fragmentShader: `
- varying vec2 vUv;
- uniform sampler2D tDiffuse;
- uniform vec3 uColor;
- void main(){
- vec4 color = texture2D(tDiffuse,vUv);
- // gl_FragColor = vec4(vUv,0.0,1.0);
- color.xyz+=uColor;
- gl_FragColor = color;
- }
- `,
- });
-
- effectComposer.addPass(shaderPass);
4)编写法相纹理着色器渲染通道
- const techPass = new ShaderPass({
- uniforms: {
- tDiffuse: {
- value: null,
- },
- uNormalMap: {
- value: null,
- },
- uTime: {
- value: 0,
- },
- },
- vertexShader: `
- varying vec2 vUv;
- void main(){
- vUv = uv;
- gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
- }
- `,
- fragmentShader: `
- varying vec2 vUv;
- uniform sampler2D tDiffuse;
- uniform sampler2D uNormalMap;
- uniform float uTime;
- void main(){
-
- //通过时间和uv控制场景的摆动
- vec2 newUv = vUv;
- newUv += sin(newUv.x*10.0+uTime*0.5)*0.03;
-
- vec4 color = texture2D(tDiffuse,newUv);
- // gl_FragColor = vec4(vUv,0.0,1.0);
- vec4 normalColor = texture2D(uNormalMap,vUv);
- // 设置光线的角度
- vec3 lightDirection = normalize(vec3(-5,5,2)) ;
- //设置亮度效果
- float lightness = clamp(dot(normalColor.xyz,lightDirection),0.0,1.0) ;//前置函数
- color.xyz+=lightness;
- gl_FragColor = color;
- }
- `,
- });
- techPass.material.uniforms.uNormalMap.value = normalTexture;
- effectComposer.addPass(techPass);
5)在声明函数中挂载effectComposer
- const clock = new THREE.Clock();
- function animate(t) {
- controls.update();
- const time = clock.getElapsedTime();
- requestAnimationFrame(animate);
- // 使用渲染器渲染相机看这个场景的内容渲染出来
- // renderer.render(scene, camera);
- techPass.material.uniforms.uTime.value = time;
- effectComposer.render();
- }
-
- animate();
6)实现效果:
7)全部源码:
main.js:
- import * as THREE from "three";
-
- import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
- import gsap from "gsap";
- import * as dat from "dat.gui";
- import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader.js";
- import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
-
- // 导入后期效果合成器
- import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer";
-
- // three框架本身自带效果
- import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass";
- import { DotScreenPass } from "three/examples/jsm/postprocessing/DotScreenPass";
- import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass";
- import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass";
- import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
-
- // 目标:后期处理
-
- //创建gui对象
- const gui = new dat.GUI();
-
- // console.log(THREE);
- // 初始化场景
- const scene = new THREE.Scene();
-
- // 创建透视相机
- const camera = new THREE.PerspectiveCamera(
- 75,
- window.innerHeight / window.innerHeight,
- 1,
- 50
- );
- // 设置相机位置
- // object3d具有position,属性是1个3维的向量
- camera.position.set(0, 0, 3);
- // 更新摄像头
- camera.aspect = window.innerWidth / window.innerHeight;
- // 更新摄像机的投影矩阵
- camera.updateProjectionMatrix();
- scene.add(camera);
-
- // 加入辅助轴,帮助我们查看3维坐标轴
- // const axesHelper = new THREE.AxesHelper(5);
- // scene.add(axesHelper);
-
- // 加载纹理
-
- // 创建纹理加载器对象
- const textureLoader = new THREE.TextureLoader();
-
- // 添加环境纹理
- const cubeTextureLoader = new THREE.CubeTextureLoader();
- const envMapTexture = cubeTextureLoader.load([
- "textures/environmentMaps/0/px.jpg",
- "textures/environmentMaps/0/nx.jpg",
- "textures/environmentMaps/0/py.jpg",
- "textures/environmentMaps/0/ny.jpg",
- "textures/environmentMaps/0/pz.jpg",
- "textures/environmentMaps/0/nz.jpg",
- ]);
- scene.background = envMapTexture;
- scene.environment = envMapTexture;
-
- const directionLight = new THREE.DirectionalLight("#ffffff", 1);
- directionLight.castShadow = true;
- directionLight.position.set(0, 0, 200);
- scene.add(directionLight);
-
- // 模型加载
- const gltfLoader = new GLTFLoader();
- gltfLoader.load("./models/DamagedHelmet/glTF/DamagedHelmet.gltf", (gltf) => {
- console.log(gltf);
- // scene.add(gltf.scene)
- const mesh = gltf.scene.children[0];
-
- scene.add(mesh);
- });
-
- // 初始化渲染器
- const renderer = new THREE.WebGLRenderer();
- // 设置渲染尺寸大小
- renderer.setSize(window.innerWidth, window.innerHeight);
- renderer.shadowMap.enabled = true;
-
- // 合成效果
- const effectComposer = new EffectComposer(renderer);
- effectComposer.setSize(window.innerWidth, window.innerHeight);
-
- // 添加渲染通道
- const renderPass = new RenderPass(scene, camera);
- effectComposer.addPass(renderPass);
-
- // 点效果
- const dotScreenPass = new DotScreenPass();
- dotScreenPass.enabled = false;
- effectComposer.addPass(dotScreenPass);
-
- // 抗锯齿
- const smaaPass = new SMAAPass();
- effectComposer.addPass(smaaPass);
-
- // 发光效果
- const unrealBloomPass = new UnrealBloomPass();
- effectComposer.addPass(unrealBloomPass);
- unrealBloomPass.strength = 1;
- unrealBloomPass.radius = 0;
- unrealBloomPass.threshold = 1;
-
- //设置色调映射
- renderer.toneMapping = THREE.ACESFilmicToneMapping;
- renderer.toneMappingExposure = 1;
-
-
- gui.add(renderer, "toneMappingExposure").min(0).max(2).step(0.01);
- gui.add(unrealBloomPass, "strength").min(0).max(2).step(0.01);
- gui.add(unrealBloomPass, "radius").min(0).max(2).step(0.01);
- gui.add(unrealBloomPass, "threshold").min(0).max(2).step(0.01);
-
- //定义颜色参数
- const colorParams = {
- r: 0,
- g: 0,
- b: 0,
- };
- // 着色器写渲染通道
- const shaderPass = new ShaderPass({
- uniforms: {
- tDiffuse: {
- value: null,
- },
- uColor: {
- value: new THREE.Color(colorParams.r, colorParams.g, colorParams.b),
- },
- },
- vertexShader: `
- varying vec2 vUv;
- void main(){
- vUv = uv;
- gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
- }
- `,
- fragmentShader: `
- varying vec2 vUv;
- uniform sampler2D tDiffuse;
- uniform vec3 uColor;
- void main(){
- vec4 color = texture2D(tDiffuse,vUv);
- // gl_FragColor = vec4(vUv,0.0,1.0);
- color.xyz+=uColor;
- gl_FragColor = color;
- }
- `,
- });
-
- effectComposer.addPass(shaderPass);
-
- gui
- .add(colorParams, "r")
- .min(-1)
- .max(1)
- .step(0.01)
- .onChange((value) => {
- shaderPass.uniforms.uColor.value.r = value;
- });
- gui
- .add(colorParams, "g")
- .min(-1)
- .max(1)
- .step(0.01)
- .onChange((value) => {
- shaderPass.uniforms.uColor.value.g = value;
- });
- gui
- .add(colorParams, "b")
- .min(-1)
- .max(1)
- .step(0.01)
- .onChange((value) => {
- shaderPass.uniforms.uColor.value.b = value;
- });
- // 监听屏幕大小改变的变化,设置渲染的尺寸
- window.addEventListener("resize", () => {
- // console.log("resize");
- // 更新摄像头
- camera.aspect = window.innerWidth / window.innerHeight;
- // 更新摄像机的投影矩阵
- camera.updateProjectionMatrix();
-
- // 更新渲染器
- renderer.setSize(window.innerWidth, window.innerHeight);
- // 设置渲染器的像素比例
- renderer.setPixelRatio(window.devicePixelRatio);
-
- effectComposer.setSize(window.innerWidth, window.innerHeight);
- effectComposer.setPixelRatio(window.devicePixelRatio);
- });
-
- //添加法相纹理
- const normalTexture = textureLoader.load("./textures/interfaceNormalMap.png");
-
- const techPass = new ShaderPass({
- uniforms: {
- tDiffuse: {
- value: null,
- },
- uNormalMap: {
- value: null,
- },
- uTime: {
- value: 0,
- },
- },
- vertexShader: `
- varying vec2 vUv;
- void main(){
- vUv = uv;
- gl_Position = projectionMatrix*modelViewMatrix*vec4(position,1.0);
- }
- `,
- fragmentShader: `
- varying vec2 vUv;
- uniform sampler2D tDiffuse;
- uniform sampler2D uNormalMap;
- uniform float uTime;
- void main(){
-
- //通过时间和uv控制场景的摆动
- vec2 newUv = vUv;
- newUv += sin(newUv.x*10.0+uTime*0.5)*0.03;
-
- vec4 color = texture2D(tDiffuse,newUv);
- // gl_FragColor = vec4(vUv,0.0,1.0);
- vec4 normalColor = texture2D(uNormalMap,vUv);
- // 设置光线的角度
- vec3 lightDirection = normalize(vec3(-5,5,2)) ;
- //设置亮度效果
- float lightness = clamp(dot(normalColor.xyz,lightDirection),0.0,1.0) ;//前置函数
- color.xyz+=lightness;
- gl_FragColor = color;
- }
- `,
- });
- techPass.material.uniforms.uNormalMap.value = normalTexture;
- effectComposer.addPass(techPass);
-
- // 将渲染器添加到body
- document.body.appendChild(renderer.domElement);
-
- // 初始化控制器
- const controls = new OrbitControls(camera, renderer.domElement);
- // 设置控制器阻尼
- controls.enableDamping = true;
- // 设置自动旋转
- // controls.autoRotate = true;
-
- const clock = new THREE.Clock();
- function animate(t) {
- controls.update();
- const time = clock.getElapsedTime();
- requestAnimationFrame(animate);
- // 使用渲染器渲染相机看这个场景的内容渲染出来
- // renderer.render(scene, camera);
- techPass.material.uniforms.uTime.value = time;
- effectComposer.render();
- }
-
- animate();