私の膨大な数の画像のために、またはそれにもかかわらず、スプライトシートを使用する必要がありますか?


13

2Dゲームを開発していますが、たくさんのスプライトがあります。3Dアニメーションとモデルを使用して2Dにレンダリングし、「フォールアウト」または「ディアブロ」に見えるようにしました。また、手で描くよりも簡単です(笑)。

私はすでにフレームレートを15fpsに削減しなければなりませんでした。これは、フレームをぎこちなくすることなく下げることができる最低のフレームレートでした。しかし、24フレームが非常に滑らかに見えたために悲しかったです。

これを行った理由は2つあります。

1)HDDスペースを削減します。画像が少ないほど、ゲーム全体が小さくなります。

2)RAMの消費を削減します。ロードする画像が少ないほど、RAMの制限を膨らませる問題を回避できる可能性が高くなります。

ただし、HDDスペースとRAMの両方でイメージを圧縮する方法があれば、それを行います。以前にテストしたことがありますが、ほとんどの場合、RGBA8888からRGBA5555に変換しても品質に変化はなく、TexturePackerプログラムでRGBA4444に変換してもほとんど影響を受けません。SFMLは、.PNGイメージのタイプに関係なく、同じ量のメモリを使用するように見えるため、現在これを行いません。異なる方法でロードする方法を調査しましたが、このテーマについては何も見つかりませんでした。

2Dビデオゲームの処理方法について多くの記事を読みました。コンセンサスは圧倒的です。優れたパフォーマンスのために、スプライトをより大きなテクスチャに詰め込みます!そこで、TexturePackerを使用して、小さなスプライトを非常に大きなスプライトシートにパックします。

ただし、キャラクターごとに10〜15のアニメーション、5つの移動方向、およびアニメーションごとに15〜40のフレーム(おそらく平均24)を用意する予定です。15アニメーション、5方向、およびアニメーションあたり平均24フレーム。つまり、1文字あたり1800個の個別フレームです。スプライトシートにパックされている場合、代わりに75個の画像のみです。(アニメーションごと、方向ごとに1つのスプライトシート。15* 5)

ゲーム内の1人の巨大なボスキャラクターの場合、スプライトシートを使用できず、一度に1つのイメージを単純に読み込む方法をプログラムする必要があります。パフォーマンスのためにこれを行うことができるかどうかはまだわかりません。

キャラクターについては、すでにスプライトシートにパックしています。1人のキャラクターが歩き回る場合、これはほとんどの場合うまくいくようですが、時々失速します。ただし、そのキャラクターのすべてのテクスチャをプリロードするのではなく、テクスチャをスワップアウトする悪い考えのコードに起因します。

テクスチャをプリロードする場合、スプライトシートには意味があります。各キャラクターに1800個の小さな画像をプリロードするのは悪い考えだと想像するだけです。

ただし、一度に1つずつメモリにストリーミングしたり、メモリからストリーミングしたりするのは非常に高速であるため、一度に1つの画像をメモリに保存するだけで済みます。これは、特定の瞬間に各キャラクターが45 + MBではなく数KBしか消費しないという意味ではないでしょうか?

ストリーミングは信じられないほど高速(1秒間にメモリとレンダリングに出入りする15枚の画像)が必要であり、画像は非常に小さいものの、キャラクタースプライトシートをロードすることをお勧めします。代わりにメモリに。しかし、とにかく大きなボスキャラクターのために、単一画像ストリームのようなレンダリングシステムをコーディングする必要があります。

私は実験してきましたが、単純なプロセスではありません。特に、現在グラフィックスを処理していないゲームエンジンの他の部分に取り組んでいるという事実を考えると。


1. RAMまたはHDDの制約を指定していません。高速アクセスするには何人のキャラクターが必要ですか?2.テキストに沿っていくつかの質問があります。太字で質問に集中したり、質問を部分に分割したりすることもできますか?
Kromsterは、サポートモニカ

あっ、すみません。多くはありません。一度に画面に表示される個々のキャラクターの最大数は約40になると想像します。人々がクライアントをクラッシュさせようとする場合、130は絶対最大数です。通常、通常の最大値は10である必要があり、絶対最大値は40未満です。ユーザーがスクリーンショット以外の理由で、またはキャラクターを詰め込む楽しみのために意図的にキャラクターを詰め込もうとする場合、40を超えるものは極端で極端な希少性になります。10を超えるものはまれであり、40を超えるものは非常にまれです。
Carter81

ゲームはPC専用(モバイルではない)2D RPGですが、モバイルプラットフォームが不可能な場合を除き、モバイルプラットフォームを除外したくありません。私が持っているRAMスペースは、ユーザーのPCとユーザーのVRAMにあるRAMに制限されていると思います。私は、それが賢明な非常に大きなHDDになることを厳しく疑います。HDDの消費量は、小さいほど良いというのが常に真実であるというだけです。
Carter81

画面上にいくつのユニークなキャラクターが必要ですか?
Kromsterは、サポートモニカ

20以下。それ以外の場合は、だまされない限り不可能です。通常5〜10。
Carter81

回答:


16

RTSリメイクでも同様のケースがあります。すべてのユニットと家はスプライトです。ユニットと家と地形用に18,000のスプライトがあり、さらにチームカラー用に別の〜6000があります(マスクとして適用されます)。長く引き伸ばされて、フォントで使用される〜30 000文字もあります。

アトラスの背後にある主な理由は次のとおりです。

  • 無駄なRAMが少ない(NPOTをGPUにアップロードすると、POTにストレッチ/パディングされますが、iOSといくつかのフレームワークでも同じです。ターゲットとするハードウェアの範囲を確認してください)
  • 少ないテクスチャスイッチ
  • より少ない大きなチャンクですべてを高速にロード

うまくいかなかったもの:

  • パレットテクスチャ。この機能はOpenGL 1.x 2.xにのみ存在し、それでもほとんどGPUメーカーによって削除されました。ただし、OpenGL + Shadersを目指す場合は、シェーダーコードでそれを行うことができます。
  • NPOTテクスチャでは、境界線が間違っていたりスプライトがぼやけたりする問題がありましたが、これはピクセルアートでは受け入れられません。RAM使用量もはるかに高くなりました。

これで、すべてが数十個の1024x1024アトラスに詰め込まれ(最新のGPUはさらに大きなサイズをサポートします)、それはPCゲームには非常に問題なく、〜300mbのメモリしか消費しません。私たちが持っていたいくつかの最適化:

  • RGBA8(チェッカーボードシャドウ)の代わりにRGB5_A1を使用するユーザーオプションを追加します。
  • 可能な場合は8ビットAlphaを避け、RGB5_A1形式を使用します
  • スプライトをアトラスにしっかりとパックします(ビンパッキングアルゴリズムを参照)
  • HDDから1つのチャンクにすべてを保存およびロードします(リソースファイルはオフラインで生成する必要があります)
  • ハードウェア圧縮形式(DXT、S3TCなど)を試すこともできます

モバイルデバイスへの移行を真剣に検討する場合、制約が心配になります。今のところは、ゲームを機能させてプレイヤーを引き付けるだけです!;)


これは断然最高のソリューションでした!私のスプライトはRGB5_A1とRGBA4444で異なってさえ見えませんが、メモリを節約します。RAMとVRAMにすべてのアセットをプリロードするチャットでの提案は完璧です。さらに、RAMを持っている人向けの高解像度クライアントや、フレームレートを半分にするオプションなど、オプションのグラフィックレベルを用意することを提案しました。
Carter81

5

ここに接線関連の答えがありますが、一般的なアイデアは、異なる時間にテクスチャをロードして描画する場合(レンダリング中に追加のテクスチャをロードしない場合)、2つの場所がありますあなたのパフォーマンスに影響します:

読み込み時間:

これは、テクスチャをメモリにアップロードする瞬間です。VRAMに送信するデータの全体量が、ロード時間の長さの大部分を定義します。テクスチャをRGBA4444のような小さなフォーマットにすると、これが速くなります。ただし、数百メガバイトのテクスチャをVRAMにアップロードしない限り、おそらくここでボトルネックが発生することはないでしょう。そうした場合、すてきなロード画面が待ちを楽にします。

テクスチャをアトラスに結合しても、VRAMに送信する情報の量はすべて同じになるため、ほとんど効果がありません。実際、テクスチャをアトラス化していて、アトラスに空のスペースを残さなければならない場合、実際にはより多くのデータをVRAM に送信するため、この部分は遅くなります!

レンダリングパフォーマンス:

すべてのテクスチャがVRAMに格納されると、テクスチャの量がレンダリングパフォーマンスに影響を与えることはありません。レンダリングのパフォーマンスに影響する要素は4つあります。

  1. レンダリング状態の変更レンダリング元の画像を変更するたびに、レンダリングに要する時間が大幅に増加します。一般に、状態の変化の量を最小限に抑えたい場合、連続して描画する複数の画像をテクスチャアトラスにグループ化することにより、状態の変化の量を減らすことができます。

    アトラスだけでは不十分です。パフォーマンスの向上を得るには、状態の変化を減らす方法でアトラスを作成する必要があります。たとえば、メインキャラクターをスプライトシートに入れるとパフォーマンスが向上すると思うかもしれませんが、フレームごとにそのスプライトシートからスプライトを1つだけ描画する場合、パフォーマンスを向上させることはできません。個別のファイル内の各スプライト。

    適切なアトラス化は簡単ではありませんが、一般に、同じレイヤーのスプライトを安全にグループ化できます。たとえば、1つのスプライトシートにすべてのGUIアイテムを含めることは非常に有望ですが、モンスターをアルファベット順にグループ化することはできません。

  2. ドローコール:一般に、ドローコールを最小限に抑えたい場合があります。目安として、2つの描画呼び出しの間にレンダリング状態の変更がない場合は、それらを1つの描画呼び出しに結合できます。より高度なパフォーマンスを得るには、たとえば8つのテクスチャサンプラーを使用し、8つのテクスチャごとにグループ描画呼び出しを行うことができるため、8つのテクスチャごとにテクスチャを変更するだけで済みます。

  3. 三角形の数:実際、描画する三角形が多いほど、描画に時間がかかります。ただし、最新のコンピューター、およびほとんどの2Dゲームでは、これを最大限に活用することはできません。フレームごとに何十万ものスプライトを安全に描画でき、それでも非常に優れたフレームレートを取得できます。GPUで問題が発生する前に極端な量のスプライトを描画している場合は、おそらくCPUに縛られることになります。

  4. API設定:すべてを正しく実行しても、フレームレートが異常に低い場合は、スプライトを描画する設定を確認してください。SFMLはわかりませんが、たとえば、Direct3D 9ではD3DUSAGE_DYNAMIC、またはで頂点バッファーを作成すると、D3DPOOL_MANAGEDレンダリング時間が10倍になります。もちろん、vSyncを使用すると、モニターのリフレッシュレートでフレームレートが制限されます。また、非整列FVFを使用すると、一部のGPUのパフォーマンスが低下する場合があります。これもDirect3D 9用です。

    あなたの場合、使用しているAPIのドキュメントを確認してください。

低から中程度の量のテクスチャ(1GB未満)のみがあり、描画するスプライトの量が少ない(フレームあたり100万未満)場合、最初に確認するのはAPI設定を変更することです。その後、レンダリング状態と描画呼び出しの量を減らします。


ロード時間を気にしない場合、RAMまたはVRAMを使い果たしていない限り、事前にすべてをメモリにロードする必要があると思いますか?
Carter81

RAM / VRAMが不足するのが怖いので、私はすべてにしか関心がありません。理由はわかりませんが、ユニークなスプライトが多すぎるエリアにロードしようとすると、ゲームをプレイしているユーザーがクラッシュしたり、画面上にキャラクターが多くなりすぎたりするとクラッシュします。誤解がなく、各スプライトが96KBを消費する場合、各一意のキャラクターが15アニメーション、5方向、およびアニメーションあたり平均24フレームを持っている場合、完全にロードされる個々のキャラクターはそれぞれ173MBです。画面には、一度に10個以上のユニークなキャラクターがいる場合があります。
Carter81

@KromStern:アトラスを作成し、空のスペース(パディング)を残す必要がある場合、データが大きくなるため、読み込み時間が長くなります。読み込み時間が長くなる原因は空きスペースであり、読み込み時間の合計はテクスチャの量ではなくデータの合計量に関係していることは明らかです。私はそこに誤解を招くものは何も見ていません。元の質問を理解するのに十分な知識を持つ人は、テクスチャとアトラスがPoTとnPoTであるすべての場合にドットに参加し、彼自身の結論を出すことができると思います。
パンダパジャマ

1
@ Carter81:「i5、1gb RAM、NVidia GT260、400mb hdd」などのターゲットハードウェア構成を選択して、そこから作業する必要があります。より弱く、RAMが少ないPCが常に存在します。
Kromsterは、サポートモニカ

明らかに、それらは常に15のアニメーションすべてを必要としません。ただし、10個のすべてのキャラクターが同時に「戦闘モード」になり、さらに5セットのアニメーション(歩行、実行、アイドル、非戦闘など)をさらに5つ(戦闘歩行、戦闘アイドル、戦闘など)?SFMLでそれを試みたとき、テクスチャアトラスを切り替えるときにクライアントの顕著なフリーズまたは一時停止が発生したため、テクスチャのスワップが怖いです。非常に多くのスプライトを処理するためのさまざまな戦略のボトルネックがどうなるかはわかりません。
Carter81
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.