ブラウザーでは、1つの巨大なスプライトシートを使用するのが最善ですか、それとも多数(10000)の異なるPNGを使用するのが最善ですか?


33

jQueryでゲームを作成していますが、そこでは約10000個の32x32タイルを使用しています。今まで、それらをすべて別々に使用していました(スプライトシートなし)。平均的なマップでは、約2000タイル(場合によってはPNGを再利用しますが、すべて個別のdiv)を使用し、パフォーマンスの範囲は安定(Chrome)から少し遅れた(Firefox)までです。これらの各divは、CSSを使用して絶対に配置されます。新しいマップがロードされるときだけ、ティックごとに更新する必要はありません。

gameQueryのように、CSSバックグラウンドポジショニングを使用してdivにspritesheetメソッドを使用するとパフォーマンスが向上しますか?

前もって感謝します!


3
地獄のどこにマップのために10 000タイルが必要ですか?ユーザー側ですべてのマップをアップロード/描画しないことをお勧めします。表示されている部分のみを表示します。ユーザーが移動したら、次のセクションを読み込みます。すべての3Dグラフィックスが機能する方法。
ディール

平均的なマップでは、2000種類のタイルを使用していますか、それとも合計で2000タイルだけですか?作成するマップの大きさはどれくらいですか?
ニックラーセン

1つまたはいくつかの大きな画像を背景として使用し、境界のポリゴン衝突検出を実行することを検討しましたか?
SAHornickel

回答:


50

私のおすすめ

小さいPNGが多すぎると、多くのネットワークオーバーヘッドが追加されます(HTTPリクエストのサイズだけでなく、PNGヘッダー、そしておそらくさらに重要なことに、効率的に圧縮できないため)。一方、非常に大きなPNGには、ロードに時間がかかり、連続したメモリチャンクでメモリ(10,000タイルで40メガバイト)を永続的に保持する必要があるという欠点があります。

は中間的な場所をお勧めします:いくつかの適度なサイズのPNG、例えばサイズ32×32の1024タイル。テーマごとにグループ化することもできます(たとえば、森林タイルのあるPNG、山タイルのあるPNG、都市タイルのあるPNG-ゲームのテーマはわかりませんが、アイデアはわかります)。

キャッシュ効率に関する注意

メモリアクセスの効率のため、スプライトシートの幅を広げすぎないでください。128×8192画像からのタイルのブリットは、8192×128画像からのブリットよりも常に高速です。

8192×128の画像の最初のタイルをブリットすることを想像してください。簡単にするために、1ピクセルが1バイトであると仮定します。最初の2行のピクセルは次のように配置されます(セルのメモリにはバイト番号が含まれます)。

┌────┬────┬───┬────┬──────────┬─────┐
  0   1 │...│ 31    ....    8191 1st line of pixels: bytes 0 to 8191
├────┼────┼───┼────┼──────────┼─────┤
81928193│...│8223   ....   16383 2nd line of pixels: bytes 8192 to 16383
├────┼────┼───┼────┼──────────┼─────┤
 ..  .. │...│ ..    ....    ... 

したがって、最初のタイトルの最初の行をblitするために、ブラウザエンジンはにバイト031取得します2行目をblitするには、バイト81928223取得する32行目までバイト253952253983取得します。

処理されるバイトの総数は32×32です。ただし、合計メモリ範囲は253984バイトを超えています。最新のCPUでは、これは32または33のキャッシュストールを意味します。対照的に、イメージが128×8192の場合、メモリ範囲は4000バイトのみであり、キャッシュストールが2つ以下であることを意味します。

今日のCPUは非常に高速であるため、キャッシュストールは非常に高価であり、計算がハングします。そのため、少なくとも理論的には、8192×128画像の代わりに128×8192画像を使用すると、潜在的に8倍高速になります。実際には、これはブリットの実装方法に依存します。基礎となるエンジン自体が画像をタイルに分割して問題を軽減する可能性があります。

これを正確に説明するのは簡単ではなく、あまり詳しく説明することも期待していませんでした。それが理にかなっていることを願っています!


4
「また、メモリアクセス効率のため、スプライトシートの幅を広げすぎないでください。128×8192画像からのタイルのブリットは、8192×128画像からのブリットよりも常に高速です。」-好奇心nice盛です。詳しく説明してください。:)
グリムショー

@DevilWithin:問題を説明しようとしました。十分に明確になっているかどうか教えてください!
サムホセバー

キャッシュの効率性は魅力的です。フレームレートに関してこれがもたらす違いについて数字はありますか?
グレゴリーアヴェリーウィアー

それが問題であるかどうか、実装の具体的なように見えるが、方法は、必ずその考慮し、感謝:)取ることが重要であるとテクスチャのAPIのOpenGLのような行為の場合
グリムショー

2
@DevilWithin:私が書いたのはCPUに対してのみ有効です-GPUは、超並列で、キャッシュ設定が大きく異なり、ランダムアクセス用に最適化された独自の内部形式を使用してテクスチャを保存します。これが、OpenGLで正方形の2のべき乗のテクスチャが推奨される理由であり、タイルセットについてもそのルールに従います。
サムホセバル

5

ラグの最大の原因の1つは、ブラウザー要求からサーバー、ブラウザーへのラウンドトリップであるため、1つの巨大なスプライトシートは(おそらく)より良いパフォーマンスを提供します。10,000のHTTP呼び出しは、10,000より大きいファイルを返す1つのHTTP呼び出しよりもはるかに長くかかります。

ゲームの構造と作成しているHTMLによっては、ラグを減らすために使用できる他のものがあるかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.