以前、次のようないくつかの質問があったことを知っています。 JSでFPSを確認しますか? -ある程度は機能しましたが、各ループが完了するまでにかかった時間を知ることができました。 。
私が探しているのは、もっと読みやすく、制御しやすいものです。 FPSカウンターのリフレッシュレートを遅く設定して、人間が読める形式にするか、アプリケーションを実行できる速度で実行できるようにしたいので、ある種の速度計で使用できます。
とにかく、これが私が今持っているコードです:
var lastLoop = new Date().getTime();
function updateStage()
{
clearCanvas();
updateStageObjects();
drawStageObjects();
var thisLoop = new Date().getTime();
var fps = (thisLoop - lastLoop);
$('#details').html(fps);
lastLoop = thisLoop;
iteration = setTimeout(updateStage, 1);
}
SetTimeout関数を1ミリ秒の速度に設定するのは正しいですか?これにより、ループができるだけ速くなると思っていました。
100フレームごとに数える必要があります。100フレームを実行するのに何ミリ秒かかったかを調べてから、ミリ秒が1000だった場合に何フレーム実行したかを計算しますか?この計算は何でしょうか?
結果をより正確にするために、1つのフレームが大幅に変化する可能性があるため、平均を表示する必要があると思いますが、これをどのように行う必要がありますか?
ヒントは大歓迎です。
ありがとう。
出力の更新が速いほど、測定に影響を与えることに注意してください。最小限ですが、高速化する必要がない限り、fps出力を1秒に1回以下で更新しようとしています。
一時的な一時的な中断が値にあまり強く影響しないように、結果にローパスフィルターを設定するのが好きです。これは移動平均よりも計算と書き込みが簡単であり、「現在の」読み取り値が実行全体の合計パフォーマンスの影響を受ける全体的な平均の問題はありません(たとえば、起動時の異常な読み取り値)。
まとめると、私が通常FPSを測定する方法は次のとおりです。
var fps = 0, now, lastUpdate = (new Date)*1;
// The higher this value, the less the FPS will be affected by quick changes
// Setting this to 1 will show you the FPS of the last sampled frame only
var fpsFilter = 50;
function drawFrame(){
// ... draw the frame ...
var thisFrameFPS = 1000 / ((now=new Date) - lastUpdate);
if (now!=lastUpdate){
fps += (thisFrameFPS - fps) / fpsFilter;
lastUpdate = now;
}
setTimeout( drawFrame, 1 );
}
var fpsOut = document.getElementById('fps');
setInterval(function(){
fpsOut.innerHTML = fps.toFixed(1) + "fps";
}, 1000);
私は何かを試しました、
変更した場合
lastUpdate = now
に
lastUpdate = now * 1 - 1;
NaNの問題は解決しました!これは、lastUpdateが定義されている場合にも使用されます。おそらく、日付をUNIXタイムスタンプに変換できないためです。
新しい結果は次のようになります。
var fps = 0, now, lastUpdate = (new Date)*1 - 1;
// The higher this value, the less the FPS will be affected by quick changes
// Setting this to 1 will show you the FPS of the last sampled frame only
var fpsFilter = 50;
function drawFrame(){
// ... draw the frame ...
var thisFrameFPS = 1000 / ((now=new Date) - lastUpdate);
fps += (thisFrameFPS - fps) / fpsFilter;
lastUpdate = now * 1 - 1;
setTimeout( drawFrame, 1 );
}
var fpsOut = document.getElementById('fps');
setInterval(function(){
fpsOut.innerHTML = fps.toFixed(1) + "fps";
}, 1000);
投稿されたソリューションを採用し、少し強化しました。こちらをご覧ください- http://jsfiddle.net/ync3S/
メインブロックは次のとおりです。
var fpsFilter = 1; // the low pass filter to apply to the FPS average
var fpsDesired = 25; // your desired FPS, also works as a max
var fpsAverage = fpsDesired;
var timeCurrent, timeLast = Date.now();
var drawing = false;
function fpsUpdate() {
fpsOutput.innerHTML = fpsAverage.toFixed(2);
}
function frameDraw() {
if(drawing) { return; } else { drawing = true; }
timeCurrent = Date.now();
var fpsThisFrame = 1000 / (timeCurrent - timeLast);
if(timeCurrent > timeLast) {
fpsAverage += (fpsThisFrame - fpsAverage) / fpsFilter;
timeLast = timeCurrent;
}
drawing = false;
}
setInterval(fpsUpdate, 1000);
fpsUpdate();
setInterval(frameDraw, 1000 / fpsDesired);
frameDraw();
このスレッドはGoogleの結果の上位にあるので、いじくり回して、もっとスムーズなものを思い付くことができるかどうかを確認します。
私たち全員がチームとして何を考え出すことができるかを見てみましょう。サードパーティのライブラリを使用しないことは常に適切であり、コードを誰にとっても移植可能にすることができます:)
-プラティマ
毎秒fpsカウンターをリセットする間隔を設定するだけです。
var fpsOut, fpsCount;
var draw = function () {
fpsCount++;
..Draw To Canvas..
..Get the fps value: fpsOut
requestAnimationFrame(draw);
};
setInterval(function () {
fpsOut = fpsCount;
fpsCount = 0;
}, 1000);
draw();