Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用three.js将FPS保持在一定范围内_Javascript_Performance_Three.js - Fatal编程技术网

Javascript 使用three.js将FPS保持在一定范围内

Javascript 使用three.js将FPS保持在一定范围内,javascript,performance,three.js,Javascript,Performance,Three.js,使用antialas=true创建的WebGLRenderer实例会随着分辨率的提高而导致明显的性能问题,尤其是在视网膜显示器上(window.devicePixelRatio==2) 由于不可能动态更改抗锯齿模式,问题是:如何自动调整像素比率以保持FPS高于某个阈值(例如30)?想法是在渲染循环中监视FPS(通过测量requestAnimationFrame调用之间的间隔)相应地降低或增加DPR “监控”是指将这些间隔记录到一个数组中,删除最小/最大值(以避免峰值),取平均值并将其与预定义阈值

使用
antialas=true
创建的
WebGLRenderer
实例会随着分辨率的提高而导致明显的性能问题,尤其是在视网膜显示器上(
window.devicePixelRatio==2


由于不可能动态更改抗锯齿模式,问题是:如何自动调整像素比率以保持FPS高于某个阈值(例如30)?

想法是在渲染循环中监视FPS(通过测量
requestAnimationFrame
调用之间的间隔)相应地降低或增加DPR

“监控”是指将这些间隔记录到一个数组中,删除最小/最大值(以避免峰值),取平均值并将其与预定义阈值进行比较

const高频阈值=20;//~每秒50帧
常数低频阈值=34;//~每秒30帧
常数minDpr=0.5;
const maxDpr=window.devicePixelRatio;
常数deltaDpr=0.1;
const relexperiod=4000;
常数累加器长度=20;
const frameTimestamp=performance.now();
常数频率累加器=[];
const lastUpdatedAt=null;
const renderer=新的WebGLRenderer({
反别名:是的,
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
document.body.appendChild(renderer.doElement);
制作动画();
函数animate(timestamp:number=performance.now()){
请求动画帧(动画);
监视器(帧时间戳、时间戳);
frameTimestamp=时间戳;
//动画计算和渲染
// ...
}
函数监视器(帧时间戳:编号,现在:编号){
收集频率(现在为帧时间戳);
//蓄能器未完全充满
if(频率累加器长度<累加器长度){
返回;
}
//最近发生了一个更新
if(现在-lastUpdatedAt低频阈值(&dpr>minDpr){
更新的PR(dpr,-deltaDpr,现在);
}否则如果(frequencyMedian0){
频率累加器。推送(频率);
}
if(频率累加器长度>累加器长度){
frequencyc累加器.shift();
}
}
函数updateDpr(dpr:number,delta:number,now:number){
渲染器.setPixelRatio(dpr+delta);
频率累加器=[];
lastUpdatedAt=现在;
}
函数中值(…元素:编号[]):编号{
常量indexOfMin=elements.indexOf(Math.min(…elements));
常量indexOfMax=elements.indexOf(Math.max(…elements));
const noMinMax=elements.filter((u,index)=>index!==indexOfMin&&index!==indexOfMax);
返回平均值(…noMinMax);
}
函数平均值(…元素:编号[]):编号{
返回元素.reduce((sum,value)=>sum+value,0)/elements.length;
}
请注意,更新DPR可能会导致短期动画冻结

此外,还可以使用更聪明的方法来平衡DPR值(而不是使用
0.1
的线性步长调用
updateDpr()
),例如二分搜索