当前位置:网站首页>window.requestAnimationFrame Web3D渲染帧率控制
window.requestAnimationFrame Web3D渲染帧率控制
2022-08-07 08:43:00 【Mr_Bobcp】
注意: window.requestAnimationFrame控制Web3D渲染帧率一般不会超过运行环境所能提供的最高帧率的,假设电脑屏幕是165Hz的,能达到的最高帧就是165帧。
window.requestAnimationFrame简介
定义
window.requestAnimationFrame()告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
语法
window.requestAnimationFrame(callback);
参数
callback:下一次重绘之前更新动画帧所调用的函数 (即上面所说的回调函数)。该回调函数会被传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻。
返回值
一个 long 整数,请求 ID ,是回调列表中唯一的标识。是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
使用注意
准备更新动画时调用此方法,这将使浏览器在下一次重绘之前调用你传入给该方法的动画函数 (即你的回调函数);
回调函数执行次数通常是每秒 60 次,但在大多数遵循 W3C 建议的浏览器中,回调函数执行次数通常与 浏览器屏幕刷新次数 相匹配;
为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame() 运行在 后台标签页 或者隐藏的 iframe标签 里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命;
回调函数会被传入DOMHighResTimeStamp参数,DOMHighResTimeStamp指示当前被 requestAnimationFrame() 排序的回调函数被触发的时间,在帧率控制中用这里传入的时间来计算时间差个人认为比较准备。在同一个帧中的多个回调函数,它们每一个都会接受到一个相同的时间戳,即使在计算上一个回调函数的工作负载期间已经消耗了一些时间。该时间戳是一个十进制数,单位毫秒,最小精度为 1ms(1000μs)。
两种方式控制帧率
定义两个描述:“标准帧”:不干涉默认requestAnimationFrame回调次数时的帧集合;“预计帧”:期望控制的帧集合;
方法一:默认帧数中取适当次数更新
不修改标准帧,只判断最近一次标准帧和上一次预期帧记录时间对比,看是否大于等于预计帧的间隔,大于则让希望被控制渲染的内容更新。如图中使用方法一预计在节点①更新的内容,实际是在标准帧中到第②节点才会去更新的。
方法二:用延时控制帧率更新的频率
修改标准帧,用setTimeout延时调用requestAnimationFrame,在方法二中让标准帧本该在①渲染的直接延时到方法二的①节点更新,达到帧数控制的效果。
以下代码是基于《Three.js学习七——播放模型动画时模型沿着轨迹移动》中代码修改的,引入了stats性能插件监控一下帧率和一些辅助变量,修改了部分animate方法内容。
import Stats from "./three.js-master/examples/jsm/libs/stats.module.js";
let stats = null;
function initStats() {
stats = new Stats(); // 引入stats性能插件监控一下帧率
stats.domElement.style.position = "absolute";
stats.domElement.style.left = "0px";
stats.domElement.style.up = "0px";
document.body.appendChild(stats.domElement);
};
let timeS = 0;
let t = 0;
const FPS = 60;
const renderT = (1 / FPS) * 1000; //单位秒 间隔多长时间渲染渲染一次
默认帧数中取适当次数更新
/* 方法一animate */
function animate(time) {
if (time !== undefined) {
t = time - timeS; // 计算时间间隔
}
if (t >= renderT) {
stats.update(); // 更新stats
// 更新动画帧
if (mixer) {
mixer.update(clock.getDelta());
}
moveOnCurve();
timeS = time; // 更新时间
}
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
效果:
用延时控制帧率更新的频率
/* 方法二animate */
function animate(time) {
if (time !== undefined) {
t = renderT - (time - timeS) % renderT;
}
stats.update();
// 更新动画帧
if (mixer) {
mixer.update(clock.getDelta());
}
moveOnCurve();
timeS = time; // 更新时间
renderer.render(scene, camera);
// 延时回调
setTimeout(() => {
requestAnimationFrame(animate);
}, t)
};
效果:
总结
| 方法 | 要点 | 优缺点 |
|---|---|---|
| 方法一 | 判断帧间的时间间隔,默认帧数中取适当次数更新 | 正常运行时帧数非常稳定,一般键鼠操作不会有明显影响 |
| 方法二 | 计算预计帧间时间延时,用延时控制帧率更新的频率 | 由于控制了整个标准帧刷新正常运行时帧数可能因为键鼠操作导致帧率上下浮动较方法一明显 |
边栏推荐
- Sort--selection sort
- rest client: a lightweight vscode plugin for api requests
- 6.PHP函数、$GET和$POST变量
- redis基础常识、数据类型及基本命令
- 你如何看待抖音的中视频伙伴计划的?
- 30.01 C/S and TCP/IP protocols are interesting and vivid
- Web3 Reference Architecture
- Backpack Theory 01 Backpack
- 【正点原子STM32连载】第六章 新建寄存器版本MDK工程 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
- Sort -- bubble sort
猜你喜欢

redis的原理和源码-redis的六种数据类型基本介绍:string、hash、list、set、zset、stream

帕累托分析中的累计优化

【正点原子STM32连载】第六章 新建寄存器版本MDK工程 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

力拓信创生态,博睿数据多款产品获得东方通与达梦数据库产品兼容互认证明
![[Promise] Promise use / callback hell problem async-await / macro queue and micro queue](/img/59/8ebdd70122b7e3c094f971454a5336.png)
[Promise] Promise use / callback hell problem async-await / macro queue and micro queue

jenkins配置自动打包

redis的原理和源码-sentinel哨兵的原理和源码解析(上)

The baud rate of STM32 is wrong. The baud rate we want to set is 9600, but the actual baud rate is 14400. Why is this?

30.01 C/S、TCP/IP协议妙趣横生、惟妙惟肖谈

30.01 C/S and TCP/IP protocols are interesting and vivid
随机推荐
【LeetCode】Day110- Divide the letter interval
Sort--selection sort
Error f "pip[sys.version_info.major)" is reported after pip3 upgrade
插入排序(直接、二分)
rest client: 一款轻量级用于api请求的vscode插件
《C陷阱与缺陷》之“语义”陷阱——数组越界导致的程序死循环问题
帕累托分析中的累计优化
6.PHP函数、$GET和$POST变量
Heavy Live | ORB-SLAM3 Series Code Explanation: Key Frames Topic 1
Click: 1049. Weight of the last stone II
[Promise] Promise use / callback hell problem async-await / macro queue and micro queue
redis的原理和源码-集群的原理和源码解析(上)
The PG function generates the corresponding table creation statement according to the table name
Routing, network, Internet, Internet, public network private network IP, NAT technology
redis的原理和源码-redis的内存淘汰策略&LRU源码解析&LFU源码解析
选择排序(简单选择排序和堆排序)
The use of modules in ansible
The number of [NOIP2001 improve group] division
二分查找(搜索区间为左闭右开)
大屏显示之动态词云组件