上节把底座画好了:

这节我们加上经文,就是类似这种文字雨效果:

在那之前,我们给佛祖加上发光特效。
这个要用后期通道来做。

创建 EffectComposer、RenderPass,并且添加一个伽马校正的 pass 避免色差。
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
const gammaPass= new ShaderPass(GammaCorrectionShader);
composer.addPass(gammaPass);
const clock = new THREE.Clock();
function render() {
const delta = clock.getDelta();
// renderer.render(scene, camera);
composer.render();
requestAnimationFrame(render);
if(batchRenderer) {
batchRenderer.update(delta);
}
}
render();
然后加上描边 pass:

const v = new THREE.Vector2(window.innerWidth, window.innerWidth);
const outlinePass = new OutlinePass(v, scene, camera);
outlinePass.visibleEdgeColor.set('lightyellow');
outlinePass.edgeStrength = 10;
outlinePass.edgeThickness = 10;
outlinePass.pulsePeriod = 5;
outlinePass.selectedObjects = [mesh];
composer.addPass(outlinePass);
描边厚度是 10,强度是 10, 5s 闪烁一次
这里用了淡黄色,不然都是金色不太明显。

现在就有闪烁的轮廓了。
然后再加上另一个发光 pass:

const bloomPass = new UnrealBloomPass(v);
bloomPass.strength = 0.2;
composer.addPass(bloomPass);
指定发光强度。

这样整个画面就比较亮了。
然后来加文字雨。
这个从上往下落,也是粒子效果,用 three.quarks 的 GridEmitter 就行
之前我们做过落叶效果:

原理差不多。
创建 text-rain.js
import * as THREE from "three";
import SpriteText from "three-spritetext";
import { AxisAngleGenerator, BatchedParticleRenderer,ConeEmitter, ConstantValue, DonutEmitter, GridEmitter, IntervalValue, Noise, ParticleSystem, RandomColor, RectangleEmitter, RenderMode, Rotation3DOverLife, TextureSequencer, Vector3, Vector4 } from "three.quarks";
const group = new THREE.Group();
const batchRenderer = new BatchedParticleRenderer();
group.add(batchRenderer);
const figureText = new SpriteText('卐', 30);
figureText.color = 'gold';
const geometry = new THREE.PlaneGeometry(20, 20);
const particles = new ParticleSystem({
duration: 20,
looping: true,
instancingGeometry: geometry,
startLife: new ConstantValue(20),
startSpeed: new IntervalValue(100, 200),
startSize: new IntervalValue(1, 3),
startColor: new RandomColor(
new Vector4(1, 0.7, 0, 1),
new Vector4(1, 1, 1, 1)
),
startRotation: new IntervalValue(Math.PI / 6, Math.PI / 3),
emissionOverTime: new IntervalValue(10, 30),
shape: new GridEmitter({
width: 1500,
height: 1000,
column: 20,
row: 20
}),
renderMode: RenderMode.Mesh,
material: new THREE.MeshBasicMaterial({
map: figureText.material.map,
transparent: true,
side: THREE.DoubleSide
})
});
group.add(particles.emitter);
particles.emitter.rotateX(Math.PI / 2);
particles.emitter.position.y = 600;
batchRenderer.addSystem(particles);
export {
batchRenderer
}
export default group;
用 GridEmitter 从上往下撒,20 行 20 列。
这里用 Mesh 模式,渲染 mesh。
具体的纹理用 SpriteText 画好之后取 sprite.material.map
main.js 里引入下:


import textRain, { batchRenderer as br } from './text-rain.js';
scene.add(textRain);
if(br) {
br.update(delta);
}

现在掉落的范围能覆盖整个场景。
然后加一下文字的旋转、噪音:

particles.addBehavior(
new Rotation3DOverLife(
new AxisAngleGenerator(
new THREE.Vector3(0, 1, 1).normalize(),
new IntervalValue(Math.PI / 10, Math.PI)
)
)
)
particles.addBehavior(
new Noise(
new ConstantValue(0.2),
new IntervalValue(100, 300)
)
)
加两个自定义行为
一个是绕着一个轴旋转,从 Math.PI / 10 到 Math.PI
另一个是噪音,第一个参数是改变频率,第二个参数是改变的幅度。这个会影响位置。
看下效果:

有一些特别近的文字,可以在视野里截掉


这样,文字雨效果就完成了。
最后我们加一面镜子:

const mirror = new Reflector(geometry, {
color: 'gold',
textureWidth: window.innerWidth * window.devicePixelRatio,
textureHeight: window.innerHeight * window.devicePixelRatio,
});
mirror.position.z = -1;
group.add(mirror);
镜子也是金色的。

案例代码上传了小册仓库
总结
这节我们给 3D 场景加上了文字雨效果,并且加了后期通道实现了发光。
我们加了效果处理器,并加了伽马校正、发光、描边三个通道。
用描边实现了闪烁、发光提亮整个场景、伽马校正坐颜色修正
然后用 three.quarks 的 GridEmitter 实现了文字雨效果。
用 Reflector 加上了镜面效果。
下节我们来加上入场动画。