EffectComposerでポストプロセッシング

「Three.jsでポストプロセッシング」でポストプロセッシングを試しましたが、Three.jsのEffectComposerを試しました。※Three.jsはr128を使用しています。
EffectComposerでポストプロセッシング
EffectComposerを使用すると、ポストプロセッシングを簡単に実装できます。また、Three.jsにはカラーハーフトーンやグリッチ、ゴッドレイなどさまざなエフェクトが用意されています。
● ライブラリの読み込み
まず、必要なライブラリを読み込みます。EffectComposer.jsとRenderPass.jsの他に、それぞれから読みこまれている「examples > jsm > postprocessing」の中のShaderPass.js、MaskPass.js、Pass.js、「examples > jsm > shaders」の中のCopyShader.jsが必要になります。また、各ファイルの中のパスを必要に応じて修正します。
import { EffectComposer } from './lib/three_jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './lib/three_jsm/postprocessing/RenderPass.js';
● EffectComposerでポストプロセッシング
「examples > jsm > postprocessing」の中に各エフェクトのファイルがありまが、今回はカラーハーフトーンとグリッチをかけます。カラーハーフトーンとグリッチは、それぞれ「examples > jsm > shaders」の中のHalftoneShader.jsとDigitalGlitch.jsも必要です。エフェクトは複数組み合わせることもできます。
//エフェクトファイルを読み込み
import { HalftonePass } from './lib/three_jsm/postprocessing/HalftonePass.js';
import { GlitchPass } from './lib/three_jsm/postprocessing/GlitchPass.js';
//コンポーザーを生成
const composer = new EffectComposer(renderer);
//レンダーパスを生成
const renderPass = new RenderPass(scene,camera);
//カラーハーフトーンエフェクト
const halftonePass = new HalftonePass();
//グリッチエフェクト
const glitchPass = new GlitchPass();
//コンポーザーに追加
composer.addPass(renderPass);
composer.addPass(halftonePass);
composer.addPass(glitchPass);
function rendering(){
requestAnimationFrame(rendering);
//コンポーザーでレンダリング
composer.render();
}
必要なファイルを読み込んだら、コンポーザーを生成し、コンポーザーを使用してレンダリングします。後は、かけたいエフェクトをコンポーザーに追加するだけです。
● オリジナルエフェクトの制作
EffectComposerはオリジナルエフェクトを制作することもできます。詳細は、「How to use post-processing - three.js docs」の最後に書いてあります。
● script.js
必要なライブラリを読み込みます。
<script src="js/preloadjs.min.js"></script> <script src="js/TweenMax.min.js"></script> <script src="js/script.js" type="module"></script>
完成したscript.jsになります。
//===============================================================
// Import Library
//===============================================================
import * as THREE from './lib/three_jsm/three.module.js';
import { EffectComposer } from './lib/three_jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './lib/three_jsm/postprocessing/RenderPass.js';
import { HalftonePass } from './lib/three_jsm/postprocessing/HalftonePass.js';
import { GlitchPass } from './lib/three_jsm/postprocessing/GlitchPass.js';
import { OrbitControls } from './lib/three_jsm/OrbitControls.js';
import { scene, camera, container, renderer } from './lib/basescene.js';
//===============================================================
// Init
//===============================================================
window.addEventListener('load',function(){
init();
});
let orbitControls;
let composer;
let sphereContainer;
let directionalLight;
let time = 0;
function init(){
setLoading();
}
function setLoading(){
TweenMax.to('.loader',0.1,{opacity:1});
TweenMax.to('#loader_wrapper',1,{
opacity:0,
delay:1,
onComplete: function(){
document.getElementById('loader_wrapper').style.display = 'none';
TweenMax.to('.loader',0,{opacity:0});
}
});
threeWorld();
setLight();
setControll();
rendering();
}
//===============================================================
// Create World
//===============================================================
function threeWorld(){
renderer.outputEncoding = THREE.sRGBEncoding;
sphereContainer = new THREE.Object3D();
scene.add(sphereContainer);
for(let i = 0; i < 150; i++){
const h = Math.round((i / 150) * 360);
const s = 30;
const l = 60;
console.log(l);
const color = new THREE.Color(`hsl(${h},${s}%,${l}%)`);
const geometry = new THREE.SphereGeometry(2,6,6);
const material = new THREE.MeshPhysicalMaterial({
color:color,
flatShading:true
});
const sphere = new THREE.Mesh(geometry,material);
const radian = (Math.random() * 360) * Math.PI / 180;
const radian2 = (Math.random() * 360) * Math.PI / 180;
const x = Math.cos(radian) * Math.cos(radian2) * 15;
const y = Math.sin(radian) * 15;
const z = Math.cos(radian) * Math.sin(radian2) * 15;
const scale = Math.random() * 0.7 + 0.2;
sphere.position.set(x,y,z);
sphere.scale.set(scale,scale,scale);
sphere.rotation.set(
Math.random() * 360 * Math.PI / 180,
Math.random() * 360 * Math.PI / 180,
Math.random() * 360 * Math.PI / 180
)
sphereContainer.add(sphere)
}
composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene,camera);
const halftonePass = new HalftonePass();
const glitchPass = new GlitchPass();
composer.addPass(renderPass);
composer.addPass(halftonePass);
composer.addPass(glitchPass);
}
function setLight(){
const ambientlight = new THREE.AmbientLight(0xFFFFFF,0.5);
scene.add(ambientlight);
directionalLight = new THREE.DirectionalLight(0XFFFFFF,0.8);
scene.add(directionalLight);
}
function setControll(){
document.addEventListener('touchmove',function(e){e.preventDefault();},{passive:false});
orbitControls = new OrbitControls(camera,renderer.domElement);
orbitControls.enableDamping = true;
orbitControls.dampingFactor = 0.5;
}
function rendering(){
requestAnimationFrame(rendering);
if(orbitControls){
orbitControls.update();
}
time++;
sphereContainer.rotation.x = time * 0.1 * Math.PI / 180;
sphereContainer.rotation.y = time * 0.1 * Math.PI / 180;
const radian = time * 0.2 * Math.PI / 180;
const radian2 = time * 0.2 * Math.PI / 180;
directionalLight.position.x = Math.cos(radian) * Math.cos(radian2) * 10;
directionalLight.position.y = Math.sin(radian) * 10;
directionalLight.position.z = Math.cos(radian) * Math.sin(radian2) * 10;
composer.render();
}
● basescene.js
sceneやcameraなど基本的な設定を管理するbasescene.jsです。
//===============================================================
// Import Library
//===============================================================
import * as THREE from './three_jsm/three.module.js';
//===============================================================
// Base scene
//===============================================================
let scene,camera,container,renderer;
init();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50,window.innerWidth/window.innerHeight,1,100);
camera.position.set(0,20,20);
scene.add(camera);
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth,window.innerHeight);
renderer.setClearColor(new THREE.Color(0x000000));
container = document.querySelector('#canvas_vr');
container.appendChild(renderer.domElement);
window.addEventListener('resize',function(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
},false);
}
export { scene, camera, container, renderer }
完成したデモになります。Three.jsのEffectComposerでポストプロセッシングを試しました。
※グリッチエフェクトをかけているため、画面が激しく点滅します。

