[英]Using javascript to detect device CPU/GPU performance?
(這個問題不是針對 three.js 的,但我會以它為例)
我最近一直在使用 three.js 開發 web 應用程序界面,並在 WebGL 和 Canvas 渲染器(用於桌面瀏覽器)之間編寫了一些不錯的后備。
但是現在問題變成了如何正確檢測設備能力,問題有兩個方面:
一個值得注意的例子:Firefox 移動/Opera 移動聲稱支持 WebGL,但存在錯誤或受設備硬件限制。
到目前為止,我提出了一些解決方法:
或者也許它不必這么難,還有其他建議嗎?
我最終在一個項目中使用了性能測量方法,我們希望利用高規格CPU / GPU桌面上的畫布功能,以及桌面和手機等低速設備。
基本上我們從最小的場景復雜度開始,如果renderloop花費不到33ms,我們就增加了復雜性(如果renderloop以后開始花費太長時間,我們也會降低復雜性)。
我想在您的情況下,您可能需要運行快速畫布和webgl性能測試,然后選擇一個。 花了一些時間研究這個我沒有遇到一些棘手的非顯而易見的技術,可以更好地解決這個問題。
您可以使用http://webglstats.com/進行WebGL硬件支持和功能檢測。
如果您使用three.js,您可以使用detector.js來查明是否啟用了webgl。 也遠離canvasrenderer將有所幫助。 使用webglrenderer或softwarerender。 因為它們允許更多頂點。 softwarerender相當新,需要一些工作但可以使用。
這是我使用 three.js 寫給基准 webgl 的代碼片段:
import {
Mesh,
MeshStandardMaterial,
PerspectiveCamera,
Scene,
SphereGeometry,
WebGLRenderer,
} from "three";
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export enum GPUPerformanceLevel {
HIGH = "HIGH",
LOW = "LOW",
}
/**
* Three.js based webgl benchmark
*
* In summary, the `run` method adds `meshPerStep` new spheres every step (frame)
* and measures the fps. If we're able to perform >=`thresholds.steps` of these
* steps, without the fps dropping below `thresholds.fps`, then we label the device
* `GPUPerformanceLevel.HIGH`.
*/
export class GPUBenchmark {
scene = new Scene();
material = new MeshStandardMaterial();
geometry = new SphereGeometry();
static thresholds = { fps: 10, steps: 40 };
static meshPerStep = 1000;
async run(debug = false): Promise<GPUPerformanceLevel> {
const camera = new PerspectiveCamera(75);
const renderer = new WebGLRenderer();
let tPrev = performance.now() / 1000;
let steps = 0;
let passedThreshold = false;
const animate = async () => {
const time = performance.now() / 1000;
const fps = 1 / (time - tPrev);
tPrev = time;
if (debug) {
console.log(`fps: ${fps} steps: ${steps}`);
}
if (
fps > GPUBenchmark.thresholds.fps &&
steps < GPUBenchmark.thresholds.steps
) {
requestAnimationFrame(animate);
this.step();
steps++;
renderer.render(this.scene, camera);
} else {
passedThreshold = true;
}
};
animate();
while (!passedThreshold) {
await sleep(1);
}
this.cleanup();
const level = GPUBenchmark.stepsToPerfLevel(steps);
if (debug) {
console.log("device benchmarked at level:", level);
}
return level;
}
private step() {
for (let i = 0; i < GPUBenchmark.meshPerStep; i++) {
const sphere = new Mesh(this.geometry, this.material);
sphere.frustumCulled = false;
this.scene.add(sphere);
}
}
private cleanup() {
for (const obj of this.scene.children) {
this.scene.remove(obj);
}
//@ts-ignore
this.scene = null;
this.material.dispose();
this.geometry.dispose();
//@ts-ignore
this.material = null;
//@ts-ignore
this.geometry = null;
}
private static stepsToPerfLevel(numSteps: number): GPUPerformanceLevel {
if (numSteps >= GPUBenchmark.thresholds.steps) {
return GPUPerformanceLevel.HIGH;
} else {
return GPUPerformanceLevel.LOW;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.