ファンパレ「夢幻廻楼」技術の裏側 ~ 天候変化編~

はじめに

サムザップの『呪術廻戦 ファントムパレード(以下、ファンパレ)』開発チームに所属している二宮です。リリースしてから半年が経ち、新コンテンツ「夢幻廻楼」をリリースしました。このコンテンツでは、3Dを使用してライティングを施したリッチなグラフィックを提供しています。また、各階層にいる敵を倒して登っていくと天候が変わるギミックもあり、上層では暗くなって空間に歪みも発生するなどの特徴があります。

この記事では夢幻廻楼の背景の演出システムについて、大きく2点に分けて紹介します。

  1. 無限に登れる塔 x 天候変化 を実現する仕組み
  2. 塔の背景だけを歪ませる表現

夢幻廻楼のゲーム画面

無限に登れる塔 x 天候変化 を実現する仕組み

夢幻廻楼は定期的な階層追加を予定しているコンテンツで、上へと伸びていきます。さらに、上の階層ほど強力な敵が出現するため、強敵の気配をより強く演出するために特定の階層よりも上にいくと天候が変わる機能も必要でした。これらの要件を満たすため、以下の仕組みを作りました。

小さい塔を積み上げて無限に登れる塔を作る

塔、空、エフェクトを8階層分程度のブロックとして扱い、これを縦に積み上げることで塔を構成するようにしました。クリエイターと相談して、適切に絵が繋がるように各アセットを作ってもらいました。

今後階層が追加された時に、階層が足らなくなったらブロックを上に増やすことで、どこまでも塔を伸ばせるようにしています。

1ブロック分の塔
2ブロック分積み重ねた塔。
切れ目を曖昧にして、どこまでも続いているように見えるように工夫しています。

また、階層が伸びたからといって、素直にブロックを積み上げていくとパフォーマンスに影響が出てしまいます。そのため、見える範囲のブロックだけを生成し、生成していないエリアにカメラが移動したら適切にブロックを瞬間移動させることで、ブロックの生成数を抑えて快適にプレイするための工夫も行っています。

フリックによるカメラの移動に従って、ブロックが移動している様子。
必要最低限のブロックを運用して無限の塔を表現しています。

天候変化の仕組み

天候変化は、ライトマップ、カラーマップ、パーティクル、ポストエフェクトを天候ごとに用意して、テクスチャを切り替えることで行っています。さらに、夢幻廻楼では特定の階層をカメラが映した時に、シームレスに天候を切り替えたくてブレンディングによる切り替えを採用しています。

ライトマップのブレンディングはあまり一般的ではないため、ファンパレで使った手法を紹介します。まず、ライトマップはUnityによってベイクしたものを使用しました。これは、ライトマップの更新作業が楽になることを狙っています。今回開発したカスタムシェーダーを使用して、2枚のライトマップのブレンディングを行います。

// 元々, SAMPLE_GIで定義されていたメソッドの中身をTextureを外部から指定できる形に変更したメソッド
half3 SampleLightmap(TEXTURE2D(lightMapName), float2 staticLightmapUV)
{
    #ifdef LIGHTMAP_ON
    #ifdef UNITY_LIGHTMAP_FULL_HDR
    bool encodedLightmap = false;
    #else
    bool encodedLightmap = true;
    #endif
    half4 decodeInstructions = half4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0h, 0.0h);
    half4 transformCoords = half4(1, 1, 0, 0);
    return SampleSingleLightmap(
        TEXTURE2D_LIGHTMAP_ARGS(lightMapName, sampler_LinearClamp), LIGHTMAP_SAMPLE_EXTRA_ARGS,
        transformCoords, encodedLightmap, decodeInstructions);
    #else
    return half3(1,1,1);
    #endif
}
// FirstLightmap, SecondLightmapをブレンディング
const half3 bakedGI1 = min(2, SampleLightmap(_FirstLightmap, input.lightmapUV));
const half3 bakedGI2 = min(2, SampleLightmap(_SecondLightmap, input.lightmapUV));
const half3 bakedGI = lerp(bakedGI1, bakedGI2, _LightmapWeight);

夢幻廻楼の各種テクスチャ。天候: 夕焼け。

夢幻廻楼の各種テクスチャ。天候: 夜。

塔の背景を歪ませる表現

強敵の気配を出すため、通常とは異なる雰囲気を出すために、塔の背景を歪ませる効果を追加しました。しかし、「塔の奥の空間が歪んでいる」という状況を作りたいので、手前の塔によって奥の歪みを隠す必要がありました。また、一部の演出にて歪み表現が二重でかかることも考慮し、システムを検討しました。

要件を精査してみたところNovaShaderのDistortion機能がほぼ全ての要件を満たしていそうだったので、部分的に導入を決めました。これによりずいぶん工数が削減されて、絵作りを高速に進めることができました。



しかし、クリエイターにテストを進めてもらっていたところ、NovaShaderの仕組みだけでは手前の塔が周辺のDistortionに巻き込まれるケースが見つかり、これを解決するためにファンパレ用に少し改変したものを使っています。

NovaShaderのDistortionの仕組みとファンパレにおける課題

NovaShaderはDistortion効果によってUVがどれくらいずれるかを別バッファに描画し、この時ZTestを行うことで手前オブジェクト (夢幻廻楼では塔) による遮蔽を考慮します。最後にバッファに書き込んだ情報を元にフレームバッファのRGB値をずらし、Distortion効果を表現します。

UVズレの大きさをバッファに書き込む際のZTestによって塔自体は歪みませんが、塔の周辺画素を書き込む時には歪みが適用されるため、歪みの方向によっては塔の画素を取り込んでしまうことがあり、ファンパレではこれが課題となりました。

ファンパレで課題となった、塔の一部が空間の歪みに巻き込まれてしまう様子。ZTestの効果で塔自体に歪みはありませんが、塔右側の棒あたりには歪みが適用されてしまっているように見えます。

解決策:手前背景の周辺画素の歪みを弱くする

ファンパレでは、塔の近くの画素を描画する際に歪みを抑えるための改良を施しました。

改良内容をまとめます。

  1. フレームバッファのうち、塔が描かれている範囲のマスク画像を取得
    • ZBufferから塔までの距離を元に、塔のマスク画像を生成
  2. マスク画像をぼかす
  3. ぼかしたマスク画像をもとに塔周辺の画素のみ歪みの強度を弱くする

細かい説明は数値や数式と絡むので、ぼかしたマスク画像から歪みの強度を調整するShaderコードを載せておきます。

// _DistortionWeightBuffer: 塔のシルエットをぼかしたマスク画像 (ぼかす前は塔の部分が0, 他が1)
half distortionWeight = SAMPLE_TEXTURE2D(_DistortionWeightBuffer, sampler_ScreenSpaceUvTexture, uv).r;

// 0(塔のエリア) , 1(塔以外のエリア)の2値画像をぼかしたもの. 値域は0 ~ 1. ただし境界は0.5になっているはず
// ぼかす前の塔が存在したエリアは、ぼかした後の値は0 ~ 0.5になる
// 今回 歪みを弱めたいエリアは塔の近くで、塔ではない部分なので, 0.5 < distortionWeight < 1のエリア.
// distortionWeight: 0.5 ~ 1のエリアを alpha: 0 ~ 1でブレンディングするために, 0.5 ~ 1.0のエリアを 0 ~ 1に変換. 1以上は1にする
distortionWeight = saturate(distortionWeight * 2.0 - 1.0);
// 手前オブジェクト周辺の歪みを弱めるため, distortionによるuvのずれ幅(dist) に対して乗算
dist *= distortionWeight;

改善後のDistortionを適用した様子
塔右側の棒の歪みがほぼなくなっていることがわかると思います

おわりに

ファンパレ「夢幻廻楼」技術の裏側 ~ 天候変化編~ ということで、夢幻廻楼の演出システムについて紹介しました。この記事では、無限に登れる塔の設計や、天候が変化する演出、そして背景のDistortionエフェクトなど、技術的な工夫点や細かいこだわりを詰め込みました。特に、天候変化や背景の歪みといった視覚的な要素は、ゲームの雰囲気を一層引き立てる重要な要素となっています。

このような細部へのこだわりが、新鮮で魅力的な体験につながると考えています。これからも、常にユーザーの皆様の期待を超えるようなコンテンツを提供できるよう取り組んでいきます。

最後まで読んでいただきありがとうございました。この記事が、ゲーム開発に興味を持っている方々の参考になれば幸いです。今後も、ファンパレのさらなる進化にご期待ください。


©芥見下々/集英社・呪術廻戦製作委員会 ©Sumzap, Inc./TOHO CO., LTD.

二宮 章太

株式会社サムザップ クライアントエンジニア 2015年入社。
『NieR Re[in]carnation』『呪術廻戦ファントムパレード』等の開発に従事。
最近は演出周りの仕事が多めです。