如何避免 webGL 着色器加载对 cpu 施加过多负载
how to avoid webGL shader loading putting too much load on cpu
加载多个大型着色器程序时,webGl 会对 cpu 施加很大压力,使 UI 停滞,有时甚至会触发 chrome 的 cpu 杀死页面的看门狗。
我该怎么做才能在这种情况下显示 "loading" 屏幕并限制我的处理器使用率,以免被 chrome 抓到?
relevant section of code, which ultimately leads to 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.
加载多个大型着色器程序时,webGl 会对 cpu 施加很大压力,使 UI 停滞,有时甚至会触发 chrome 的 cpu 杀死页面的看门狗。
我该怎么做才能在这种情况下显示 "loading" 屏幕并限制我的处理器使用率,以免被 chrome 抓到?
relevant section of code, which ultimately leads to 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.