現代のゲームでダブルまたはトリプルバッファリングはどのような問題を解決しますか?


31

ダブル(またはトリプル)バッファリングを使用する原因の理解が正しいかどうかを確認したい:

60Hz更新のモニターは、モニター表示を1秒間に60回更新します。モニターがモニター表示を更新する場合、彼はピクセルのピクセルとラインのラインを更新します。モニターは、ビデオメモリからピクセルのカラー値を要求します。

今ゲームを実行している場合、このゲームは常にこのビデオメモリを操作しています。

このゲームがバッファ戦略(ダブルバッファリングなど)を使用しない場合、次の問題が発生する可能性があります。

これで、モニターはモニター表示を更新しています。この時点で、モニターは前半のモニター表示を既に更新していました。同時に、ゲームは新しいデータでビデオメモリを操作していました。これで、モニターは後半のモニターにアクセスし、ビデオメモリからこの新しい操作データを表示します。問題は裂け目またはちらつきです。

バッファ戦略を使用する場合の私の理解は正しいですか?他の理由はありますか?

回答:


62

基本的に、レンダリングの主な目標は、モニターに表示される各フレームが単一の一貫した画像を表示することです。これを達成するために使用された、または使用されたいくつかの異なる戦略があります。

以下では、「vsync」に言及します。Vsyncは、モニターが新しい画面イメージの描画を開始する瞬間です。これは、従来のCRT画面で「vblank」が開始するポイントであり、スキャンラインは一時的に描画を停止し、モニターの上部に戻ります。この瞬間は、フレームコヒーレンスへのアプローチの多くにとって非常に重要です。

「ティアリング」とは、画面が1つのフレーム内で2つの異なる画像からレンダリングされるときに私たちが呼ぶものです。たとえば、次々に表示することを目的とした2つの画面イメージを描画したが、代わりにモニターがフレーム1の上半分とフレーム2の下半分を表示した場合、それは「ティアリング」です。これは、vblank中ではなく、モニターの描画中にモニターが読み取っているデータを変更するために発生します。(最新のプログラムでは、これは通常、ユーザーがドライバー設定でvsyncの待機を無効にしているために発生します)

ゼロバッファ

最も古いハードウェアでは、フルスクリーン画像を保持するのに十分なメモリがないことがよくあったため、スクリーン画像を描画する代わりに、モニターがそのラインを描画している間に各スキャンラインの色を個別に指定する必要がありました。たとえば、Atari 2600では、テレビが実際にスキャンラインを描画し始める前に、スキャンラインの各ピクセルにどの色を入れるかを指定するマシン命令サイクルが76だけでした。そして、次のスキャンラインなどにコンテンツを提供するために、76命令サイクルがありました。

シングルバッファ

「単一バッファ」コンテキストで描画する場合、モニタから読み取られているVRAMに直接描画します。このアプローチでは、「スキャンラインをレース」します。一般的な考え方は、スキャンラインが画面上部の前のフレームのコンテンツの描画を開始すると、その背後の VRAM 描画するというものです。したがって、スキャンラインが最後のフレームの画面イメージを描画している間に、スキャンラインの後ろに次のフレームを描画します。

一般的に、あなたはあなたが再び周り来て、あなたのしている描画こと、また、取得することはありませんにピクセルを追い越しにより走査線「ラップ」の前に次のフレームの画像の描画を終了しようとしているの走査線の、または他のあなたの新しいですフレームは、前のフレームであるはずだったものを描画する場合があります。

このため、通常、シングルバッファレンダリングは、スキャンラインを上から下、左から右に描画することで機能しました。他の順序で描いた場合、スキャンラインが再び出現し、まだ描画していない「次の」画像の一部を見つける可能性があります。

最近のオペレーティングシステムでは、通常、シングルバッファーで描画する機会はありませんが、これは30年前にはかなり一般的でした。(まあ、私は今、古いと感じていますか?これは、私が最初にゲーム開発を始めたときにやっていたことです)

ダブルバッファ

これは、以前の戦略のいずれよりもはるかに簡単です。

ダブルバッファリングシステムでは、2つの異なる画面イメージを保存するのに十分なメモリがあるため、一方を「フロントバッファ」、もう一方を「バックバッファ」として指定します。「フロントバッファ」は現在表示されているものであり、「バックバッファ」は現在描画している場所です。

バックバッファーへの画面イメージの描画が完了したら、vsyncまで待機してから、2つのバッファーを交換します。この方法では、バックバッファーがフロントバッファーになり、逆もまた同様であり、モニターが何も描画していない間に全体のスワップが発生しました。

トリプルバッファ

ダブルバッファアプローチでよく発生する問題の1つは、バックバッファへの描画が完了した後、バッファをスワップして作業を続行する前に、vsyncを待機する必要があることです。その間に計算を行っていたかもしれません!さらに、バッファ間でスワップを待機している間、そのバックバッファ内の画像は古くなり、ユーザーの知覚遅延が増加します。

トリプルバッファシステムでは、3つのバッファを作成します。1つのフロントバッファと2つのバックバッファです。アイデアはこれです:

モニターはフロントバッファーを表示しており、バックバッファー#1に描画しています。モニターがフロントバッファーの描画を完了する前にバックバッファー#1への描画を完了した場合、vsyncを待つ代わりに、すぐに次のフレームのバックバッファー#2への描画を開始します。終了してもvsyncがまだ届かない場合は、バックバッファー#1への描画を開始します。最終的にvsyncが発生すると、いずれかのバックバッファーが完成し、フロントバッファーと交換できるという考え方です。

トリプルバッファリングの利点は、ダブルバッファリングアプローチでvsyncの待機に費やした時間を失わないことです。また、フロントバッファにスワップされたイメージは、vsyncを待機していたイメージよりも「新しい」場合があります。 8ms。トリプルバッファリングのマイナス面は、追加の画面イメージを保存するために追加のメモリが必要になることと、CPU / GPUの使用率が高くなることです(これも、vsyncを待つために遅くならないためです)。

通常、現代のドライバーは、多くの場合、舞台裏で透過的にトリプルバッファリングを実行します。ダブルバッファリングを行うコードを記述すると、ドライバーは実際に制御を早期に戻し、使用したいバックバッファー間のスワップを内部的に処理しますが、コードはそれを認識しません。

GPUベンダーは現在、トリプルバッファリングを自分で実装しないことを推奨しています。ドライバーが自動的にそれを行います。


7
これは信じられないほど詳細な答えであり、多くのことがそのまま行われる理由を説明します(画面座標空間など)。また、「なぜ4倍のバッファーではないのですか?5倍のバッファー?」バッファスワッピングがバックグラウンドで発生したこと、つまり2つのバックバッファが必要な最大値であることを認識していませんでした。賛成。
lunchmeat317 14

実際には、クワッドバッファリングが存在します。これは、立体視用のダブルバッファリングです。swiftless.com/tutorials/opengl/smooth_rotation.html
Narek

@Narekいいえ。リンクからの引用:「実際のポイントがないため、コンピューターグラフィックス環境で実際のクワッドバッファーを実際に有効にすることはできません」。2つの異なるビューで同時にダブルバッファリングを行うことを「クアッドバッファリング」とすることは、単なる言葉遊びです。本物ではありません。
トレバーパウエル

@TrevorPowell含めるのを忘れた部分を追加します:「まあ、通常、クワッドバッファリングは、立体視環境でのダブルバッファリングを指します。たとえば、通常3Dの目的で2つのディスプレイがあり、各目がダブルバッファリングされます。」コンテキストがより明確になるかもしれません。
ナレク

@TrevorPowellあなたのポイントは完全に明らかですが。1つのレンダーバッファーに対して3つ以上のバッファーを使用することは意味がありません。
ナレク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.