のぐそんブログ

暗いおじさんがシコシコ書くブログです。

Three.jsでポストプロセスを試してみる

THREE.jsにはポストプロセス用のフィルターが用意されている。 使い方を調べてみる。 ポストプロセスはオブジェクトに対して適応するのではなくシーン全体に対して適応する。

ポストプロセスの手順

①必要なライブラリを読み込む ②THREE.EffectComposerを作成する ③EffectComposerにTHREE.RenderPassを追加する ④EffectComposerにフィルタを追加する。 ⑤EffectComposerでレンダリングする。

必要なライブラリを読み込む

ポストエフェクトを利用するには、THREE.jsに用意されているライブラリを読み込むする必要があります。

ポストプロセスに必要なjs

THREE.EffectComposerの作成

ポストプロセスを利用するには、THREE.EffectComposerを作成する必要があります。

使い方
var renderer = new THREE.WebGLRenderer();
var composer = new THREE.EffectComposer(renderer);

THREE.EffectComposerの設定

ポストプロセスで利用するフィルタは、EffectComposerのaddPass()を使って追加します。

まずは現在のシーンを描画するためのフィルタであるTHREE.RenderPassを追加します。

使い方
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);

FilmPassフィルタをかけてみる

FilmPassフィルタをかけてみます。 FilmPassは古いテレビのノイズのようなフィルタです。

フィルタ用のjsを読み込む

使い方

new THREE.FilmPass(noiseIntensity,scanLinesIntensity, scanLinesCount, grayscale);
プロパティ
プロパティ 説明
noiseIntensity シーンの画像粒子の粗さの制御
scanLinesIntensity 走査線の見え方の制御
scanLinesCount 走査線の数
grayscale trueを設定するとグレースケールに変換される
抜粋したコード
let composer = new THREE.EffectComposer(renderer);
let renderPass = new THREE.RenderPass(scene, camera);

let effectFilm = new THREE.FilmPass(0.8, 0.325, 256, false);
effectFilm.renderToScreen = true;

composer.addPass(renderPass);
composer.addPass(effectFilm);


//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

BloomPassフィルタをかけてみる

ブルームエフェクトと言われるフィルタをかけてみます。 シーンの明るい部分がより明るくなり、暗い部分ににじみ出ます。 ブラーのような効果があります。

使い方

new BloomPass(strength,kernelSize, sigma, resolution);
フィルタ用のjsを読み込む
プロパティ
プロパティ 説明
strength フレームエフェクトの強さ。値が大きいほど、明るい領域が明るくなり、暗い領域により滲みがでる
kernelSize オフセットを指定
sigma 値が大きければよりぼやけて見える
resolution エフェクトの詳細度です。値が小さいとブロックノイズが発生する
抜粋したコード
let composer = new THREE.EffectComposer(renderer);
let renderPass = new THREE.RenderPass(scene, camera);
let effectBloom = new THREE.BloomPass(1.0, 25, 2.0, 512);

composer.addPass(renderPass);
composer.addPass(effectBloom);

var toScreen = new THREE.ShaderPass(THREE.CopyShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen);


//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

THREE.BloomPassは画面に直接描画できない為、new THREE.ShaderPass(THREE.CopyShader)を使って描画します。 ここがイマイチよくわかりませんでしたが、これが無いと描画されませんでした。

また、フィルタをかける対象が明るいと、ブルームエフェクトをかけると真っ白になりなにも表示されなくなりました。その為サンプルでは背景を黒にしてフィルタをかけました。

DotScreenPassフィルタをかけてみる

DotScreenPassはドットを組み合わせて描画するフィルタです。

使い方

new DotScreenPass(center,angle, scale);
フィルタ用のjsを読み込む
プロパティ
プロパティ 説明 備考
center ドットのオフセットの細かさ THREE.Vecter2()で定義する
angle ドットの並び方
scale ドットの大きさ
抜粋したコード
let composer = new THREE.EffectComposer(renderer);
let renderPass = new THREE.RenderPass(scene, camera);
let effectBloom = new DotScreenPass();

composer.addPass(renderPass);
composer.addPass(effectBloom);

var toScreen = new THREE.ShaderPass(THREE.CopyShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen);


//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

GlitchPassフィルタをかけてみる

GlitchPassはランダムな間隔で電子的なグリッチを描画するフィルタです。

使い方

new GlitchPass();
フィルタ用のjsを読み込む
プロパティ
プロパティ 説明
size グリッチの細かさ
抜粋したコード
let composer = new THREE.EffectComposer(renderer);
let renderPass = new THREE.RenderPass(scene, camera);
let effectBloom = new GlitchPass();

composer.addPass(renderPass);
composer.addPass(effectBloom);

var toScreen = new THREE.ShaderPass(THREE.CopyShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen);


//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

EdgeShader、EdgeShader2フィルタをかけてみる

エッジを抽出するフィルタです。

使い方

フィルタ用のjsを読み込む
抜粋したコード
var composer = new THREE.EffectComposer(renderer);
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);

var toScreen = new THREE.ShaderPass(THREE.EdgeShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen); 

//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

THREE.ShaderPassの引数として設定します。

EdgeShader

EdgeShader2

MirrorShaderフィルタをかけてみる

鏡面コピーのフィルタを表現します。

使い方

フィルタ用のjsを読み込む
抜粋したコード
var composer = new THREE.EffectComposer(renderer);
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);

var toScreen = new THREE.ShaderPass(THREE.MirrorShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen); 

//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

HorizontalBlurShaderフィルタをかけてみる

鏡面コピーのフィルタを表現します。

使い方

フィルタ用のjsを読み込む
抜粋したコード
var composer = new THREE.EffectComposer(renderer);
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);

var toScreen = new THREE.ShaderPass(THREE.HorizontalBlurShader);
toScreen.renderToScreen = true;
composer.addPass(toScreen); 

//中略・・・
//WebGLRenderer.render()を削除して、EffectComposerでレンダリング
function render() {

    requestAnimationFrame(render);

    composer.render();
}

まとめ

使い方があっているかわかりませんが、すでに用意されているフィルタでも色々できそうです。 生のWebGLでポストプロセスを実装しようとすると、かなり難しいですがTHREE.jsはわりとシンプルに実現できそうです。