処理落ちしても一定のFPS制御のロジックについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
Ketty
記事: 103
登録日時: 11年前

処理落ちしても一定のFPS制御のロジックについて

#1

投稿記事 by Ketty » 11年前

いつもお世話になっております。Kettyです(^^)

ISLeさんが公開してくださっている
「処理落ちしても一定のFPS制御」のロジックについての質問です。
http://isle.cocolog-nifty.com/blog/2011 ... -927b.html

もし、ここで質問することが不適切であればご指摘くださいm(__)m
また、私の知識や理解が未熟であるため、思い違いなどあるかもしれないのですが、
その場合もご指摘いただけると助かります。

isle.videogame.20120426(.zip)の
VGLibMain.cppの
run関数のFPS制御部分(69行目~104行目)についてなのですが、

【質問1】
まず、このFPS制御部分の流れとして以下のように解釈しているのですが正しいでしょうか?

1~58のそれぞれのフレームについて、
Step1 あるべき経過時間(disttime)を求め、
Step2 実際の経過時間と(pasttime)を求め、
Step3 disttimeとpasttimeの差分によって以下パターンで分岐
 パターンA:垂直帰線期間より早く到達しまっている場合は、SleepでウェイトしてScreenFlipする
 パターンB:垂直帰線期間より遅れて到達してしまっている場合は次の垂直帰線期間に間に合うタイミングまで待つ

【質問2】
おそらく、パターンBの待機のことを、スキップする(skipped_count ++)と表現されているのだと思うのですが、
ゲームプログラムなどで一般的に言われているフレームスキップ法というものはまた別物という認識であってますか?
(私は、更新処理のあと描画処理を1回分飛ばすことをフレームスキップというのかなと考えていました)

以下は、【質問3~5】となります。
77~81行目について

コード:

int passtime = GetNowCount() - lasttime;
if (passtime < 0 || skipped_count >= 8) {
	lasttime += passtime - disttime;
	passtime = disttime;
}
if (passtime < 0 || skipped_count >= 8)
この条件の意味がわかりません。
【質問3】経過時間が0より小さくなるというのはどういうときにありえるのでしょうか?
【質問4】また、スキップ数が8以上とありますが、この8というのはどこからきたものでしょうか?
たとえば、1や100ではダメで、8でなければいけない理由というのがあるのでしょうか?

【質問5】条件がtrueになった場合に実施される処理の意味を教えてください。
89~90行目にも同じ処理があるのですが、どういう効果があるのかよくわかりません。

最新時間を実経過時間とあるべき経過時間の差分を埋めて…
lasttime += passtime - disttime;
実経過時間をあるべき経過時間で上書きしていることから…
passtime = disttime;
あるべき時間ぴったりに来たように振る舞わせるという意味になるのかと推測しています。

以上です。ISLeさんご本人でなくとも、ご教示してくださる方がいらっしゃると助かりますm(__)m

ISLe()

Re: 処理落ちしても一定のFPS制御のロジックについて

#2

投稿記事 by ISLe() » 11年前

【回答1】
この処理はVSYNCを完全に無視することで成り立っています。
常に理想のタイミングのみを目指してそれに間に合ったか間に合わなかったかだけを判定します。
VSYNC待ちが有効のときScreenFlipはタイミングをずらす邪魔者です。

【回答2】
スキップは、いわゆる自動フレームスキップと言われる処理のためのヒントで、同じものです。
ただし、スキップの原因をVSYNCには限定しません。

【回答3】
このコードを最初に書いたのがJavaで、Javaでは現在時刻を使うため巻き戻る可能性を考慮しました。
Windows95時代にはWin32APIでもクロックが巻き戻る現象の報告をゲーム開発者向けのメーリングリストで見た記憶があります。
どんなプラットフォームにおいてもあって無駄になるものではないと思いますし。

【回答4】
コマ落ちが8コマ超えたらとてもプレイに耐えないだろうということで加えてあるコードです。
そういうときは早くプレイを諦めてもらうほうが良いと思うのでメインの処理に復帰する方を優先させてます。
数値は個人的な感覚で適当に決めました。

【回答5】
推測どおりです。
異常事態には即座にループを抜けてもらう必要があると思うので。


この処理はメインの処理がある程度重くなるとVSYNC待ちとのタイミングのズレで常にコマ落ち状況になることがあります。
なのでVSYNC待ちが有効のときは起動後に動作が安定した際など適度にタイミングをリセットしなければいけません。
リセットする処理とそれを起動するためのフラグはあるのにフラグをONにする公開メンバ関数をまだ用意していなかったりしますが。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: 処理落ちしても一定のFPS制御のロジックについて

#3

投稿記事 by Ketty » 11年前

>>ISLeさん
丁寧にご回答くださりありがとうございます。
赤色の番号だけ、追加で質問させてくださいm(__)m

>【回答1】
>この処理はVSYNCを完全に無視することで成り立っています。
>常に理想のタイミングのみを目指してそれに間に合ったか間に合わなかったかだけを判定します。
>VSYNC待ちが有効のときScreenFlipはタイミングをずらす邪魔者です。
実装では、SetWaitVSyncFlag( False )しておられないようですが、
ScreenFlipのVSYNC待ちの有効/無効は、どちらであっても
この処理の本質(理想タイミングを目指す)には関係ない、という認識であってますでしょうか?

>【回答2】
>ただし、スキップの原因をVSYNCには限定しません。
VSYNCの遅延のみならず、ゲームロジックの遅延(処理落ち)も、
等価にスキップ要因として扱う、という意味であってますか?

>【回答3】
クロックが巻き戻る現象というのがある(あった)とは知りませんでした。
とても貴重な情報ありがとうございます。

>【回答4~5】
なるほど。異常時にそなえてメインに復帰させるためのもので、
判定用の8という数値はお好みで・・・ということですね(^^)

ISLe()

Re: 処理落ちしても一定のFPS制御のロジックについて

#4

投稿記事 by ISLe() » 11年前

Ketty さんが書きました: >この処理はVSYNCを完全に無視することで成り立っています。
>常に理想のタイミングのみを目指してそれに間に合ったか間に合わなかったかだけを判定します。
>VSYNC待ちが有効のときScreenFlipはタイミングをずらす邪魔者です。
実装では、SetWaitVSyncFlag( False )しておられないようですが、
ScreenFlipのVSYNC待ちの有効/無効は、どちらであっても
この処理の本質(理想タイミングを目指す)には関係ない、という認識であってますでしょうか?
VSYNC待ちの有効無効はアプリ側で選択できます。
タイミングにシビアなプレイヤーがテアリングを我慢してもVSYNC待ちを切ってプレイすることができます。
VSYNCが有効のときテアリングが発生しないかわりに、十分なスペックであっても気付かないレベルでコマ落ちの発生するリスクがあります。

最近話題のNVIDIAのG-SYNCを新たに採用しようというときでもこの部分は何も変える必要がありません。
G-SYNCでハード側のVSYNCに対する待機時間がゼロになるのは、VSYNCが無効のときと同じことだからです。
Ketty さんが書きました: >ただし、スキップの原因をVSYNCには限定しません。
VSYNCの遅延のみならず、ゲームロジックの遅延(処理落ち)も、
等価にスキップ要因として扱う、という意味であってますか?
No.1の投稿でリンクされているブログ記事がそれを説明している記事ですね。


PCモニタのリフレッシュレートとは微妙に異なるアーケードゲームを移植する際にアプリ側で対策せずとも済むように考えたのが最初ですが、遅延を抽象化することで普遍的なロジックになっていると思います。

アバター
Ketty
記事: 103
登録日時: 11年前

Re: 処理落ちしても一定のFPS制御のロジックについて

#5

投稿記事 by Ketty » 11年前

>>ISLeさん
度重なる質問にもかかわらず、貴重な情報つきでご回答くださり、ありがとうございますm(__)m

>VSYNC待ちの有効無効はアプリ側で選択できます。
>VSYNCが有効のときテアリングが発生しないかわりに、十分なスペックであっても気付かないレベルでコマ落ちの発生するリスクがあります。
なるほど。
ティアリングOKとするか、コマ落ちOKとするか、アプリとして、ユーザーが選択できる手段を提供することに意義があるわけですね。
参考になりました。

>最近話題のNVIDIAのG-SYNCを新たに採用しようというときでもこの部分は何も変える必要がありません。
>PCモニタのリフレッシュレートとは微妙に異なるアーケードゲームを移植する際に
>アプリ側で対策せずとも済むように考えたのが最初ですが、
>遅延を抽象化することで普遍的なロジックになっていると思います。
私は、ゲームPCのハードについてはまったく知識がなかったので、G-SYNCなるものを知りませんでした。
またもや貴重な情報ありがとうございます。

何よりも、アプリケーションがハードを意識せずに済むコーディングであるということの素晴らしさにとても共感します。
こういうことは、ひょっとすると有識者の方々にとっては当たり前のことなのかもしれませんが、
私のような初級者にはとても難しい課題だと思うのです。

特にFPS制御に関しては、一体どんなロジックを組むのがよいのか・・・と長く悩んでいましたのでとても感銘を受けました。
ありがたく使わせていただきますm(__)m
(まんまではなくて、アレンジするつもりです(^^)/)
オフトピック
こういう考え方とか、ソースが広く認知されたら(FPS制御のロジックといえば、これだろ!くらいにでも広まれば)、
ゲームプログラミングの敷居が低くなって、より多くの人がゲーム作りやすくなるんではないかなぁと思ったりします。
(コピペ当たり前!みたいになってしまうと、より多くのでたらめなプログラムソースが量産されるような懸念もありますが)

さぁみんなゲームプログラミングしようぜ!悩もうぜ!すごく勉強になるよ! ←これを言いたい(^^)

閉鎖

“C言語何でも質問掲示板” へ戻る