ThreeJS——机房Demo(四)
ThreeJS —— 机房Demo(四)
上⼀节我们提到了光圈效果,除了这种光效,还有⼀个光效是3D可视化常⽤的,那就是辉光效果
⽬录结构
├── font // 字体⽂件
|├──── f // 字体源⽂件
|└──── 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(){
// ...
// der(scene, camera);
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>
效果图:
部分辉光效果
上⾯虽然实现了辉光效果,不过它将所有的物体,⼀切场景都添加了辉光,⽽我们的实际需求是只需要部分物体实现辉光
部分辉光效果原理:
1. 准备两个EffectComposer,⼀个 bloomComposer ⽤来产⽣辉光效果,另⼀个 finalComposer ⽤来正常渲染整个场景
2. 将除辉光物体外的其他物体的材质转成⿊⾊
3. 在 bloomComposer 中利⽤ BloomPass 产⽣辉光,但这⾥需要设置 derToScreen = false; 表⽰不渲染到
屏幕上
4. 将转成⿊⾊材质的物体还原成初始材质
5. ⽤ 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");
const material =new THREE.MeshBasicMaterial({ map: texture });
const mesh =new THREE.Mesh(geometry, material);
initConfig(mesh, conf);
able(1);// 与编号为1的图层建⽴关系,并切换到该图层。⼀定不能⽤ mesh.layers.set(1); 因为 set 会删除已有关系的图层,如果0图层没有了,那⽤ finalComposer 渲染的时候将渲染不了这个物体
return mesh;
}
编写效果处理器代码
// composer_fn.js
function createComposer(){
const renderPass =new THREE.RenderPass(scene, camera);// 两个composer都要⽤到这个renderPass,所以在前⾯公共部分声明
// bloomComposer效果合成器产⽣辉光,但是不渲染到屏幕上
const bloomComposer =new THREE.EffectComposer(renderer);
const bloomPass =createUnrealBloomPass();
bloomComposer.addPass(renderPass);
bloomComposer.addPass(bloomPass);
// 最终真正渲染到屏幕上的效果合成器 finalComposer
const finalComposer =new THREE.EffectComposer(renderer);
const shaderPass =createShaderPass(bloomComposer);// 创建⾃定义的着⾊器Pass,详细见下
finalComposer.addPass(renderPass);
finalComposer.addPass(shaderPass);
return{ bloomComposer, finalComposer };
}
// ShaderPass,着⾊器pass,⾃定义程度⾼,需要编写OpenGL代码
// 传⼊bloomComposer
function createShaderPass(bloomComposer){
// 着⾊器材质,⾃定义shader渲染的材质
const shaderMaterial =new THREE.ShaderMaterial({
uniforms:{
baseTexture:{ value:null},
bloomTexture:{ value: ure },// 辉光贴图属性设置为传⼊的bloomComposer,这⾥就说明了为什么bloomComposer 不要渲染到屏幕上
},
vertexShader: ElementById("vertexshader").textContent,// 顶点着⾊器
fragmentShader: ElementById("fragmentshader").textContent,// ⽚元着⾊器
defines:{},
});
const shaderPass =new THREE.ShaderPass(shaderMaterial,"baseTexture");
return shaderPass;
}
在⼊⼝⽂件 index.html 中,运⽤效果处理器,实现部分辉光
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<div>...</div>
<!-- 着⾊器代码 -->
<script type="x-shader/x-vertex"id="vertexshader">
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix *vec4( position,1.0);
实现特效的代码js}
</script>
<script type="x-shader/x-fragment"id="fragmentshader">
uniform sampler2D baseTexture;
uniform sampler2D bloomTexture;
varying vec2 vUv;
vec4 getTexture( sampler2D texelToLinearTexture ){
return mapTexelToLinear(texture2D( texelToLinearTexture , vUv ));
}
void main(){
gl_FragColor =(getTexture( baseTexture )+vec4(1.0)*getTexture( bloomTexture ));
}
</script>
<script src="..."></script>
<script>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论