2011-10-06 30 views
9

Làm thế nào để giải quyết FPS khác nhau trong requestAnimationFrame trên các trình duyệt khác nhau?
Tôi đang tạo trò chơi 3D bằng cách sử dụng THREE.js sử dụng requestAnimationFrame và nhanh chóng trên Google Chrome 15.
Tuy nhiên, nó thực sự chậm trên Firefox 6 và thực sự thực sự chậm (chậm hơn Firefox) trên IE9.
Đây thực sự là một sự cố lớn và tôi tự hỏi nếu có giải pháp cho điều đó.Làm thế nào để giải quyết FPS khác nhau trong requestAnimationFrame trên các trình duyệt khác nhau?

Cảm ơn.

+1

Cách để giải quyết điều này là làm cho bất kỳ mã nào bạn đang chạy từ cuộc gọi lại chạy nhanh. Làm thế nào để làm điều đó là không thể nói mà không nhìn thấy mã số ... –

Trả lời

5

Theo như tôi biết không có cách nào để thực sự khắc phục điều này, khác hơn là làm cho mã của bạn ít tài nguyên hơn.

Chrome có vẻ là trình duyệt nhanh nhất, nhưng thường FF không xa phía sau, nhưng IE vẫn chậm. Tùy thuộc vào phương thức hiển thị, canvas, svg hoặc webGL, nó cũng phụ thuộc rất nhiều vào phần cứng cục bộ của bạn vì nó sử dụng client cho hầu hết mọi thứ và kết xuất webGL phức tạp cần GPU mạnh để đạt được khung hình tốt.

Có nhiều cách để đo tốc độ khung hình khi đang di chuyển và thay đổi hoạt ảnh của bạn cho phù hợp.
Đây là một ví dụ rất đơn giản để đo tốc độ khung hình.

function step(timestamp) { 
 
    var time2 = new Date; 
 
    var fps = 1000/(time2 - time); 
 
    time = time2; 
 
\t 
 
    document.getElementById('test').innerHTML = fps; 
 
    window.requestAnimationFrame(step); 
 
} 
 

 
var time = new Date(), i = 0; 
 
window.requestAnimationFrame(step);
<div id="test"></div>

Đây chỉ là một biện pháp ngay lập tức mà không phải là chính xác, bạn có thể muốn một cái gì đó mà các biện pháp trên một thời gian để có được một khung hình chính xác hơn cho trình duyệt được sử dụng.

Cũng lưu ý đối số timestamp, trong đó requestAnimationFrame là dấu thời gian có độ chính xác tối thiểu 1 mili giây, cũng có thể được sử dụng để xác định tốc độ của hoạt ảnh và bất kỳ độ trễ trình duyệt nào.

+2

IE9 + thực sự là khá nhanh. Đôi khi nhanh hơn FF, theo kinh nghiệm của tôi. – kangax

14

Điều phổ biến cần làm là tạo biến deltaTime (dt) sau đó được sử dụng làm tham số cho mỗi chu kỳ hoạt ảnh/cập nhật.

Mã chỉ để hiển thị vấn đề/giải pháp.

// ... 
timer: function(){ 
    var now = new Date().getTime(); // get current time 
    this.controls.dt = now - this.controls.time; // calculate time since last call 
    this.controls.time = now; // update the current application time 
    this.controls.frame++; // also we have a new frame 
    return this.controls.dt ; 
} 

cho bất kỳ cuộc gọi đến chức năng làm cho sau đó bạn vượt qua dt

// we call the update function with every request frame 
update: function(){ 
    var dt = this.timer(); 
    _.each(this.activeViews, function(item){ item.update(dt); }); // this is underscore.js syntax 
} 

item.update (dt) trông như thế

//... 
var x = this.position.get(x); 
x = x + (10*dt); // meaning: x increases 10 units every ms. 
this.position.x = x; 
2

Trên một số trình duyệt requestAnimationFrame hoạt động như thế

setTimeout(callback, 1000/(16 + N)

trong đó N là thời gian cần thiết để mã của bạn thực thi. Có nghĩa là nó mũ FPS của bạn tại 62Hz nhưng nếu mã của bạn hoạt động chậm, nó sẽ nắp ở một cái gì đó cách thấp hơn. Về cơ bản nó cố gắng tạo ra khoảng cách 16ms giữa mọi khoảng trống. Tất nhiên, điều này là không đúng đối với tất cả các trình duyệt và có thể sẽ thay đổi trong tương lai dù sao nhưng nó vẫn có thể cung cấp cho bạn một ý tưởng về cách hoạt động của nó.

Thậm chí nếu nó được thực hiện giống nhau trong mọi trình duyệt, có nhiều yếu tố ảnh hưởng đến hiệu suất mã của bạn và v.v. Bạn không bao giờ có thể chắc chắn mã của mình sẽ chạy ở tần số không đổi.

3

Khuôn khổ Crafty thực hiện điều gì đó hơi khác một chút, nhưng có thể hoạt động đối với một số trường hợp - số lần đánh dấu trò chơi trên mỗi trận hòa không phải là không đổi. Thay vào đó, nó sẽ nhận thấy khi tốc độ khung hình giảm xuống sau một số mục tiêu lý tưởng và sẽ quay vòng qua nhiều lần đánh dấu trò chơi trước khi thực hiện bước vẽ. Bạn có thể xem số step function trên github.

Tính năng này hoạt động tốt miễn là trò chơi sẽ chạy trơn tru. Nhưng nếu bạn cố gắng xử lý nhiều thứ hơn, nó có thể có xu hướng làm trầm trọng thêm tình hình, vì nó sẽ ưu tiên logic trò chơi trên hoạt ảnh.

Trong mọi trường hợp, nó sẽ chỉ hoạt động nếu logic trò chơi và logic hiển thị được tách riêng. (Nếu họ là hoàn toàn được tách riêng, bạn có thể đặt chúng trong các vòng hoàn toàn riêng biệt.)

Các vấn đề liên quan