马黑PHP整站系统

ThreeJS后期处理

位置: 首页 > 前端三套件[ 发布时间: 2025.6.6  作者: 马黑  阅读: 32 ]

和电影拍完之后还要做一系列的后期处理一样,使用 ThreeJS 创作的图形作品也可以进行类似的工作。ThreeJS 的后期处理,指在按常规绘制好可能包含动画的图像之后,根据需要可以再添加相应的一个或多个效果,这个工作称作 Post Processing。后期处理本质上是一个相当复杂的工作机制,涉及到通道、合成技术等等问题,不过 ThreeJS 提供了一系列的解决方案,我们只需导入相应的库再按流程操作即可。

根据官方示例,以下是 ThreeJS 后期处理基本操作流程:

一、创建效果合成器 EffectComposer

const composer = new EffectComposer(renderer);

所创建的效果合成器示器实例 composer 将接管 renderer 渲染器渲染的结果,即后续应该使用的渲染方法 renderer.render(scene, camera); 将改用composer.render(); , 同时将管理调度各个通道 pass 的执行。形象一点讲,composer 搭建一个生产流水线,对之前 ThreeJS 绘制好的产品在各个通道层面进行效果合成然后渲染合成后的最终效果。

二、创建基础渲染通道 RenderPass

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

实例化渲染通道 RenderPass 是其它具体通道的通道,也就是说,后续的每一个具体特效通道 *Pass 都因为它的存在才能产生作用,所以也称此通道为基础通道。RenderPass 相当于流水线上的线长,它不从事具体的生产劳动,属于基层领导,它的作用是站线,别的事不干。RenderPass 任命(创建)后需要加入到 composer 合成器中,composer.addPass(renderPass);

三、创建具体效果通道 *Pass

ThreeJS 封装有一些具体的效果通道,命名为 *Pass,例如,点网效果通道,DotScreenPass,创建方式和基础渲染通道一样,都是先创建然后加入到合成器中:

const dotscreenPass = new DotScreenPass();
composer.addPass(dotscreenPass);
	

dotscreenPass 是实例化的 DotscreenPass,DotscreenPass 是 ThreeJS 封装的一个特效类(class),将其实例化后加入合成器 composer 中,该类封装的黑白点效果就会改变之前所绘制的图像。此类 ThreeJS 封装的 class 类有不少,还有第三方封装的其它特效可供选择。

效果合成器生产流水线 composer 上可以有很多个工位,每一个工位负责一个特定通道的效果处理,例如上例的点网效果。安排多少个工位取决于产品的设计需要,需要注意的是,一,每一个工位都要实例化一个具体的通道并立马将处理结果(即实例化变量)加入到效果合成器中,如你在点网效果通道代码示例中所看的那样;二,每一个通道特效都提供有默认的配置,这些配置可以根据需要另行设置。

四、渲染效果

当所有特定效果通道都建立完毕并一一加入到后期效果合成器 composer 之后,就可以使用 composer.render(); 来渲染效果,效果渲染工作通常放在动画函数中,若作品是静态图像也可以放在原先渲染器 renderer.render(scene, camera) 所在的地方。

五、导入依赖库

首先,不论使用了多少个 ThreeJS 封装的或第三方封装的后期效果处理库,EffectComposerRenderPass 这两个库都不能缺失;其次,具体要使用哪个特定效果通道库就对应导入相应的库,各库的导入都应是在创建了 ThreeJS 场景(scene)、相机(camera)、渲染器(renderer)等之后操作。

下面的实例我们在绘制好一个几何体图像的基础上进行后期处理:一是加入高亮描边特效通道 OutlinePass,使用了一些参数设置,其中描边的闪烁属性放在动画函数里;二是加入默认设置的电影胶片颗粒特效通道 FilmPass

<div style="position: absolute; padding: 10px; color: #333;">单击页面暂停/继续动画</div>

<!-- ThreeJS扩展库内部可能使用相对路径,因此需要通过映射方式导入 -->
<script type="importmap">
{
	"imports": {
		"three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
		"three/addons/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
	}
}
</script>

<script type="module">
	import * as THREE from 'three'; // ThreeJS主库,下面的都是扩展库
	import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; // 效果合成库
	import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; // 渲染器基础通道库
	import { FilmPass } from 'three/addons/postprocessing/FilmPass.js'; // 电影风格库
	import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js'; // 高亮描边通道库

	const scene = new THREE.Scene();
	const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
	camera.position.z = 10;
	const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); // alpha将因为因辉光库缺陷而失效
	renderer.setSize(window.innerWidth, window.innerHeight);
	const clock = new THREE.Clock();
	document.body.appendChild(renderer.domElement);

	// 绘制图像 圆环扭结几何体 + 法向量网格材质
	const mesh = new THREE.Mesh(
		new THREE.TorusKnotGeometry(),
		new THREE.MeshNormalMaterial()
	);
	scene.add(mesh); // 图像加入到场景

	// 创建效果合成器
	const composer = new EffectComposer(renderer);

	// 创建渲染(基础)通道并加入效果合成器
	const renderPass = new RenderPass(scene, camera);
	composer.addPass(renderPass);

	// 创建第一个效果 : 高亮描边通道并加入效果合成器(三个参数:渲染二维向量、场景、相机)
	const outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
	outlinePass.visibleEdgeColor.set(0xBA55D3); // 描边颜色(缺省默认白色)
	outlinePass.edgeThickness = 4; // 描边厚度
	outlinePass.edgeStrength = 6; // 描边光亮强度
	outlinePass.selectedObjects = [mesh]; // 描边作用对象
	composer.addPass(outlinePass); // 描边效果通道加入到后期效果合成器

	// 创建第二个效果 :老电影胶片颗粒
	const filmPass = new FilmPass();
	composer.addPass(filmPass);

	// 动画
	const animate = () => {
		requestAnimationFrame(animate);
		const delta = clock.getDelta();
		mesh.rotation.x += delta / 5;
		mesh.rotation.y += delta / 5;
		outlinePass.pulsePeriod = delta === 0 ? 0 : 1; // 描边闪烁
		composer.render(); // 后期合成效果
	};

	document.onclick = () => clock.running ? clock.stop() : clock.start(); // 动画交互

	animate(); //运行动画
</script>

【附】后期处理通道汇总

API效果说明
AdaptiveToneMappingPass根据场景光照强度自动调节场景亮度
BloomPass增强场景中的明亮区域模拟现实世界中的摄像机
BokehPass实现类似于大光圈镜头的景深效果
ClearPass清空纹理缓存
CubeTexturePass渲染天空盒
DotScreenPass将黑点图层应用到屏幕的原始图片上
FilmPass通过扫描线和失真来模拟电视屏幕效果
GlitchPass随机在屏幕上显示电脉冲
HalftonePass模拟传统印刷中的半色调效果,通过网格点大小和疏密表现亮度
MaskPass在当前区域添加掩码,后续的通道只会影响掩码区域
OutlinePass勾勒场景中的轮廓
RenderPass在当前场景和摄像机上渲染出一个新的场景
SAOPass 、SSAOPass实现实时环境光遮挡效果
SMAAPass、SSAARenderPass添加全屏反锯齿效果
SSAARenderPass根据场景光照强度自动调节场景亮度
SavePass反复当前的渲染效果
ShaderPass接收自定义的着色器,生成一个高级、自定义的后期处理通道
TAARenderPass一种全屏反锯齿效果
AdaptiveToneMappingPass根据场景光照强度自动调节场景亮度
TexturePass将其它组合器的当前状态保存为纹理,将其参数传入到其它的组合器里
UnrealBloomPass与Bloom类似的泛光,效果接近于Unreal 3D

前一篇: ThreeJS入门(十一)相机动画
下一篇: 没有了

发表评论:

       

评论列表 [1条]

#1 | 飞飞 于 2025-6-6 18:55 发布: 这个感觉更难一些,粗看一遍完全不能消化,需要时间反复细看

Copyright © 2023 All Right Reserved 马黑PHP文章管理整站系统v1.8
联系我们: gxblk@163.com