前言
特效合成器(英文名:Special Effects Compositor)指的是一种计算机软件,用于将不同的视觉特效、图像和视频元素合成在一起,以创造出各种令人惊叹的视觉效果。通常,特效合成器是电影制作、电视节目制作和广告制作等行业中用于增强影像和视频质量的一个重要工具。特效合成器可以使用各种技术,如蓝/绿屏合成、3D建模、摄影和覆盖等,以创建高质量的视觉特效。常用的特效合成器软件包括Nuke、After Effects和Fusion等。
一、特效合成器
1.RenderPass
RenderPass是Three.js中的一个渲染通道,用于执行一些基本的渲染操作,例如将场景绘制到屏幕上。在RenderPass中,会指定一个场景、一个相机和一个渲染目标,然后将这个渲染目标作为输出,交给下一个后置通道进行处理,从而构建出完整的后置处理效果。
RenderPass的实现流程如下:
1.首先指定需要绘制的场景和相机。
2.创建渲染目标,并且利用场景和相机将场景渲染到该目标上。
3.将渲染目标后置处理输出到下一个后置通道中。
RenderPass的使用场景通常是场景中包含多种材质状态对象或者光源状态对象等,并且需要进行多个通道之间的后置处理。例如在Three.js中实现后期处理,通常需要配置多个后置处理通道,通过RenderPass可以将场景渲染到渲染目标中,然后传递给下一个后置处理通道进行处理。
2.OutlinePass
OutlinePass是Three.js中的一种特殊的后期处理效果,用于实现物体轮廓的高亮效果。OutlinePass能够将被选中的物体描边,并在该物体周围呈现一种发光的效果。
使用OutlinePass需要先添加Three.js中的一些特定组件,如EffectComposer和RenderPass。然后,可以将OutlinePass添加到EffectComposer中。
下面是一个例子,展示如何使用OutlinePass:
// 新建一个EffectComposer
const composer = new THREE.EffectComposer(renderer);
// 新建一个RenderPass,这是渲染场景的第一步
const renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);
// 新建一个OutlinePass,并将其添加到EffectComposer中
const outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
composer.addPass(outlinePass);
// 将轮廓的颜色和宽度设置到OutlinePass中
outlinePass.edgeStrength = 5; // 轮廓强度
outlinePass.edgeGlow = 0.5; // 轮廓的发光强度
outlinePass.edgeThickness = 2; // 轮廓的宽度
// 将需要高亮的物体传递给OutlinePass
outlinePass.selectedObjects = [object];
需要注意的是,使用OutlinePass需要在每个动画帧中更新它,这可以通过将composer.render()方法放置在requestAnimationFrame函数中来实现。
function animate() {
requestAnimationFrame(animate);
composer.render();
}
animate();
3.EffectComposer
EffectComposer是Three.js中的一个类,它允许您将多个渲染通道组合在一起以创建最终的渲染结果。它是一个非常强大的工具,可以用来创建各种各样的视觉效果,例如后期处理、光照效果等。
使用EffectComposer的基本步骤如下:
-
创建一个EffectComposer实例。
-
创建一个或多个渲染通道(Render Pass)。每个渲染通道可以使用不同的材质、摄像机和渲染目标。
-
将渲染通道添加到EffectComposer实例中。
-
在每个渲染帧中,通过EffectComposer实例进行渲染。这将执行所有添加到EffectComposer中的渲染通道,并将它们组合成一个最终的渲染结果。
例如,以下代码展示了如何使用EffectComposer创建一个简单的后期处理效果:
// 创建EffectComposer实例
var composer = new THREE.EffectComposer(renderer);
// 创建渲染通道
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);
// 添加后期处理效果
var effect = new THREE.ShaderPass(THREE.DotScreenShader);
effect.uniforms.scale.value = 4;
composer.addPass(effect);
// 渲染帧
composer.render();
在这个例子中,我们首先创建一个EffectComposer实例,然后创建一个RenderPass渲染通道,将其添加到EffectComposer中。然后,我们创建一个ShaderPass渲染通道,使用DotScreenShader着色器来创建一个点阵效果,将其添加到EffectComposer中。最后,在每个渲染帧中,我们使用EffectComposer实例来渲染场景,并应用所有添加的渲染通道,以产生最终的渲染结果。
4.案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
</style>
</head>
<body>
</body>
</html>
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/[email protected]';
import {
OrbitControls } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls.js'
import {
EffectComposer } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/postprocessing/EffectComposer.js'
import {
RenderPass } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/postprocessing/RenderPass.js'
import {
OutlinePass } from 'https://cdn.skypack.dev/[email protected]/examples/jsm/postprocessing/OutlinePass.js'
const clock = new THREE.Clock()
// 创建一个场景
const scene = new THREE.Scene();
// 创建一个相机 视点
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
// 设置相机的位置
camera.position.set(100,100,0);
camera.lookAt(new THREE.Vector3(0,0,0));
// 创建一个渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
const controls = new OrbitControls(camera, renderer.domElement)
document.body.appendChild(renderer.domElement);
// 添加灯光
const spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(2000,8000,4000);
scene.add(spotLight);
const g1 = new THREE.BoxGeometry(18,18,18);
const g2 = new THREE.BoxGeometry(18,18,18);
const m1 = new THREE.MeshBasicMaterial({
color: 0x00ff00
})
const m2 = new THREE.MeshBasicMaterial({
color: 0xff0000
})
const c1 = new THREE.Mesh(g1, m1)
const c2 = new THREE.Mesh(g2, m2)
c1.position.y = 20;
c2.position.y = -20;
scene.add(c1)
scene.add(c2)
// 辉光效果
// 创建了一个渲染通道,这个通道会渲染场景,不会渲染到屏幕上
const renderScene = new RenderPass(scene, camera);
// 分辨率 场景 相机 当前选中的物体,(需要添加辉光效果)
const outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera, [c2, c1])
outlinePass.renderToScreen = true; // 渲染到屏幕上
outlinePass.edgeStrength = 3; // 尺寸
outlinePass.edgeGlow = 2; // 发光的强度
outlinePass.edgeThickness = 2; // 光晕粗细
outlinePass.pulsePeriod = 1;// 闪烁的速度
outlinePass.visibleEdgeColor.set('yellow');
// 创建一个组合器对象,添加处理通道
const bloom = new EffectComposer(renderer)
bloom.setSize(window.innerWidth, window.innerHeight)
bloom.addPass(renderScene)
bloom.addPass(outlinePass)
const animation = () => {
// 渲染
renderer.render(scene, camera);
bloom.render();
requestAnimationFrame(animation);
}
animation()
</script>