物体发光效果非常炫酷,本期来讲three场景内物体自带发光效果怎么来实现。本次使用的是threejs138版本,在vue3+vite+ant的项目中使用。
下面来看看实现的效果。绿色罐体有了明显的发光效果。
实现步骤
-
增加composer.js
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js'
import scene from '../scene';
import camera from '../camera';
import renderer from '../renderer';
import * as THREE from 'three';
const effectComposer = new EffectComposer(renderer.renderer)
const renderPass = new RenderPass(scene, camera)
effectComposer.addPass(renderPass)
//创建UnrealBloomPass泛光通道
const unrealBloomPass = new UnrealBloomPass(
//参数一:泛光覆盖场景大小,二维向量类型
new THREE.Vector2(window.innerWidth, window.innerHeight),
//参数二:bloomStrength 泛光强度,值越大明亮的区域越亮,较暗区域变亮的范围越广
2,
//参数三:bloomRadius 泛光散发半径
1,
//参数四:bloomThreshold 泛光的光照强度阈值,如果照在物体上的光照强度大于该值就会产生泛光
0.05
)
unrealBloomPass.renderToScreen = false
const composer = new EffectComposer(renderer.renderer)
composer.renderToScreen = false
composer.addPass(new RenderPass(scene, camera))
composer.addPass(unrealBloomPass)
// var params = {
// exposure: 0,
// bloomStrength: 0.2,
// bloomThreshold: 0,
// bloomRadius: 0,
// };
// unrealBloomPass.threshold = params.bloomThreshold;
// unrealBloomPass.strength = params.bloomStrength;
// unrealBloomPass.radius = params.bloomRadius;
// 着色器
let shaderPass = new ShaderPass(new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: composer.renderTarget2.texture },
tDiffuse: {
value: null
}
},
vertexShader:'\t\t\tvarying vec2 vUv;\n' +
'\n' +
'\t\t\tvoid main() {\n' +
'\n' +
'\t\t\t\tvUv = uv;\n' +
'\n' +
'\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n' +
'\n' +
'\t\t\t}',
fragmentShader:'\t\t\tuniform sampler2D baseTexture;\n' +
'\t\t\tuniform sampler2D bloomTexture;\n' +
'\n' +
'\t\t\tvarying vec2 vUv;\n' +
'\n' +
'\t\t\tvoid main() {\n' +
'\n' +
'\t\t\t\tgl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n' +
'\n' +
'\t\t\t}',
defines: {}
}), 'baseTexture')
shaderPass.renderToScreen = false
shaderPass.needsSwap = true
//将创建的通道添加到EffectComposer(效果组合器)对象中
effectComposer.addPass(shaderPass)
const effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader)
effectComposer.addPass(effectColorSpaceConversion)
export default {composer,effectComposer};
-
在animate里面重复调用,
- 以下着重注意的点有三点。
- Composer.composer的引入位置必须是在renderer.render()之后。否则不能出来效果。
- Composer.effectComposer的位置必须是在最后,否则合成器不能展示成功。
- glowMaterialList 里面的值是需要发光的物体名称,可以通过mitt或者vuex或者watch监听等方法来同步监听。
import camera from './camera';
import renderer from './renderer';
import controls from './controls';
import scene from './scene';
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min';
import composer from './modify/composer';
import * as THREE from 'three';
var materials ={
scene:null,
}
var glowMaterialList=['Cylinder022']
function animate() {
controls.update();
TWEEN.update();
// 使用渲染器渲染相机看这个场景的内容渲染出来
renderer.renderer.render(scene, camera);
// 将不需要处理辉光的材质进行存储备份
scene.traverse((v) => {
// 备份一份场景背景然后清空
if (v instanceof THREE.Scene) {
materials.scene = v.background
v.background = null
}
if (!glowMaterialList.includes(v.name) && v.isMesh) {
// 备份当前材质内容
materials[v.uuid] = v.material
// 将不需要辉光的材质设置为黑色
v.material = new THREE.MeshBasicMaterial({ color: 'black' })
}
})
if (composer.composer) { composer.composer.render() }
scene.traverse((v) => {
if (materials[v.uuid]) {
v.material = materials[v.uuid]
delete materials[v.uuid]
}
if (v instanceof THREE.Scene) {
v.background = materials.scene
delete materials.scene
}
})
if (composer.effectComposer) { composer.effectComposer.render() }
requestAnimationFrame(animate);
}
export default animate;
-
resize的时候增加适应屏幕
import camera from "./camera";
import rendererModule from "./renderer";
import composer from './modify/composer';
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
// 监听屏幕大小改变的变化,设置渲染的尺寸
window.addEventListener("resize", () => {
// console.log("resize");
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
// 更新摄像机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器
rendererModule.renderer.setSize(window.innerWidth, window.innerHeight);
// 设置渲染器的像素比例··
rendererModule.renderer.setPixelRatio(window.devicePixelRatio);
// 更新渲染器
composer.composer.setSize(window.innerWidth, window.innerHeight);
});
以上就是实现物体发光的步骤,只需要调节composer.js里面unrealBloomPass 的参数就可以调节到你需要的发光的亮度,如果还有不懂的可以联系我哦。