昨今のWebサイトではWebGLを利用した3Dコンテンツをしばしば見かけるようになってきました。WebGLに対応した端末が普及してきていることや、Three.jsなどのライブラリが充実していることもあり、実案件での採用が現実的になってきているからです。
しかし、いざ3Dコンテンツを作ってみると、どこか味気のないものになってしまう事があります。そんな時はエフェクトの追加をオススメです。エフェクトを追加することで、コンテンツの見栄えが派手になったり、キャラやゲームの状態が伝わりやすくなります。今回エフェクトの例として、RPGのセーブポイントや回復ポイントで使用されそうなデモを制作してみました。
※このデモはThree.js r146とTypeScript 4.9によって書かれています。
本記事では、セーブポイント風なエフェクトの作成を通して、Three.jsを使ったエフェクト作成の3つの基本ノウハウを解説します。他のエフェクト作成にも応用できるので是非ご参考ください。
制作の流れ
冒頭のデモは下図のパーツで構成されています。複雑そうに見えますが、分解してみるとシンプルなパーツで構成されている事が分かります。
今回は以下の3つに絞って順に解説します。その他のパーツはこの3つの方法の応用で作る事ができます。
- 光の柱
- 渦
- パーティクル
ステップ1. 光の柱の作成
円柱を作る
光の柱は縦に伸びる円柱のような形をしています。Three.jsではCylinderGeometry
という円柱型のジオメトリが用意されているのでこちらを使用して表現します。
// THREE.CylinderGeometry(上面円の半径, 下面円の半径, 高さ, 縦分割数, 横分割数, 上下面を無くすか否か)
const geometry = new THREE.CylinderGeometry(
5,
5,
15,
25,
25,
true
);
この時、第6引数の上下面を無くすか否かにtrue
を指定するように注意ください。蓋のある円柱になってしまうのを防ぐためです。
柱を光らせる
円柱に光っているかような質感をもたせます。
発光体を表現する際は、光源に関係なく発色できるMeshBasicMaterial
が最適です。
const material = new THREE.MeshBasicMaterial({
map: texture, // テクスチャーを指定
color: 0x007eff, // 色
transparent: true, // 透明の表示許可
blending: THREE.AdditiveBlending, // ブレンドモード
side: THREE.DoubleSide, // 表裏の表示設定
depthWrite: false // デプスバッファへの書き込み可否
});
設定しているパラメーターを順に解説します。
map
map
パラメーターは使用するテクスチャーを指定できます。テクスチャーはモノクロで作成しておくとcolor
パラメーターから白色部分を指定した色に変更できるため、汎用性が高く扱いやすいのでオススメです。
blending
blending
パラメーターはブレンドモード指定できます。NoBlending
(無し)、NormalBlending
(半透明合成)、AdditiveBlending
(加算合成)、SubtractiveBlending
(減算合成)、MultiplyBlending
(乗算合成)の5つから選択できます。
今回は重なった部分を白く発光させたいためAdditiveBlending
を指定します。
side
side
パラメーターは描画面を指定できます。FrontSide
(表のみ)、BackSide
(裏のみ)、DoubleSide
(表裏両方)の3つから選択できますが、今回は筒の中も表示させたいためDoubleSide
を指定します。
depthWrite
depthWrite
パラメーターは面と面が重なって見える時に、陰に隠れてしまった面を描画させないようにするかどうかを設定できます。今回は光が重なって見える必要があるのでfalse
を指定します。
depthWrite: false
にすると深度バッファを更新しない(深度テストはする)ので、深度的には何も書かれてなかったことになり、それより奥のオブジェクトを後から描画できる(=後ろが透けて見える)ことになります。
基本的に「不透明オブジェクトは深度書き込みアリ」、「半透明オブジェクトは深度書き込みナシ」がセオリーです。
また、3D的に「半透明」というのは、「完全不透明でない箇所が一部でもある」ことなので、アルファ50%の透けているガラスのようなものだけでなく、パーティクルでよくある板ポリに●を書いて丸の中はアルファ100%、外は0%というようなものも半透明扱いとする必要があります。
ジオメトリとマテリアルが完成したので、この2つを使用したメッシュを作成すれば光の柱の完成です。
// 光る柱のメッシュを作成
const mesh = new THREE.Mesh(geometry, material);
ステップ2. 渦の作成
渦をつくる
渦は地面にドーナツ型に渦を発生させたいので、TorusGeometry
というドーナツ型のジオメトリを使用します。本来は立体のドーナツ型を想定したジオメトリですが、第3引数の分割数の値を2
にすることで平面のドーナツ型を作成できます。
// THREE.TorusGeometry(半径, 太さ, 放射状の分割数, 管の分割数)
const geometry = new THREE.TorusGeometry(6, 3, 2, 100);
マテリアルは前章の光の柱とほぼ同じ内容で、テクスチャーのみ変更したものを使用します。
const material = new THREE.MeshBasicMaterial({
color: 0x007eff,
map: texture,
transparent: true,
blending: THREE.AdditiveBlending,
side: THREE.FrontSide
});
地面に設置する
TorusGeometry
はデフォルトで縦に立っているので、90度回転させて地面と平行にします。描画面はFrontSideとしているので、表面が見えるように回転させる向きに注意してください。
mesh.rotaition.x = 90 * Math.PI / 180; // 90度回転
地面と平行になりましたが、このままでは地面とエフェクトが重なってしまい下図のようなチラつきが発生してしまいます。
この問題はメッシュを少しだけ浮かせる事で回避できます。
mesh.position.y = 0.01; // 少しだけ浮かせる
回転させる
渦を巻いているアニメーションをつけます。回転角度をフレーム毎に増やしメッシュを回転させます。
angle++; // 角度をインクリメント
mesh.rotation.y = angle * Math.PI / 180; // 回転
回転させたことで渦を巻いているような見栄えになりました。
ステップ3. パーティクルの作成
粒をつくる
パーティクルにはSprite
というオブジェクトを使用します。Sprite
は必ずカメラに正面を向くという特徴のある平面オブジェクトで、パーティクルを表現する場合に、テクスチャーの見え方が均一になるため非常に有効です。このような手法を一般的にビルボードと呼びます。Sprite
を生成する場合のマテリアルはSpriteMaterial
を使用します。
const material = new THREE.SpriteMaterial({
color: 0x007eff,
map: texture,
transparent: true,
blending: THREE.AdditiveBlending
});
const sprite = new THREE.Sprite(material);
これで一粒分のパーティクルを作成できました。
湧き出させる
パーティクルが下から湧き出るような演出を作っていきます。下から上へと上がっていく動きと、フェードアウトさせる動きを合わせる事で表現します。
// 徐々に上へ
sprite.position.y += 0.1;
// 徐々に薄く
material.opacity -= 0.01;
真上に上がって消えていくアニメーションができました。あとは同じパーティクルをいくつか生成し、時間差をつけてアニメーションさせることで、湧き出るような演出を表現できます。さらに横方向の動きや拡縮を入れるとよりクオリティーが上がります。
まとめ
特別なツールを使用する事なく、JavaScriptのコードのみでセーブポイント風なエフェクトを作成できました。今回紹介した基本ノウハウは、セーブポイントだけでなく、波動や爆発などのさまざまなエフェクトを作成する際に応用できます。
Three.jsとは関係ありませんが、BISHAMONというエフェクトツールの解説書籍『BISHAMON ゲームエフェクトデザイン入門』ではエフェクトのさまざま表現方法がわかりやすく解説されているので、あわせて見ておくと良いでしょう。本記事以外でもエフェクトに関連した記事をいくつか掲載しているので、こちらもご参考ください。
- エフェクト作成入門講座 UVスクロールを使ったマグマエフェクトの作成
- エフェクト作成入門講座 リング描画を使った乱れ斬りエフェクトの作成
- エフェクト作成入門講座 Fカーブを使った吹雪エフェクトの作成
- PopcornFxによる花火エフェクトの作成
ぜひ、みなさんも色々なエフェクト作成に挑戦してみてください。
※この記事が公開されたのは8年前ですが、1年前の2022年12月に内容をメンテナンスしています。