Javascript 在webGL中记录FPS
我试图比较移动设备上3d应用程序的性能。我在webGL中设置了一个3d太阳系,我试图记录或至少显示FPS。到目前为止,这就是我所拥有的: 体内Javascript 在webGL中记录FPS,javascript,webgl,Javascript,Webgl,我试图比较移动设备上3d应用程序的性能。我在webGL中设置了一个3d太阳系,我试图记录或至少显示FPS。到目前为止,这就是我所拥有的: 体内 <script language="javascript"> var x, message; x = Time; message = "fps is equal to "; document.write (message); // prints the value of the message variable document.write
<script language="javascript">
var x, message;
x = Time;
message = "fps is equal to ";
document.write (message); // prints the value of the message variable
document.write (x); //prints the value of x
</script>
我在画布底部得到的输出是“fps等于null”
任何帮助都会很好 我假设您反复调用drawScene,但如果只设置了一次
x
,则不会在每次调用drawScene时更新。另外,您在Time
中存储的是经过的时间,而不是每秒帧数
下面这样的怎么样?其思想是计算渲染的帧数,并在经过一秒钟后将其存储在fps变量中
<script>
var elapsedTime = 0;
var frameCount = 0;
var lastTime = 0;
function drawScene() {
// draw scene here
var now = new Date().getTime();
frameCount++;
elapsedTime += (now - lastTime);
lastTime = now;
if(elapsedTime >= 1000) {
fps = frameCount;
frameCount = 0;
elapsedTime -= 1000;
document.getElementById('test').innerHTML = fps;
}
}
lastTime = new Date().getTime();
setInterval(drawScene,33);
</script>
<div id="test">
</div>
var elapsedTime=0;
var frameCount=0;
var lastTime=0;
函数drawsecene(){
//在这里画场景
var now=new Date().getTime();
frameCount++;
elapsedTime+=(现在-上次);
上次=现在;
如果(elapsedTime>=1000){
fps=帧数;
帧数=0;
elapsedTime-=1000;
document.getElementById('test').innerHTML=fps;
}
}
lastTime=新日期().getTime();
设置间隔(drawScene,33);
显示FPS非常简单,实际上与WebGL没有任何关系,只是大家都想知道。这是一个小的FPS显示
const fpsElem=document.querySelector(“#fps”);
然后设=0;
函数渲染(现在){
现在*=0.001;//转换为秒
const deltaTime=now-then;//计算自上一帧起的时间
然后=现在;//记住下一帧的时间
常量fps=1/deltaTime;//每秒计算帧数
fpsElem.textContent=fps.toFixed(1);//更新fps显示
请求动画帧(渲染);
}
请求动画帧(渲染)代码>
fps:
我创建了BarıUşaklı答案的面向对象版本。
它还跟踪最后一分钟的平均fps
用法:
function OverrideRingBuffer(size){
this.size = size;
this.head = 0;
this.buffer = new Array();
};
OverrideRingBuffer.prototype.push = function(value){
if(this.head >= this.size) this.head -= this.size;
this.buffer[this.head] = value;
this.head++;
};
OverrideRingBuffer.prototype.getAverage = function(){
if(this.buffer.length === 0) return 0;
var sum = 0;
for(var i = 0; i < this.buffer.length; i++){
sum += this.buffer[i];
}
return (sum / this.buffer.length).toFixed(1);
};
全局变量:
var fpsCounter;
启动程序时在某处创建对象:
fpsCounter = new FpsCounter();
在draw()函数中调用update方法并更新fps显示:
function drawScene() {
fpsCounter.update();
document.getElementById('fpsDisplay').innerHTML = fpsCounter.getCountPerSecond();
document.getElementById('fpsMinuteDisplay').innerHTML = fpsCounter.getCountPerMinute();
// Code
}
注意:为了简单起见,我只将fps显示更新放在draw函数中。在每秒60帧的情况下,它会被设置为每秒60次,即使每秒一次就足够了
FPS计数器代码:
function FpsCounter(){
this.count = 0;
this.fps = 0;
this.prevSecond;
this.minuteBuffer = new OverrideRingBuffer(60);
}
FpsCounter.prototype.update = function(){
if (!this.prevSecond) {
this.prevSecond = new Date().getTime();
this.count = 1;
}
else {
var currentTime = new Date().getTime();
var difference = currentTime - this.prevSecond;
if (difference > 1000) {
this.prevSecond = currentTime;
this.fps = this.count;
this.minuteBuffer.push(this.count);
this.count = 0;
}
else{
this.count++;
}
}
};
FpsCounter.prototype.getCountPerMinute = function(){
return this.minuteBuffer.getAverage();
};
FpsCounter.prototype.getCountPerSecond = function(){
return this.fps;
};
覆盖缓冲代码:
function OverrideRingBuffer(size){
this.size = size;
this.head = 0;
this.buffer = new Array();
};
OverrideRingBuffer.prototype.push = function(value){
if(this.head >= this.size) this.head -= this.size;
this.buffer[this.head] = value;
this.head++;
};
OverrideRingBuffer.prototype.getAverage = function(){
if(this.buffer.length === 0) return 0;
var sum = 0;
for(var i = 0; i < this.buffer.length; i++){
sum += this.buffer[i];
}
return (sum / this.buffer.length).toFixed(1);
};
函数重写缓冲区(大小){
这个。大小=大小;
这个头=0;
this.buffer=新数组();
};
overrideeringbuffer.prototype.push=函数(值){
如果(this.head>=this.size)this.head-=this.size;
this.buffer[this.head]=值;
这个.head++;
};
overrideeringbuffer.prototype.getAverage=函数(){
如果(this.buffer.length==0)返回0;
var总和=0;
for(var i=0;i
由于其他答案均未提及问题的“在WebGL中”部分,因此在正确测量WebGL中的FPS时,我将添加以下重要细节
window.console.time('custom-timer-id'); // start timer
/* webgl draw call here */ // e.g., gl.drawElements();
gl.finish(); // ensure the GPU is ready
window.console.timeEnd('custom-timer-id'); // end timer
为了简单起见,我使用了控制台计时器。我试图指出始终使用的要点,以确保测量正确的时间,因为所有对GPU的WebGL调用都是异步的 使用旋转阵列可以做得更好。
使用dom元素:
切勿将setInterval
用于动画。当选项卡被隐藏时,它将使用用户的机器。使用requestAnimationFrame
。看,谢谢这正是我需要的!不客气!再看看@gman的答案,然后requestAnimationFrame
,因为这是制作动画的更好方法代码>beelapsedTime=0代码>?在我做出更改之前,我无法实现这一点。请看一看,虽然您的大多数答案都很好,但有一点很重要:1除以帧时间(deltaTime
)不是计算每秒帧数的正确方法。你应该在一秒钟内计算渲染的帧数,就像在接受的答案中一样。如果一帧用了.9秒,59帧用了0.00169秒,你不会看到,如果你所做的只是看一秒钟内绘制的帧数,你当然会看到。帧时间为0.00169s时,应用程序以600 FPS的速度渲染。所以,如果一帧现在需要0.9秒,那么帧计数器将计数60帧,而不是600帧,所以您将看到10倍的差异。帧计数类似于您的averageFPS
,但变量更少,代码更简单
只是一个一厢情愿的想法,如果所有帧都能在那一时间渲染,我们可以拥有多少FPS。顺便说一句,WebGL基础知识太棒了!:)这行不通<代码>总帐。在WebGL中完成
不会按照您的想法执行。即使在OpenGL中,这也不会给出准确的结果