『The Times They Are a-Changin'(時代は変る)』 - ボブ・ディラン
ゲームオーディオデザインにおける厄介な作業のひとつが、時間的なバリエーションに対応することです。例えば1つのサウンドから、いくつかの指定されたデュレーションに合わせて複数のバージョンを作成する必要があるかもしれません。あるいは仕様が変更されたため、完成したサウンドを新しいタイミングに合わせて作り直さなくてはならない場合もあります。もちろんその両方が起こることもあり、1つのサウンドから複数のバージョンを作成した後、変更に合わせるためにサウンドの複数のバージョンを作り直す必要が出てくる場合もあります。それに対処するには多くの時間と労力が求められます。
単純なケースであれば、ループベースのオーディオを活用できることがあります。これはサウンドがほぼ一定である場合には有効です。より複雑なサウンドになるとツールは限られます。ランタイムのタイムストレッチでは多くの場合、スペクトルアーティファクトによってサウンド特性が望ましくない形で変化してしまうまでの範囲が非常に狭くなります。エンジン内の従来の合成技術でも、ある程度は時間的な柔軟性を確保できますが、このアプローチだとデザイナーが使用できるのは内部合成によるサウンドや機能に限定されます。結局のところ進行を伴うサウンドは、オリジナルのタイミングで固定されてしまうことが多くなります。
数年前、車両サウンドを制作するためにSoundseed Grainを導入した後、ほかに使い道がないか試しはじめました。その過程でサウンドをオリジナルのタイミングから切り離し、サウンドを作成したツールにかかわらず、時間的な柔軟性を提供する強力なソリューションとしても活用できることに気づきました。
このしくみを実際に示すために、Unrealでいくつかのサンプルを作成しました。分かりやすくするため、以下のBlueprintスクリーンショットではオーディオ以外の要素のほとんどをマクロにまとめています。
ビルドアップ(盛り上がり)
2つのサンプル動画をご用意しました。1つは膨らむ風船を取り上げています。もう1つは魔力を蓄えるにつれて跳ね回り、最終的に蒸発する幻想的なキューブを示しています。音質的にはまったく異なりますが、セットアップはほぼ同じです。いずれの例でも、Soundseed Grainを活用してコンテンツをさまざまなデュレーションに合わせる、単一のWwiseイベントを使用しています。(各デザインの最後の「ポン」という音は、完了した印象を与える装飾的な要素にすぎません。グラニュラー設計の一部ではありません。)
これらのセットアップを簡単にご紹介します。
膨張 - Wwiseのセットアップ
WwiseでソースオーディオファイルをSoundseed Grainにロードします。徐々に膨らむ風船のサウンドで、変化を伴う長く安定した音です。

グラニュラーシンセシスであるSoundseed Grainは、Position値が示す位置を中心に、オーディオを細かい音の粒に分割します。
このPosition値を柔軟に変化させることが秘訣です。ここではゲームエンジンから送られる値のストリームでPosition設定を直接コントロールするため、Real Time Parameter Control経由で制御しています。

このRTPC「Progression_Balloon」は、0から1までの値を使用してサウンド内を移動します。時間の経過と共に、この範囲内で増加する値を送ることで、ゲームエンジンがSoundseed GrainのPosition値を徐々に更新します。これによりオーディオファイル内を効果的に「スクラブ」します。この処理は非常に柔軟なデュレーション範囲で実行できます。

ここにあるもう1つの設定「Output Level」について補足すると、強度も高めたかったため、同じRTPCを使用して6dBのボリュームランプも駆動させています。

膨張 - Unrealのセットアップ
Level BlueprintのイベントがBalloon Blueprintに対する参照を取得し、風船の「Inflate」イベントをトリガーすると同時にデュレーション値を送信します。

以下はBalloon BlueprintのInflateイベントを示しています。

このBlueprintの要となるのは、風船メッシュのスケールを駆動するタイムラインで、これによってタイムラインの進行に合わせて膨らんでいるように見せます。非常にシンプルなカーブです。

「Progression_Balloon」RTPCは同じ値を使用することで、視覚的な膨張と連動してサウンド内をスクラブできます。(「Inflate Update」ロジックは、見やすいようにメインのロジックパスの下の別のイベント内に配置されています。)

タイムラインの最後に到達すると、Finishedピンが実行されます。その時点で膨張サウンドは停止し、「ポン」という最終サウンドが再生されます。

以上です。Inflateイベントのコール時に異なるデュレーション値をプッシュすると、タイムラインのレートが変わり、タイムラインの出力値のストリームがサウンドと視覚的膨張の進行を完全に同期させて駆動します。
注目すべき点として、ゲーム内に0から1の範囲で進行する値を送信できる要素があれば、この処理に利用できます。Timelineから送信される必要はありません。
キューブ破壊前 - レイヤー
キューブと風船のセットアップにおける唯一の大きな違いは、キューブが2つのSoundseed Grainレイヤーを組み合わせて使用している点です。

サウンド内の進行用に1つのRTPCを共有する一方で、このレイヤー分離によりグラニュラー化設定を別々に調整して最適な結果を得ることができます。またレイヤーを分けることで、Wwiseのほかの設定を個別に扱うこともできます。ここではより幻想的な「Cube_Grain」レイヤーが徐々に強まるように設定されているのに対し、ノック/ガタガタ音の「Cube_Grain_Breakage」レイヤーは最後の劇的なクレッシェンドまで大部分が控えめのまま維持されます。
リロード
より現実的なサウンド例として、複雑な銃のリロードシーケンスを取り上げます。このように細部まで作り込まれたサウンドでも、さまざまなアニメーションのデュレーションに合わせ、柔軟に対応させることが簡単に行えます。
この場合のセットアップはほかとは異なります。ゲームエンジン側の構成は非常にシンプルです。
リロード - Unrealのセットアップ
主な違いは、RTPC「ReloadDuration」を1度だけ設定するという点です。

これまでの例では、ゲームエンジンが変化するRTPC値のストリームをWwiseに継続的に送信し、それによりオーディオが進行しました。今回の場合はReloadDuration値が1度だけ送られ、そのデュレーションの間、Soundseed Grainがオーディオ全体を通してスクラブという主要な処理を担当します。
リロード - Wwiseのセットアップ
先ほどと同じように、Soundseed Grainでソースサウンドをセットアップします。

利用するのはReloadDuration値1つのみで、これを複数個所に適用する必要があります。まずはモジュレータ4をSaw+に設定し、Soundseed GrainのPosition値をコントロールするように割り当てます。続いて、ReloadDurationのRTPCを使用してモジュレータ4のPeriodを設定します。

これによりモジュレータ4がReloadDuration値で設定されるレートで、Position値を前進させます。次に、サウンドがループしないよう適切なタイミングで停止する必要があります。
停止はOutput Levelにモジュレーションエンベロープをマッピングすることで実現されます。このエンベロープのアタックタイム/リリースタイムは極めて短く、Sustain Time値にReloadDuration RTPCが渡されます。最後に確実に停止するよう、Modulator Settingsの「Stop playback after release」ボックスにチェックを入れます。

このアプローチはWwise側でやや多くのセットアップが必要ですが、ゲームエンジン側のセットアップが最小限で済むというメリットがあります。この巧妙なアイデアを考案したJeshua Whitaker氏には敬意を表します。
まとめ
何事にも当てはまることですが、この手法にも注意点と限界があります。以下に考慮すべき点をいくつか示します。
- 音をストレッチしすぎると、音響的なアーティファクトが発生しやすくなります。一般的な傾向としては、ソースファイルが使用するデュレーションより長い方が、優れた結果を得られます。
- 短すぎるのも問題になることがあります。先ほどの動画にあった3秒のリロードは、やや不安定と言えると思います(オリジナルのデザインは約6秒でした)。これがデモ以上のものであれば、銃身の回転はおそらく個別に処理していました。
- この手法は空想的なサウンドの方が機能しやすいかもしれません。より現実的なサウンドは扱いが難しく、自然に聞こえるようにするには細かい調整が必要になる場合があります。
- いろいろ試してみてください。さまざまなソース素材から最適な結果を得るには、異なる設定が必要な場合もあります。アタック、デュレーションマルチプライヤ、シェイプ設定を調整したり、モジュレータを使用して、メインの進行にわずかなPositionモジュレーションを加えたりしてみましょう。ぜひ試行錯誤してください。
- ファイル全体を使用する必要はありません。RTPCはソースファイル内の一部範囲をPosition値にマッピングできます。
- Soundseed Grainの再生は循環して戻る場合があるため、両端にあるPosition値にはご注意ください。0から逆方向に循環しないよう、前方向(正)のモジュレーションのみを加えるモジュレータを使用すると効果的かもしれません。またソースの最後から最初へと循環するのを防ぐには、マッピングするPosition値の範囲を100%より少し手前までにし、さらに希望する結果に応じてソース素材の末尾周辺でテイルを残すか音を一定にするとよいかもしれません。
以上です。みなさまのお役に立てば幸いです。ワークフローの改善やタイミングの変更にうまく対応できる、クリエイティブで魅力的なデザインを生み出すために、ぜひご活用ください。
ここではごく一部にしか触れられていないと思いますが、みなさまが今後どのように発展させていくのかを楽しみにしています。ご質問やご提案、共有したい魅力的なデザインがありましたら、ぜひご連絡ください。

コメント