当加载几个庞大的着色器程序时,webGl 会给 cpu 带来很大的压力,使 UI 停滞,有时甚至会触发 chrome 的 cpu watchdog,从而杀死页面。
我该怎么做才能在这种情况下显示“正在加载”屏幕并限制我的处理器使用率,以免我被 chrome 盯上?
relevant section of code ,最终导致 these actual webGL calls :
var p = this.program = gl.createProgram();
gl.attachShader(p, this.makeShader(gl.VERTEX_SHADER, vertex));
gl.attachShader(p, this.makeShader(gl.FRAGMENT_SHADER, fragment));
gl.linkProgram(p);
最佳答案
几个想法
您可以尝试等待几帧以检查结果
var vs = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vs, vSource); gl.compileShader(vs); var fs = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fs, vSource); gl.compileShader(fs); var p = gl.createProgram(); gl.attachShader(p, vs); gl.attachshader(p, fs); gl.linkProgram(p); gl.flush(); // Important! setTimeout(checkResults, 2000); // check results 2 seconds later function checkResults() { var status = gl.getProgramParameter(p, gl.LINK_STATUS); ... }
至少在 Chrome 中,这可能意味着 GPU 进程将编译程序,而渲染进程(运行 JavaScript 的进程)将继续运行,因此至少 JavaScript 不会阻塞,除非它在您运行时尚未完成检查结果。
将事情分解成多个步骤
var tasks = []; addTask(compileVertexShader); addTask(compileFragmentShader); addTask(linkProgram); addTask(render); function addTask(fn) { tasks.push(fn); runNextTask(); } var taskRunning = false; function runNextTask() { if (taskRunning) { return; } var taskFn = tasks.shift(); if (taskFn) { taskRunning = true; setTimeout(function() { taskRunning = false; taskFn(); runNextTask(); }, 1); } } function compileVertexShader() { ... } function compileFragmentShader() { ... } function linkProgram() { ... } function render() { ... }
只要一个功能不会花费太长时间,就不会有任何问题。
有一些通用库可以帮助处理此类问题。例如the async library .
关于javascript - 如何避免 webGL 着色器加载对 cpu 施加过多负载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29184370/