映像作品においてジャンルを問わず様々なところで活躍の場を広げているCGエフェクト。ここでは、PopcornFXを用いたサウンドボリュームに合わせたエフェクト制作について、プログラム部分まで掘り下げて解説する。
※本記事は月刊「CGWORLD + digital video」vol. 234(2018年2月号)からの転載となります
TEXT_鈴木克史(ICS)
EDIT_斉藤美絵 / Mie Saito(CGWORLD)、山田桃子 / Momoko Yamada
スクリプトが織りなす躍動感サウンドビジュアライザーの作成
筆者にとってエフェクトの魅力は、人を驚かせる演出の裏側には技術的な創意工夫があり、制作するなかでも日々発見があるところです。ツールの機能ひとつとっても人によって使い方が異なり、複数の機能をブロックのように組み合わせることで新しい効果を生み出せます。小さな機能でもしくみや原理を理解しておくことが、人を惹きつけるエフェクトをつくる上で重要だと考えています。本記事では、エフェクトの動きを生み出しているプログラムの部分まで掘り下げて解説します。他のツールでエフェクトをつくる際にも覚えておいて損はないでしょう。
-
鈴木克史氏(ICS)
株式会社ICS取締役。エンジニア、3Dモーションデザイナー、エフェクトアーティストとしてスマホゲーム開発から3Dコンテンツ開発まで幅広く従事。オウンドメディアであるICS MEDIAにてエフェクト記事を連載中!
ics.media
作例
PopcornFXは、パリとモントリオールに拠点を置くPersistant Studios社が提供するリアルタイムパーティクルエフェクトツールです。エフェクトエディタ(Windowsのみ対応)、マルチプラットフォーム対応のランタイムSDK(C++)、Unity、Unreal Engineのプラグインから構成されています。PopcornFXを使って感じるのは、パフォーマンスの高さです。パーティクルを数十万個レベルで表示してもツールが軽快に動き、リアルタイムに編集ができるため、効率良く作業が進みます。「スクリプトとGUI」という他のエフェクトツールとは一風変わった制作スタイルにより、まさにポップコーンのように無数にパーティクルを飛ばすエフェクトをつくるときには、強力な武器となることでしょう。
本作で特に意識したのはエフェクトの「メリハリ」です。サウンドボリュームに合わせて文字が飛び出てくる際の動きや、一部のパーティクルのみにモーションを適用する箇所で意識しています。また、タービュランスノイズ関数により、無数のパーティクルが生き物のようにうねうね動く表現も加えました。動画も用意していますのでご覧いただけると嬉しいです。
Topic 01 Audio Spectrumによるサウンドの解析
Audio Spectrumとは
サウンドデータをリアルタイムに解析し、周波数ごとにボリューム値を取得できるPopcornFXの機能のひとつです。サンプリングされた値を基にパーティクルを配置すると図のようなスペクトラムが描けます。
スプライトシートを活用したテキストのレンダリング
フィルタ種別により異なるサンプリング値を抽出している図です
Pointでのスペクトラム
1.使い方
【AudioSampler.sample関数】
引数に0~1の値(周波数)を指定すると、ボリューム値を0~1で返します。リアルタイムに変化するため毎フレーム取得していくとサウンドビジュアライザーを作成できます。その後、下記のスクリプトによりスペクトラムの値を調整します。
【スクリプトの解説】
// tを周波数としオーディオサンプラー(AudioSpectrum.sample関数)を使ってスペクトラムを取得します。
float spectrum = AudioSpectrum.sample(t);
// スペクトラムに係数をかけ、平方根を取ります(スペクトラムの差を柔らかくする処理)。
float kSpectrum = pow(spectrum* 256, 0.5);
【pow関数】
第1引数で指定した値を、第2引数で指定した値でべき乗する関数。0.5のように1より小さい値を与えると平方根を取る計算になります。係数をかけた後、べき乗することで値の差をやわらかくし、鋭利にする頻出テクニックです。
pow関数によるスペクトラムの調整
ConvolutionLevelによるスペクトラムのちがい
ConvolutionLevel0.3(上)、0.5(左下)、0.75(右下)でのスペクトラムです
2.Samplers
3D空間上の特定の位置を抽出する際には[SamplerShape]を使います。エディタの3D空間上に球体などのシェイプをひとつ配置し、そのシェイプの中から点を抽出することでランダムな値を決める機能です。
【rand関数】
与えられた範囲から、ランダムな値を取得する関数。
【Shape.samplePosition関数】
シェイプからランダムな値を取得する関数。
円周上の点の抽出
次ページ:
3.ランダムな位置を抽出し、揺れを加えるスクリプト
3.ランダムな位置を抽出し、揺れを加えるスクリプト
ここでは、Circle.samplePositionによって取得した3次元ベクトルに数値型をかけ算しています。ベクトル型と数値型のかけ算は、シェーダでグラフィックスプログラミングをする際によく出てくる重要なポイントです。
【ランダムな位置を取得して揺れを加える】
例)Position = Circle.samplePosition() * rand(0.7, 1.2);
【色の変更、ランダムな色を決めるスクリプト】
例)Color = float4(0.1, rand(0.0, 0.7), rand(0.6, 1),rand(0, 1));
【色を強調してグロー効果を出す】
// PopcornFXではColor値が1を超えると、グロー効果が適用されます。
例)Color = Color * rand(1, 5);
【ランダムな文字を設定するスクリプト】
例)TextureID = rand(0, 15);
【step関数】
例)step(rand(0,1), 0.85);
【位置を2層にするスクリプト】
例)float ratio = step(rand(0,1), 0.85) * 2 + 0.7;
Position = Box.samplePosition() * rand(0.9, 1)
* ratio;
スプライトシートを活用したテキストのレンダリング
step関数による2値化を利用した「メリハリ」の演出
2つの値を比較し、どちらの値が大きいかに応じて0または1を返します。最初の引数に0~1までのランダムな値を、2番目の引数に0~1までの値を入れることで、簡単な確率分布をつくりました。上記のスクリプトにより、85%の確率で0、15%の確率で1となります。エフェクト作成時では「何かの値をちょっとだけ飛び出したい」、「この部分に少しだけ味付けしたい」といったときに便利です。今回のサウンドビジュアライザーではこの2値化の処理によって「メリハリ」を意識した動きを作成しています
4.タービュランスノイズ
ここまではシェイプの形状からランダムな値を抽出しましたが、タービュランスノイズを使うと、パラメータによって生成したノイズ画像から値を抽出することで、時間が進むごとにうねるような動きを作成することができます。
【SamplerTurbulence.samplePotential 関数】
ノイズテクスチャからシームレスなノイズ値を取得します。
// 位置をnormalize関数で正規化。
例)float3 n = normalize(Position);
// タービュランスノイズから値を取得します。
例)float3 samplingLocation = SamplerTurbulence.
samplePotential(n);
タービュランスノイズの有無によるパーティクル動作のちがい
SamplerTurbulenceノードの設定とノイズテクスチャ
5.Backdrops
Backdropsと呼ばれるテスト機能をご紹介します。これはエフェクト制作時のみ有効となる機能です。今回のサウンドビジュアライザーの場合、PopcornFX上で実際の動作を確認しながら、リアルタイムにエフェクト制作を進めていきました。この機能はとても強力で、3Dモデルデータ、モーションデータ、サウンドデータなど、エフェクトデータには含まれない要素を編集時のみ取り込んで確認ができます。
Backdropsを利用したエフェクトテストの例
火柱のエフェクトを作成した例
Backdropsにサウンドデータを設定した例
Backdropsにアニメーションデータを設定した例
6.Unityへのインポート
PopcornFXで作成したエフェクトデータをUnityにインポートします。
PopcornFX Particle Effects Plugin
エフェクトの取り込みにはスクリプトを書く必要はなく、公式プラグインを購入して[PK Fx FX]コンポーネントを作成し、エフェクトを割り当てれば完了です
assetstore.unity.com/publishers/8762
COLUMN
筆者が同じく注目しているエフェクト制作ツールに「Effekseer(エフェクシアー)」があります。Unityをはじめ、Unreal Engine 4、Cocos2d-x、HTML5(WebGL)に対応していて、エフェクトに興味をもたれた方が気軽に始めるのにオススメです。機能追加も鋭意継続中!
effekseer.github.io