たった3ステップ!WebGLを使ってインタラクティブな3D風写真を作ろう

Web上に3DCGを表現できるWebGLの人気が、年々高まっています。THREE.MeshLineBlotter.jsなどのJavaScriptライブラリで制作されたアニメーションを目にする機会も多いはず。

Facebookは2018年に、奥行きのある3D写真を作る新機能の提供をはじめ注目を集めました。この3Dエフェクトを可能にしているのが、画像加工技術と、ちょっとしたコーディングです。

こうした3Dエフェクトは、強力なライブラリであるThree.jsまたはPixi.jsで作られるのが一般的です。しかし今回はライブラリに頼らず、WebGLを使って奥行きのあるインタラクティブな3D風写真を作る方法をお伝えします。

1. 平面を作ろう

今回はライブラリではなく、WebGLを使います。(もし今回WebGLにはじめて触れるなら、こちらのWebサイトが参考になります)

最近はWebGLの使用が避けられる傾向にありますが、その理由はコーディングの冗長さです。

あらゆるフルスクリーンシェーダーエフェクトは、たとえ2Dであっても、ある種の平面(Plane)、メッシュ(Mesh)、またはいわゆるクワッド(Quad)が必要です。three.jsを使う場合はTHREE.PlaneGeometry(1,1)だけで済みますが、プレーンなWebGLでは以下のようなコードが必要です。

let vertices = new Float32Array([
	  -1, -1,
	  1, -1,
	  -1, 1,
	  1, 1,
	])
	let buffer = gl.createBuffer();
	gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
	gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW );

これで、頂点シェーダーとフラグメントシェーダーを適用できる平面が作れました。

2. 画像を用意しよう

画像に奥行きをもたせるために必要なのが「深度マップ」です。Z値に応じて、画像を前景と背景で分離します。

Photoshopで、画像を以下のようにモノクロ加工しましょう。

webgl-1

▲オブジェクトがカメラに近づくほど色が薄くなる

3. シェーダーを活用しよう

シェーダーはWebGLにおいて非常に重要な存在です。MDN web docsでは、シェーダーについて以下のように解説されています。

シェーダーは、OpenGL ES Shading Language(GLSL)を使って書くプログラムです。オブジェクトを構成する頂点に関する情報を取得し、ピクセルの位置や色などのレンダリングに必要な情報を生成します。WebGLにおいて用いられるのは、頂点シェーダーとフラグメントシェーダーの2種類です。

以下が頂点シェーダーです。

attribute vec2 position;
    void main() {
    gl_Position = vec4( position, 0, 1 );
}

そして以下が今回の核となる、フラグメントシェーダーです。2つの画像をロードしましょう。

void main(){
    vec4 depth = texture2D(depthImage, uv);
    gl_FragColor = texture2D(originalImage, uv); // just showing original photo
}

深度マップをモノクロにすることを忘れないようにしましょう。シェーダーにおいて、色はただの数字(1が白、0が黒)にすぎません。

なおuvは、表示するピクセルに関する情報を格納する2次元マップです。こうした情報を与えることにより、写真をインタラクティブに動かせるようになります。

カーソルによる動きを加えてみましょう。

vec4 depth = texture2D(depthImage, uv);
gl_FragColor = texture2D(originalImage, uv + mouse);

するとこうなります。

webgl-2

さらに、ここに奥行きを加えてみましょう。

vec4 depth = texture2D(depthImage, uv);
gl_FragColor = texture2D(originalImage, uv + mouse*depth.r);

これでインタラクティブな3D風写真が完成しました!

webgl-3

テクスチャはモノクロなので、赤チャンネル(depth.r)をカーソルの位置の値と組み合わせるだけで、カーソルで画像を動かせるようになります。明るい部分(手前)は大きく、暗い部分(奥)は小さく動くようにすることにより、奥行きを演出するという仕組みです。

おわりに

シェーダーを使ってもっと派手な演出をすることもできますが、今回のような細かい工夫による効果も魅力的です。

ぜひみなさんも、自分だけの3D風写真を作ってみてください。

(原文:Yuriy Artyukh 翻訳:Asuka Nakajima)

 

こちらもおすすめ!▼

SHARE

RELATED

  • お問い合わせ
  • お問い合わせ
  • お問い合わせ