ThreeJS中的效果合成器
//outline pass 创建高亮轮廓
// 创建 Outline Pass,传入轮廓边框的大小,场景以及相机
const outLinePass = new OutlinePass(
new THREE.Vector2(outLine.value.offsetWidth,outLine.value.offsetWidth/2), // 轮廓边框大小
scene, // 场景
camera // 相机
);
// 设置轮廓边框的强度
outLinePass.edgeStrength = 3;
// 设置轮廓边框的炫光强度
outLinePass.edgeGlow = 2;
// 设置轮廓边框的粗细
outLinePass.edgeThickness = 3;
// 设置轮廓边框的动画效果周期(单位为秒)
outLinePass.pulsePeriod = 2;
// 设置需要进行轮廓边框高亮的物体,这里只选择了一个 torusKnot
outLinePass.selectedObjects = [torusKnot];
// 将 Outline Pass 添加到渲染的 Pass 中
composer.addPass(outLinePass);
// renderPass
/*
RenderPass 是 Three.js 中的一个渲染器通道,它用于将场景中的一部分物体单独渲染到屏幕上。RenderPass 可以用于实现多种效果,
例如描边(Outline)、后期处理(Post-processing)、阴影等。
Renderer 是 Three.js 中的渲染器,它是实现 Three.js 渲染功能的核心组件。
Renderer 主要负责将场景中的对象转换成可视图像,并输出到屏幕或者图片等媒介上。它支持多种渲染方式,例如 Canvas、WebGL、SVG等。
简单来讲,RenderPass 是 Renderer 的一种子组件,它主要用于实现某些特殊效果的渲染流程,
而 Renderer 则是 Three.js 的主渲染器,它负责将所有物体渲染到屏幕上或其他媒介上。
*/
//EffectComposer
/*
EffectComposer 是 Three.js 中用于实现后期处理(post-processing)效果的函数。
它可以将场景、相机和渲染器作为参数,并且可以将不同的 RenderPass 串联起来,形成连续的后期处理效果。
具体来说,EffectComposer 中会包含多个用于控制后期处理流程的渲染通道,如 RenderPass、ShaderPass 等。
实现后期处理效果一般需要多次渲染,其中第一次是将场景渲染到纹理(render-to-texture)中,然后应用渲染通道,最终将结果渲染到屏幕上。
*/
const composer = new EffectComposer(renderer);
composer.setSize(outLine.value.offsetWidth,outLine.value.offsetWidth/2);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
composer.render();
UnrealBloomPass
实现逼真的bloom(即景物周围余晖)效果
new THREE.Vector2( window.innerWidth, window.innerHeight )
:表示渲染的分辨率大小。strength
:效果强度,默认值为1。radius
:半径大小,默认值为0。threshold
:阈值大小,影响只有高于这个值的颜色才会产生bloom效果,默认值为0。
// 定义两个场景用于渲染全屏普通场景和只有发光效果的场景
const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
// 定义一个全局变量,用于标识需要渲染发光效果的物体
const bloomLayer = new THREE.Layers();
bloomLayer.set( BLOOM_SCENE );
// 定义一个黑色材质,用于替换发光物体原来的材质
const darkMaterial = new THREE.MeshBasicMaterial( { color: 'black' } );
const materials = {};
// 定义后期处理参数
const params = {
exposure: 1, // 曝光度
bloomStrength: 5, // 发光强度
bloomThreshold: 0, // 亮度阈值,用于发光对象的选择
bloomRadius: 0, // 发光的扩散半径
scene: 'Scene with Glow' // 默认场景类型
};
// 创建 UnrealBloomPass 后期处理器,用于实现物体发光效果
const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
// 创建一个普通场景渲染器
const renderScene = new RenderPass( scene, camera );
// 创建渲染器,用于渲染只有发光效果的场景
const bloomComposer = new EffectComposer( renderer );
bloomComposer.renderToScreen = false;
bloomComposer.addPass( renderScene );
bloomComposer.addPass( bloomPass );
// 初始化场景
function setupScene() {
scene.traverse( disposeMaterial );
scene.children.length = 0;
const geometry = new THREE.IcosahedronGeometry( 1, 15 );
for ( let i = 0; i < 50; i ++ ) {
const color = new THREE.Color();
color.setHSL( Math.random(), 0.7, Math.random() * 0.2 + 0.05 );
const material = new THREE.MeshBasicMaterial( { color: color } );
const sphere = new THREE.Mesh( geometry, material );
sphere.position.x = Math.random() * 10 - 5;
sphere.position.y = Math.random() * 10 - 5;
sphere.position.z = Math.random() * 10 - 5;
sphere.position.normalize().multiplyScalar( Math.random() * 4.0 + 2.0 );
sphere.scale.setScalar( Math.random() * Math.random() + 0.5 );
scene.add( sphere );
if ( Math.random() < 0.25 ) sphere.layers.enable( BLOOM_SCENE );
}
render();
}
// 渲染发光效果
function render( ) {
camera.layers.set( BLOOM_SCENE );
bloomComposer.render();
camera.layers.set( ENTIRE_SCENE );
}
function onPointerDown( event ) {
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
const intersects = raycaster.intersectObjects( scene.children, false );
if ( intersects.length > 0 ) {
const object = intersects[ 0 ].object;
object.layers.toggle( BLOOM_SCENE );
render();
}
}
//渲染不同的场景
//
// 渲染函数,根据 params 中定义的场景类型选择不同的渲染方式
function render() {
switch ( params.scene ) {
case 'Scene only':
renderer.render( scene, camera );
break;
case 'Glow only':
renderBloom( false );
break;
case 'Scene with Glow':
default:
// render scene with bloom
renderBloom( true );
// render the entire scene, then render bloom scene on top
finalComposer.render();
break;
}
}
// 渲染发光效果
function renderBloom( mask ) {
if ( mask === true ) { // 只渲染发光物体
scene.traverse( darkenNonBloomed );
bloomComposer.render();
scene.traverse( restoreMaterial );
} else { // 渲染整个场景包括发光效果
camera.layers.set( BLOOM_SCENE );
bloomComposer.render();
camera.layers.set( ENTIRE_SCENE );
}
}
function darkenNonBloomed( obj ) {
if ( obj.isMesh && bloomLayer.test( obj.layers ) === false ) {
materials[ obj.uuid ] = obj.material;
obj.material = darkMaterial;
}
}
function restoreMaterial( obj ) {
if ( materials[ obj.uuid ] ) {
obj.material = materials[ obj.uuid ];
delete materials[ obj.uuid ];
}
}
Powered by Waline v2.13.0