ThreeJS —— 机房Demo(四)
上一节我们提到了光圈效果,除了这种光效,还有一个光效是3D可视化常用的,那就是辉光效果
目录结构
├── font // 字体文件
|├──── font.ttf // 字体源文件
|└──── font.json // 转换后的字体文件
├── img // 素材图片
|├──── xx.png
|├──── xxx.jpg
|└──── …
├── js // 自己编写的js文件
|├──── composer_fn.js // 后期处理
|├──── create_fn.js // 创建各种几何
|├──── init_fn.js // 初始化项目
|└──── util_fn.js // 工具函数
├── lib // 需要引入的js文件
|├──── three.js
|├──── OrbitControls.js
|├──── RenderPass.js
|└──── …
├── model // 建模工具导出的模型
|├──── computer.gltf
|└──── …
└── index.html // 入口文件
创建辉光效果
有的时候我们希望某个几何体能更附加一层辉光特效,这样物体将更生动
效果合成器 EffectComposer
要想实现辉光效果,就是实现后期处理效果,需要用到效果合成器 EffectComposer,所以我们新建一个 composer_fn.js 文件,专门用来写后期处理的函数,然后在 index.html 中引入该js文件
// composer_fn.js
function createComposer() {
// 后期处理的通常步骤:
// 1. 创建一个 EffectComposer,假设命名为composer
// 2. 给composer加入(addPass)各种通道
// 通常第一个加入的通道是RenderPass,后续可以看需求选择加入的通道类型和顺序,例如这里后续就用到了BloomPass
const bloomComposer = new THREE.EffectComposer(renderer);
const renderPass = new THREE.RenderPass(scene, camera);
const bloomPass = createUnrealBloomPass(); // 我们封装好的 createUnrealBloomPass 函数,用来创建BloomPass(辉光效果)
bloomComposer.addPass(renderPass);
bloomComposer.addPass(bloomPass);
return bloomComposer;
}
// UnrealBloomPass,辉光效果
function createUnrealBloomPass() {
const bloomPass = new THREE.UnrealBloomPass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
1.5,
0.4,
0.85
);
const params = {
exposure: 1,
bloomThreshold: 0.2,
bloomStrength: 0.5, // 辉光强度
bloomRadius: 0,
};
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
return bloomPass;
}
除了在 index.html 引入该js文件,还需要引入效果合成器所需要的js文件(这些文件都能在ThreeJS的源码的example目录下找到),并且将render方法改用composer的render
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<script src="..."></script>
<!-- 后期处理,效果合成器所需的一些js文件 -->
<script src="lib/EffectComposer.js"></script>
<script src="lib/ShaderPass.js"></script>
<script src="lib/RenderPass.js"></script>
<script src="lib/CopyShader.js"></script>
<script src="lib/LuminosityHighPassShader.js"></script>
<script src="lib/UnrealBloomPass.js"></script>
<script>
// ...
const composer = createComposer();
function animate() {
// ...
// renderer.render(scene, camera);
composer.render(); // 将以前的render方法注释,换成composer的render
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
效果图:
部分辉光效果
上面虽然实现了辉光效果,不过它将所有的物体,一切场景都添加了辉光,而我们的实际需求是只需要部分物体实现辉光
部分辉光效果原理:
- 准备两个EffectComposer,一个 bloomComposer 用来产生辉光效果,另一个 finalComposer 用来正常渲染整个场景
- 将除辉光物体外的其他物体的材质转成黑色
- 在 bloomComposer 中利用 BloomPass 产生辉光,但这里需要设置 bloomComposer.renderToScreen = false; 表示不渲染到屏幕上
- 将转成黑色材质的物体还原成初始材质
- 用 finalComposer 开始渲染,其中 finalComposer 需要加入一个通道(addPass),该通道利用了 bloomComposer 的渲染结果
Three中为所有的几何体分配 1个到 32 个图层,编号从 0 到 31,所有几何体默认存储在第 0 个图层上,为了更好的区分辉光物体和非辉光物体,我们需要利用 Layer 创建一个图层,把辉光物体额外添加在一个新的图层上
// create_fn.js
// 创建一个 Layer,用于区分辉光物体
function createLayer(num) {
const layer = new THREE.Layers();
layer.set(num);
return layer;
}
// 在 index.html 中使用
const bloomLayer = createLayer(1); // 创建一个新的图层,编号为1
// 然后往所有辉光物体中,添加一个新的图层,这里用我们之前写的机器为例
// create_fn.js
function createEarth(conf) {
const geometry = new THREE.SphereBufferGeometry(5, 64, 64);
const texture = new THREE.TextureLoader().load("./img/earth.png"