• ゲーム
  • Industry
  • リソース
  • コミュニティ
  • 学習
  • サポート
開発
Unityエンジン
任意のプラットフォーム向けに2Dおよび3Dゲームを構築
ダウンロードプランと価格
収益化
アプリ内課金(IAP)
ストア全体でIAPを発見し、管理する
Mediation
収益を最大化し、マネタイズを最適化する
Ad Quality
アプリのユーザーエクスペリエンスを保護する
Tapjoy
長期的なユーザーの忠誠心を構築する
すべてのマネタイズ製品
詳しく見る
詳しく見る
発見され、モバイルユーザーを獲得する
UnityベクターAI
プレイヤーを適切なゲームに接続する
Auraのオンデバイス広告
ピークエンゲージメント時にデバイス上のユーザーにリーチする
すべての成長製品
活用事例
3Dコラボレーション
リアルタイムで3Dプロジェクトを構築およびレビューする
没入型トレーニング
没入型環境でのトレーニング
顧客体験
インタラクティブな3D体験を作成する
すべての業界ソリューション
業界
製造業
運用の卓越性を達成する
小売
店内体験をオンライン体験に変換する
自動車
革新と車内体験を高める
全業界
技術ライブラリ
ドキュメント
公式ユーザーマニュアルとAPIリファレンス
開発者ツール
リリースバージョンと問題追跡
ロードマップ
今後の機能をレビューする
用語集
技術用語のライブラリ
インサイト
ケーススタディ
実際の成功事例
ベストプラクティスガイド
専門家のヒントとコツ
すべてのリソース
新機能
ブログ
更新情報、情報、技術的ヒント
お知らせ
ニュース、ストーリー、プレスセンター
コミュニティハブ
ディスカッション
議論、問題解決、つながる
イベント
グローバルおよびローカルイベント
コミュニティストーリー
Made with Unity
Unityクリエイターの紹介
ライブストリーム
開発者、クリエイター、インサイダーに参加する
Unity Awards
世界中のUnityクリエイターを祝う
すべてのレベルに対応
Unity Learn
無料でUnityスキルをマスターする
プロフェッショナルトレーニング
Unityトレーナーでチームをレベルアップ
Unity初心者向け
スタートガイド
学習を開始しましょう
Unityエッセンシャルパスウェイ
Unity は初めてですか?旅を始めましょう
ハウツーガイド
実用的なヒントとベストプラクティス
教育
学生向け
キャリアをスタートさせる
教育者向け
教育を大幅に強化
教育機関向けライセンス
Unityの力をあなたの機関に持ち込む
認定教材
Unityのマスタリーを証明する
サポートオプション
ヘルプを得る
Unityで成功するためのサポート
Success Plan
専門的なサポートで目標を早く達成する
FAQ
よくある質問への回答
お問い合わせ
私たちのチームに連絡する
プランと価格
言語設定
  • English
  • Deutsch
  • 日本語
  • Français
  • Português
  • 中文
  • Español
  • Русский
  • 한국어
ソーシャル
通貨
購入
  • プロダクト
  • Unity Ads
  • サブスクリプション
  • Unity Asset Store
  • リセラー
教育
  • 学生
  • 教育関係者
  • 教育機関
  • 認定資格試験
  • 学ぶ
  • スキル開発プログラム
ダウンロード
  • Unity Hub
  • ダウンロードアーカイブ
  • ベータプログラム
Unity Labs
  • ラボ
  • 研究論文
リソース
  • Learn プラットフォーム
  • コミュニティ
  • ドキュメント
  • Unity QA
  • FAQ
  • サービスのステータス
  • ケーススタディ
  • Made with Unity
Unity
  • 当社について
  • ニュースレター
  • ブログ
  • イベント
  • キャリア
  • ヘルプ
  • プレス
  • パートナー
  • 投資家
  • アフィリエイト
  • セキュリティ
  • ソーシャルインパクト
  • インクルージョンとダイバーシティ
  • お問い合わせ
Copyright © 2025 Unity Technologies
  • 法規事項
  • プライバシーポリシー
  • クッキーについて
  • 私の個人情報を販売または共有しないでください

「Unity」の名称、Unity のロゴ、およびその他の Unity の商標は、米国およびその他の国における Unity Technologies またはその関係会社の商標または登録商標です(詳しくはこちら)。その他の名称またはブランドは該当する所有者の商標です。

Hero background image
Last updated February 2020. 15 min read.

ライトベイク済みプレハブと、ローエンドの携帯電話で 60fps を実現するためのさまざまなヒント

このページで学ぶ内容:ゲームをすそ野の広いモバイル端末向けに最適化して、潜在的プレイヤーへのリーチ範囲を最大限に広げる方法についての、Michelle Martin 氏(MetalPop Games 社のソフトウェアエンジニア)からのヒント。

モバイル戦略ゲーム『Galactic Colonies』を開発していた MetalPop Games は、フレームレートが落ちたりデバイスが過熱することなく、プレイヤーがローエンドデバイスで巨大都市を構築できるようにするという課題に取り組んでいました。優美なビジュアルと安定したパフォーマンスのバランスをどのように取ったのかをご覧ください。

  • ローエンドデバイスで街づくり
  • モバイルでのライティングの課題
  • ライトベイキングという助け舟
  • ライトベイク済みプレハブ用パイプライン
  • UV チャンネルの活用方法
  • プレハブの作成
  • カスタムライトマップシェーダー
  • セットアップとスタティックバッチング
  • カスタム UI ダイアログ
  • フェイクライトと動的ビット
  • スペキュラー/グロス
  • ライトベイク済みプレハブのスタック
  • 制約はあります
Unity で制作されたゲーム『Galactic Colonies』

ローエンドデバイスで街づくり

最新のモバイルデバイスは高い処理能力を備えていますが、大規模で美しいゲーム環境を安定したフレームレートで実行することはいまだに困難です。より古いモバイルデバイス上で、大規模な 3D 環境で安定して 60 fps を達成するのは難題です。

開発者としては、ハイエンドのスマートフォンのみをターゲットとし、大多数のプレイヤーがゲームを滑らかに実行するのに十分なハードウェアを持っていると見なして開発を進めることもできます。ただし、いまだに数多くの古いデバイスが使用されている現状において、これは潜在的なプレイヤーを大量に締め出す結果となります。古いデバイスのユーザーはすべて、できれば排除したくない潜在的な顧客です。

当社のゲーム『Galactic Colonies』では、プレイヤーが異星人の住む星をコロニーとして、数多くの建物が建ち並ぶ大規模なコロニーを構築します。小さなコロニーの建物の数は 1 ダース程度ですが、大きなコロニーでは優に数百を超えます。

パイプラインの構築を開始したときの目標リストは次のとおりです。

  • 多数の建物が建ち並ぶ大きなマップがほしい
  • 安価で古いモバイル端末でも早い実行速度で動作するようにしたい
  • 光と陰影を美しく見せたい
  • 簡単で保守性に優れた制作パイプラインがほしい

モバイルでのライティングの課題

ゲームの巧妙なライティングは、3D モデルの見栄えを良くする鍵になります。Unity なら、手間なく巧みなライティングができます。ゲーム面を作って、ダイナミックライトを配置すれば、すぐ見栄え良く使えます。パフォーマンスを注視するなら、全ライトをベイクしてから、ポストプロセッシングスタックを通じて SSAO をいくつか追加し、その他の装飾を散りばめましょう。そうしたらもう、出荷するだけです!

モバイルゲームでは、ライティングの設定時にテクニックを駆使したり、何らかの回避策を講じたりする必要があります。例えば、ハイエンドデバイスを対象としている場合を除けば、ポストプロセッシングエフェクトには一切触れない方が良いでしょう。同様に、大きなシーンでダイナミックライトをふんだんに使ってしまうと、フレームレートが格段に低下してしまいます。

リアルタイムのライティングは、デスクトップ PC でも負荷が高くなりうるものです。モバイル端末ではリソースがさらに限られているので、こういった魅力的な華々しい機能をすべて盛り込む余裕は必ずしもありません。

ライトベイキングという助け舟

必要以上にシーンへ妙にこだわったライトを数多く設定して、ユーザーのスマートフォンのバッテリーを無駄に消耗させることは避けたいものです。

ハードウェアを限界まで酷使し続けると、スマートフォンが過熱し、その結果、端末保護のために処理能力がダウンします。これを回避するには、リアルタイムで影を描写する必要のないライトをすべてベイクするという方法があります。

(静的)シーンのハイライトと影を事前に計算しておいて、その情報をライトマップに保存するというのが、ライトベイキングのプロセスです。その後、どこでモデルを明るく(または暗く)するのかをレンダラーに伝え、ライトがあるような錯覚を作り出します。

この方法でレンダリングを高速化できます。負荷が高く時間もかかるライト計算がすべてオフラインで完了していて、レンダラー(シェーダー)は実行時にテクスチャーに格納された結果を見るだけで済むからです。

これには代償があって、ライトマップテクスチャーを余分に積み込む必要があります。これによりビルドのサイズが大きくなり、実行時に余分なテクスチャーメモリが必要になります。また、メッシュにライトマップ UV が必要になり、若干サイズが大きくなるので、ある程度スペースのロスが生じます。しかし全体的に見れば、圧倒的な高速化を実現できます。

しかし、私たちのゲームの場合、これは選択肢には入りませんでした。私たちのゲームの世界は、プレイヤーによってリアルタイムで構築されるものだからです。常にプレーヤーにより新しいエリアが発見され、新しい建物が追加され、既存の建物が改築されることから、どうしても効率的なライトベイキングは不可能です。プレイヤーによって常に変化する動的世界を相手にしている場合は、単に「Bake」ボタンを押しただけでは意味がありません。

そのため、私たちは高度にモジュール化したシーンのライトベイキングにおいて、さまざまな問題に直面しました。

ライトベイク済みプレハブ用パイプライン

Unity ではライトベイキングデータが、シーンデータに直接関連付けられるかたちで保存されます。これは、各ゲームステージが独立していてシーンが構築済みで、動的オブジェクトの数が限られている場合であれば問題になりません。ライティングを事前にベイクしておけば、それで十分です。

ところがゲームステージを動的に作成する場合、これではうまくいかないのは自明です。都市建築ゲームの世界は、創られていないのが前提です。世界の大部分はプレイヤーが何を、どこに建築するかによって動的に、その場で組み立てられていきます。これは通常、プレイヤーが何かを建築しようとするたびにプレハブをインスタンス化することで実現されます。

この問題の唯一の解決策は、関連するすべてのライトベイキングデータをシーンではなく、プレハブ内に格納することです。残念ながら、使用するライトマップのデータ、その座標、スケールをプレハブにコピーする簡単な方法はありません。

ライトベイクしたプレハブを処理するための安定したパイプラインを実現するには、個々のシーンごと(事実上複数のシーン)にプレハブを作成して、必要になったときにメインゲームにロードするのが、最善のアプローチにです。各モジュラーがライトベイクされ、必要になったらゲームに読み込まれます。

Unity でのライトベイキングの仕組みをよく見ると、実際にはライトベイクされたメッシュに他のテクスチャーが適用され、メッシュの明度が若干調整される(彩色されることもあります)だけのレンダリングであることがわかります。必要なのはライトマップテクスチャーと UV 座標だけです。そしてそのどちらも、ライトベイキングプロセスで Unity により作成されます。

ライトベイキングのプロセスで、Unity は新しい UV 座標(ライトマップテクスチャーの場所を示すもの)と、個々のメッシュのオフセットとスケールをワンセットで作成します。ライトを再ベイクするたびに、座標は変化します。

UV チャンネルの活用方法

この問題の解決策を練るうえで、UV チャンネルの仕組みと、それを最大限に活用する方法についての知識が役に立ちます。

各メッシュには複数の UV 座標セット(Unity では UV チャンネルと呼びます)を持つことができます。それぞれのテクスチャー(拡散、鏡面、バンプなど)がすべて画像内の同じ場所に情報を格納するので、たいていの場合 UV セットは 1 つで十分です。

しかしオブジェクトがライトマップのようなテクスチャーを共有していて、1 つの大きなテクスチャー内の限定的な場所に関する情報を参照する必要がある場合は、この共有テクスチャーで使用する別の UV 座標セットを追加する以外の方法がないこともあります。

複数の UV 座標を使うことの欠点は、メモリの消費量が増えることです。UV セットを 1 つではなく 2 つ使うと、メッシュの 1 つ 1 つの頂点で UV 座標が 2 倍になります。すべての頂点に 2 つの浮動小数点数が格納され、レンダリング時にそれらが GPU にアップロードされます。

プレハブの作成

Unity では、通常のライトベイキング機能を使用して座標とライトマップが生成されます。エンジンによってライトマップの UV 座標がモデルの 2 番目の UV チャンネルに書き込まれます。重要なのは、この場合は 1 番目の UV 座標セットが使えないことに注意することです。なぜなら、モデルをアンラップする必要があるからです。

各面に同じテクスチャを使用したボックスを想像してください。ボックスの個々の側面はすべて同じテクスチャを再利用するため、同じ UV 座標を持ちます。しかし、箱の各面にはそれぞれの光の当たり方と影のつき方があるため、これはライトマップされたオブジェクトでは機能しません。各面について、それぞれのライティングデータに基づくライトマップ内の独自のスペースが必要なのです。そこで、新しい UV セットが必要になります。

新しいライトベイクしたプレハブの設定に必要なのは、行方不明にならないようにテクスチャーとその座標を保存して、それをプレハブにコピーすることだけです。

ライトベイキングが完了したら、シーン内のすべてのメッシュを対象にしたスクリプトを実行し、オフセットとスケールの値が適用された状態で UV 座標をメッシュの UV2 チャンネルに書き込みます。

メッシュを更新するためのコードは、次のように比較的単純です(以下に例を示します)。

もう少し詳しく言うと:これはメッシュのコピーに対して行われ、オリジナルに対しては行われません。これは、ベイク処理中にメッシュをさらに最適化するためです。

コピーが自動的に生成されてプレハブに保存され、新しいマテリアルにはカスタムシェーダーと新しく作成されたライトマップが割り当てられます。これでオリジナルのメッシュには触れないまま、ライトベイクしたプレハブはすぐに使用できる状態になります。

Unity - ライトベイク済みプレハブ - マテリアルのセットアップ

カスタムライトマップシェーダー

これでワークフローがとてもシンプルになります。グラフィックスのスタイルや見た目を更新するには、該当のシーンを開いて納得いくまで変更を加えたらコードを実行して、自動化されたベイクとコピーのプロセスを開始します。このプロセスが終了すると、ゲームでは更新されたプレハブとメッシュが、更新されたライティングで使用されるようになります。

実際のライトマップテクスチャは、カスタムシェーダーにより追加されます。カスタムシェーダーは、レンダリング中にライトマップを 2 番目のライトテクスチャとしてモデルに適用します。シェーダーはとてもシンプルで短く、カラーとライトマップを適用するだけでなく、低負荷のフェイクスペキュラー/グロスエフェクトの計算を行います。

シェーダーコードを次に示します。上記の画像は、このシェーダーを使用したマテリアル設定の画像です。

Unity - ライトベイク済みプレハブ - ベイクレベル - MetalPop Games

セットアップとスタティックバッチング

このケースでは、すべてのプレハブが設定されている 4 つの異なるシーンを使います。私たちのゲームには熱帯、氷原、砂漠など、さまざまな生物群系があり、それに従ってシーンを分割しています。

特定のシーンで使われるすべてのプレハブで 1 つのライトマップを共有します。つまり、マテリアルを 1 つだけ共有しているプレハブに、テクスチャーが 1 つだけ加わることになります。その結果、すべてのモデルの静的レンダリングと、ほぼ世界全体のバッチレンダリングを、たった 1 つのドローコールで実行できるようになりました。

すべてのタイルや建物が設定されているライトベイキングシーンには、ローカライズしたハイライトを生成するために光源を追加しています。いずれにしてもベイクダウンすることになるので、セットアップシーンには必要と思った分だけいくつでもライトを配置しても構いません。

Unity - ライトベイク済みプレハブ - カスタマーシェーダーを使用したマテリアルのセットアップ - MetalPop Games

カスタム UI ダイアログ

ベイクプロセスは、必要なすべてのステップを示してくれるカスタム UI ダイアログで進めます。これにより、以下のことが確認できます。

  • 正しいマテリアルがすべてのメッシュに割り当てられている
  • プロセス中にベイクする必要がないものがすべて非表示になっている
  • メッシュが結合/ベイクされている
  • UVがコピーされ、プレハブが作成されている
  • すべてに正しく名前が付けられ、バージョン管理システムの必要なファイルがチェックアウトされている

適切に命名されたプレハブがメッシュから作成されるので、ゲームコードでそれらを直接ロードして使うことができます。このプロセス中にメタファイルも変更されるので、プレハブのメッシュへの参照が失われることもありません。

このワークフローのおかげで、好きなだけ建物を調整し、好きなようにライティングして、スクリプトですべてのことを処理することができます。

メインシーンに戻ってゲームを実行すると、何ら問題なく動作します。手作業で何か行ったり、他の部分を更新したりする必要はありません。

Unity - ライトベイク済みプレハブ - 『Galactic Colonies』 - MetalPop Games

フェイクライトと動的ビット

ライティングを 100% 事前にベイクしたシーンの欠点の 1 つは、動的オブジェクトやモーションを使用しにくくなることです。影を投影する要素はすべて、リアルタイムでライトや影を計算する必要があります。言うまでもなく、これは何としても避けたいものです。

しかし、動くオブジェクトがまったくないと、3D 環境は静的で活気のない世界に見えてしまいます。

見栄えするビジュアルを高速レンダリングで実現することが最優先なので、ある程度の制限は仕方ありません。生き生きとした動きのあるスペースコロニーや都市という印象を生み出すためには、大量のオブジェクトをすべて実際に動き回らせる必要はありません。また、動かすものの大部分を影がなくてもよい、または少なくとも影がなくても気にならないものにします。

私たちは、まずすべての建物のブロックを 2 つのプレハブに分けました。1 つは静的プレハブで、頂点の大部分とメッシュの複雑なビットがすべて含まれます。もう 1 つが動的プレハブで、含まれる頂点はできるだけ少なくなるようにします。

プレハブの動的な部分は、アニメーション化されたビットで、静的な部分の上に配置されます。これらはライトベイクされません。私たちは、非常に高速で負荷が軽いフェイクライティングシェーダーを使って、オブジェクトが動的にライティングされているかのような錯覚を作り出しました。

また、オブジェクトには影を持たせないか、動的ビットの一部としてフェイクシャドウを作成します。私たちのケースではサーフェスの大部分がフラットなので、これが大きな障害になることはありませんでした。

動的ビットに影はありませんが、ないことを知ったうえでよく見てみれば、かろうじて気付く程度です。動的プレハブのライティングもフェイクです。リアルタイムのライティングはまったく使われていません。

最初に私たちは負荷を軽くするための近道として、光源(太陽)の位置をフェイクライティングシェーダーにハードコーディングしました。これはシェーダーがルックアップして世界から動的に入力する必要がある、一種の less 変数です。

動的な値を使うより定数を使った方が、当然処理は早くなります。これにより基本的なライティング、メッシュの明るい面と暗い面が得られました。

スペキュラー/グロス

もう少し光沢を加えるため、私たちは動的オブジェクトと静的オブジェクトの両方のシェーダーにフェイクのスペキュラー/グロス計算を追加しました。スペキュラー反射はメタリックな見た目を演出する効果がありますが、表面のカーブも表現されます。

スペキュラーハイライトは反射の一種なので、カメラと光源の相対的な角度を正しく計算する必要があります。カメラが移動したり回転したりすると、スペキュラーは変化します。計算を行うすべてのシェーダーで、シーン内のカメラの位置とすべての光源へのアクセスが必要になります。

ただし、このゲームでは、スペキュラに使用する光源は太陽の 1 つだけです。私たちの場合、太陽は決して動かないので、指向性ライトと見なすことができます。使うライトを 1 つだけにして、ポジションと入射角が固定されていると想定したことで、シェーダーを大幅に簡略化できました。

加えて『Galactic Colonies』のカメラが、多くの都市建築ゲームと同じく見下ろし視点でシーンを映すタイプのものであることも功を奏しました。カメラは若干傾けたりズームインやズームアウトしたりできますが、上向き軸を中心に回転することはできません。

全体的に見れば、カメラは常に環境を上から見下ろしている状態です。スペキュラーの見た目を低負荷で偽装するため、私たちはカメラが完全に固定されていて、カメラとライトの角度が常に一定であるということにしました。

この方法で、改めて固定値をシェーダーにハードコーディングして、低負荷のスペキュラー/グロスエフェクトを実現できました。

スペキュラーに固定角を使うのは、もちろん技術的には正しくありませんが、実際にはカメラの角度がほぼ固定の場合と見分けはつきません。

プレイヤーにはあいからわずシーンは問題なく見えるわけで、リアルタイムライティングではそれだけが重要なのです。

リアルタイム ビデオ ゲームでの環境の照明は、物理的に正しくシミュレートすることよりも、視覚的に正しく見えるようにすることが常に重要でした。

ほとんどすべてのメッシュで 1 つのマテリアルを(ライトマップと頂点に由来する多くのディテールと合わせて)共有していたので、私たちはシェーダーにスペキュラーの値をいつどこに、どのくらいの強度で適用すればよいのかを伝えるためにスペキュラーテクスチャーマップを追加しました。テクスチャーには 1 番目の UV チャンネルを使ってアクセスするので、座標セットを追加する必要はありません。また、それほど詳細がないので解像度が非常に低く、ほとんどと言っていいほどスペースを使いません。

頂点数が少ない小さな動的ビットの一部については、Unity の自動ダイナミックバッチング機能を利用して、レンダリングをさらにスピードアップできました。

ライトベイク済みプレハブのスタック

ベイクしたこれらの影は、どれも新しい問題を引き起こす可能性を秘めています。特に比較的モジュール化の度合いが高い建造物に使う場合です。ある時私たちは、プレイヤーが建築できる倉庫の前に、保管されている商品の種類を表示させようとしました。

これが問題を引き起こしました。ライトベイクしたオブジェクトにライトベイクしたオブジェクトを重ねたからです。いわば、ライトベイクの例外が発生したのです!

別の負荷軽減テクニックを使ってこの問題に取り組むことにしました。

  • 追加オブジェクトが追加される予定であったサーフェスはフラットにし、特定のグレーカラーを使用してベースの建物と調和させる必要があった
  • そのトレードオフとして、より小さなフラットサーフェス上のオブジェクトをベイクし、それをわずかなオフセットのみでその領域の上に配置できた
  • ライト、ハイライト、色付きの光と陰影がすべてタイルにベイクされた
Unity - ライトベイク済みプレハブ - MetalPop Games

制約はあります

この方法でプレハブを構築してベイキングしたことで、ドローコール数を驚くほど少ない水準に抑えつつ、数百もの建造物がある巨大なマップを実現できました。私たちのゲームでは、世界のほぼ全部がたった 1 つのマテリアルでレンダリングされ、ゲームの世界よりも UI の方がたくさんのドローコールを使うほどです。Unity がレンダリングしなければならないマテリアルが少なければ少ないほど、ゲームのパフォーマンスは向上します。

これにより、パーティクル、天候効果、その他の装飾的な要素を追加する余地が生まれます。

この方法なら、比較的古いデバイスを使っているプレイヤーでも、安定した 60fps を維持したまま数百もの建造物が立ち並ぶ巨大な都市を作ることができます。

このコンテンツにご満足いただけましたか?

はい!

満足しました

いいえ。

いまいちでした