Ответ 1
Что-то вроде этого:
function animate() {
setTimeout( function() {
requestAnimationFrame( animate );
}, 1000 / 30 );
renderer.render();
}
Я думал, что для некоторых проектов я делаю 60 кадров в секунду, это не совсем необходимо. Я решил, что у меня может быть больше объектов и вещей, которые работают со скоростью 30 кадров в секунду, если я смогу заставить его работать плавно при такой частоте кадров. Я решил, что отредактировал прошивку requestAnimationFrame внутри three.js. Я мог бы ограничить ее до 30. Но мне было интересно, есть ли лучший способ сделать это с помощью самого тр .js, как это предусмотрено. Кроме того, это даст мне такое увеличение производительности, о котором я думаю. Смогу ли я сделать вдвое больше объектов со скоростью 30 кадров в секунду, как я буду в 60? Я знаю разницу между запущенными вещами в 30 и 60, но смогу ли я заставить его работать с плавной постоянной 30 кадров в секунду?
Обычно я использую WebGLRenderer и возвращаюсь в Canvas, если это необходимо, за исключением проектов, которые специально нацелены на них, и обычно это проекты webgl shader.
Что-то вроде этого:
function animate() {
setTimeout( function() {
requestAnimationFrame( animate );
}, 1000 / 30 );
renderer.render();
}
Объем работы вашего процессора и графического процессора зависит от рабочей нагрузки и устанавливает верхний предел плавной частоты кадров.
GPU работает в основном линейно и всегда может вытолкнуть одинаковое количество полигонов на экран.
Однако, если вы удвоили количество объектов, то ЦП должен усердно работать, чтобы оживить эти все объекты (преобразования матрицы и т.д.). Это зависит от вашей модели мира и другой работы. Javascript делает сколько дополнительных накладных расходов. Также важны такие условия, как количество видимых объектов.
Для простых моделей, где все полигоны находятся на экране всегда, это должно в значительной степени следовать правилу "половина частоты кадров, удвоить объекты". Для 3D-шутеров, подобных сценам, это определенно не так.
Я столкнулся с этой статьей, которая дает два способа решения проблемы пользовательской частоты кадров.
http://codetheory.in/controlling-the-frame-rate-with-requestanimationframe/
Я думаю, что этот способ более надежный, поскольку он будет иметь устойчивую скорость анимации даже на компьютерах, которые не отображают холст последовательно со скоростью 60 кадров в секунду. Ниже приведен пример
var now,delta,then = Date.now();
var interval = 1000/30;
function animate() {
requestAnimationFrame (animate);
now = Date.now();
delta = now - then;
//update time dependent animations here at 30 fps
if (delta > interval) {
sphereMesh.quaternion.multiplyQuaternions(autoRotationQuaternion, sphereMesh.quaternion);
then = now - (delta % interval);
}
render();
}
Этот подход также может работать, используя THREE.Clock для измерения дельты.
let clock = new THREE.Clock();
let delta = 0;
// 30 fps
let interval = 1 / 30;
function update() {
requestAnimationFrame(update);
delta += clock.getDelta();
if (delta > interval) {
// The draw or time dependent code are here
render();
delta = delta % interval;
}
}
Популярный ответ имеет проблему и выдает -10fps на медленных компьютерах по сравнению с не ограничением fps, например, без ограничения 36pfs, с принятым решением 26fps.
Вместо этого вы можете сделать это:
var dt=1000/60;
var timeTarget=0;
function render(){
if(Date.now()>=timeTarget){
gameLogic();
renderer.render();
timeTarget+=dt;
if(Date.now()>=timeTarget){
timeTarget=Date.now();
}
}
requestAnimationFrame(render);
}
Этот путь не будет ждать, если он уже позади.