- はじめに
- 開発概要
- ハイクオリティを目指す為に導入・実装したシェーダー4選
- Unity製のTimelineをベースに扱いやすいようにカスタマイズした話
- Unityでレンダリングさせているライブを収録し書き出す方法の紹介
- 最後に
はじめに
サムザップでセルルック3Dの技術研究開発(以下、3DのR&D)をしています。技術戦略室の木田です。
弊社が提供する『この素晴らしい世界に祝福を!ファンタスティックデイズ(以下、このファン)』は、2022年8月27日にリリース2.5周年を迎えました。
これを記念した様々なキャンペーンのひとつとして、『このファン』のゲーム内に登場する踊り子ユニット「アクセルハーツ」が歌う「Cutie Star」のPVが公開されています。
今まで、弊社はハイクオリティな2D表現を武器に様々なスマートフォン向けゲームを企画・開発・提供してきました。
その一方、新しい技術への研究にも力を入れており、そのひとつに3DのR&Dがあります。
3DのR&Dでは、今まで培ってきた2D表現を生かしつつ、セルルックな3D表現も会社の武器にするという目的の元、フェーズ1・フェーズ2と段階的なアウトプット目標を設けて研究を進めてきました。
フェーズ1:
UnityのUniversal Render Pipeline(以下、URP)をベースとした静的データ(動画)の制作
フェーズ2:
フェーズ1で製作したものをモバイルでリアルタイムレンダリングできるようにする
3DのR&Dでのフェーズ1の成果として公開したものが、「Cutie Star」のPVになります。本記事では、このPVの技術的な部分を一部紹介しようと思います。
開発概要
こちらが今回のPV制作で使用したUnityのバージョンやライブラリなどの一覧になります。
項目 | バージョン |
---|---|
Unity | 2021.1.28f1 |
Universal RP | 11.0.0 |
ShaderGraph | 11.0.0 |
Timeline | 1.5.7 |
Unity Recorder | 2.5.7 |
StreamingImageSequence | 0.15.3 |
PSOFT Pencil+ 4 Line | 4.1.2 |
PSOFT Pencil+ 4 Line URP | 1.1.0 |
UnityChanToonShader | 2.2.0 |
NovaShader | 1.3.2 |
PV制作の後に控えているフェーズ2での目標である「モバイルでリアルタイムレンダリングできるようにする」を見据え、UnityでのレンダーパイプラインはURPを選定しました。
また、独自に作成するShaderに関しては、将来的にしっかり技術資産になることを考慮し、Unityが推しているShader Graphを取り入れています。
ハイクオリティを目指す為に導入・実装したシェーダー4選
今回のPV制作にあたり、ハイクオリティを目指す為に行った対応を4つ紹介します。
セルルック表現を実現する為のキャラシェーダー
セルルック表現を実現する為のキャラシェーダーはUnityChanToonShader v2(以下、UTS)を利用しました。
基本的にはUTSを活用してキャラクターは表現しています。 ただ、アウトラインに関してはハイクオリティを目指すにあたり課題があった為、別の手法を採用しました。詳細に関しては後述します。
ハイクオリティなアウトライン描画を実現する為にした事
最初は先に述べたUTSによるアウトライン描画で実現しようとしていました。
しかし、フレーム単位で拡大して確認していた際に、図のように一部アウトラインが浮いているように見える事象や鋭利な部分のアウトライン裂けが発生している事に気が付きました。
UTSのドキュメントを確認すると、アウトラインの描画方法は背面法を採用しているようでした。
UTS2では、アウトライン機能として、マテリアルベースのオブジェクト反転方式のアウトラインを採用しています。
引用先リンク
そこで、毛先など鋭利な部分の頂点法線を毛先の流れる方向へ調整する事で、鋭利な部分のアウトライン裂けは改善しました。
しかし、よく見ると一部アウトラインが浮いているように見える事象はまだ解決していないように感じます。
これに関しては、背面法のデメリットと考える項目(下記)に関しての改善策を考える必要があり、ポスト処理のアウトライン描画にする事で解決しようという判断に至りました。
【背面法のデメリットと考える項目】
- モデル形状によってはアウトラインが消える
- モデル形状によってはアウトラインがモデルに対して離れて描画されているように見える
アニメの映像制作ではpencil+のアウトライン描画がよく使われているということで、今回は、pencil+のUnity URP対応版があったので動作検証しました。
そして、pencil+を使うことで画像のように、綺麗なアウトライン描画を実現しました。
なお、pencil+はモバイルをサポートしていないため、その点は注意が必要です。
3DのR&Dにおけるフェーズ1ではpencil+で要件を満たせているのですが、「モバイルでのリアルタイムレンダリング」を目標としているフェーズ2では、pencil+に代わるポスト処理での軽量なアウトライン描画を実現しなければならない課題が残っています。
パーティクルのクオリティを上げるために導入した「Nova Shader」
パーティクルのクオリティを上げる為、UnityのParticle System用シェーダ「Nova Shader」を利用しました。
「Nova Shader」はサイバーエージェントのゲーム事業部で開発していて、OSSとして一般公開しているものにはなりますが、サイバーエージェントのグループ会社である弊社でも「Nova Shader」を積極的に導入しています。
「NovaShader」の詳しい紹介はこちら、ドキュメントはこちらを参照ください。
元々、version1.0.0を利用していましたが、パーティクルも深度情報に基づいてポスト処理のDepth of Fieldを掛けたかったのですが、図のように深度情報を持っていない状態でした。
これについては、OSSということで深度情報を持つよう提案し、version 1.3.2にて_CameraDepthTextureに対して深度値、_CameraNormalTextureに対して法線が書き込まれるようになりました。
このバージョンで深度情報を持つようにしていただいたので、背景やキャラのモデルと同様にパーティクルも深度情報に基づいてポスト処理を行えるようになりました。
ライブにおける演出クオリティを向上させる為に行なった対応
ライブ演出でよくあるライトの軌跡表現の事を「ライトシャフト」というのですが、この表現をShaderGraphで実現し、表現の幅を広げられるような形を意識して工夫したので紹介します。
シェーダーによるライトシャフトを表現するために、円錐のポリゴンに対して専用のShaderを用意しました。
ライトカラーやリムライトなど基本的なものから、vertexで円錐のサイズ調整できるようにしたりと使用感の良い形にしています。 また、カメラの座標で計算して直接ライトを浴びた際の表現も擬似的に再現できるようにしました。
他にも背景のステージに埋め込まれているライトやバルーンの描画などにShaderGraphを使用した表現はありますが、ここでは説明を省きます。
Unity製のTimelineをベースに扱いやすいようにカスタマイズした話
カメラワークやステージ背景の動的オブジェクトなど、基本的にUnity公式のTimelineで制御するようにしています。
また、今回はキャラクターのモーションなどが途中で割り込む要件が無かった為、キャラクターのダンスモーションなどもスタジオ収録したデータをベースにモーション調整して、Unity上ではTimeline制御しています。
ただ、そのままだとTimelineで制御できない部分があり、その部分は拡張したので紹介します。
連番画像をレンダリングさせる為のライブラリ導入
StreamingImageSequenceはUnityが提供するTimelineで連番画像を再生する為のライブラリになります。 主にステージ背景のスクリーン上に流すアニメーションに利用しました。
本プロジェクトではversion 0.15.3を使用し、ライブラリとしてはPreview版ではありますが、今回の使用範囲では特に問題なく機能していました。 ただ、モバイルはまだサポートしていないので、対応されるのを期待しつつ、フェーズ2では別の仕組みで実現する予定です。
ポストエフェクトのパラメータをTimelineで制御するために拡張した話
ポストエフェクトのパラメータはUnity公式のTimelineでは操作できません。そこで、簡単な拡張をしました。
VolumeProfileControlBase.csのソースコード
using UnityEngine;
using UnityEngine.Rendering;
[ExecuteInEditMode, RequireComponent(typeof(Volume))]
public abstract class VolumeProfileControlBase<T> : MonoBehaviour where T : VolumeComponent
{
// T : VolumeComponent
private Volume volume;
private void OnValidate()
{
if (volume == null)
volume = this.GetComponent<Volume>();
if (volume.profile == null)
return;
foreach (var item in volume.profile.components)
{
switch (item)
{
case T itemComponent:
OnValidateEvent(itemComponent);
break;
default:
break;
}
}
}
private void Update()
{
if (volume == null || volume.profile == null)
return;
UpdateEvent();
}
public abstract void OnValidateEvent(T itemComponent);
public abstract void UpdateEvent();
}
VolumeProfileControlBase.csを継承した各VolumeComponent
に対するVolumeProfileControl
クラスで制御しました。
実行中ではない時、Timeline操作した際も結果が確認できるようにExecuteInEditMode
を使ってUpdate()
での更新にしています。
Unityでレンダリングさせているライブを収録し書き出す方法の紹介
今回はクオリティ重視で静的なデータとして動画でのアウトプットを目的としていたので、動画の書き出しについても少し触れておきます。
Unity Recorderを用いたライブ映像収録
Unityが提供するUnity Recorderを使用し、Unity上でライブ映像の収録を行いました。
Unity Recorderには収録タイプのMovie Recorder
を選択することで動画形式での書き出しができますが、
今回はImage Sequence Recorder
を選択する事で、Unity上でライブ映像を収録したものを連番画像として書き出しました。
その書き出した連番画像をAdobe AfterEffectsで最終的にコンポジットしてPVの動画にしています。
最後に
今回は、3DのR&Dにおけるフェーズ1の成果である「Cutie Star」のPVの技術的な部分を一部紹介しました。
普段、2Dのスマートフォン向けゲームを作ることが多い弊社にとっては、かなり挑戦的なプロジェクトでした。また、私自身も技術的な挑戦となり、成長の機会としても前向きに取り組むことができています。
ハイクオリティな2D表現を武器としている弊社ですが、これに加えてセルルックな3D表現も武器とし、作るゲームのクリエイティブやジャンルなどに応じて使い分けられる未来を目指します。
それに向けて、次のフェーズ2では今回のクオリティを保ったまま、モバイルでリアルタイムレンダリングできるように、引き続き3DのR&Dを進めます。
最後まで読んでいただき、ありがとうございました。次のフェーズ2での成果が出た際に、またブログを書こうと思います。
©2019 暁なつめ・三嶋くろね/KADOKAWA/映画このすば製作委員会 ©Sumzap, Inc.