在 OpenGL 中加载统一变量是否昂贵?
Is loading uniform variables in OpenGL expensive?
通常我会在绘制网格之前加载所有统一变量(无论是否需要)。例如(在 WebGL 中):
gl.uniformMatrix4fv(program.ModelView, false, ModelView.array);
var MVP = Projection.mult(ModelView);
gl.uniformMatrix4fv(program.ModelViewProjection, false, MVP.array);
var NormalMatrix = ModelView.normal();
gl.uniformMatrix3fv(program.NormalMatrix, false, NormalMatrix);
gl.uniform3fv(program.materalDiffuse, materialDiffuse);
gl.uniform3fv(program.materalAmbient, [1.0, 1.0, 1.0]);
// ...etc...
// ... draw mesh via gl.drawArrays or gl.drawElements
其中一些制服自上次调用 gl.draw(Arrays|Elements)
以来可能没有改变,因此加载它们通常是多余的。我应该担心这个开销吗?
我可以向客户端变量添加一个 dirty
位,并且只加载需要更改的统一变量;例如:
if (ModelView.dirty || Projection.dirty) {
gl.uniformMatrix4fv(program.ModelView, false, ModelView.array);
var MVP = Projection.mult(ModelView);
gl.uniformMatrix4fv(program.ModelViewProjection, false, MVP.array);
ModelView.dirty = Projection.dirty = false;
}
然后,每当 ModelView
或 Projection
发生突变时,我都会设置相应的 dirty
位。
尝试限制统一变量加载是否值得?
根据我的经验,与 openGL 相比,webGL 中的统一更新有明显的开销。话虽如此,您仍然可以期望每秒能够进行数千次这些统一更新,并且仍能达到 60 FPS。
实际上,我认为对于大多数应用程序,如果您使用统一作为模型实例化的手段,统一更新只会成为一个问题。那么您可能 运行 由于统一更新开销和所需绘制调用次数的组合而遇到问题。
否则,我不会太担心缓存制服。这样做当然不是一个坏主意,只是不要指望它会成为让你从 30 FPS 升到 60 FPS 的灵丹妙药。
通常我会在绘制网格之前加载所有统一变量(无论是否需要)。例如(在 WebGL 中):
gl.uniformMatrix4fv(program.ModelView, false, ModelView.array);
var MVP = Projection.mult(ModelView);
gl.uniformMatrix4fv(program.ModelViewProjection, false, MVP.array);
var NormalMatrix = ModelView.normal();
gl.uniformMatrix3fv(program.NormalMatrix, false, NormalMatrix);
gl.uniform3fv(program.materalDiffuse, materialDiffuse);
gl.uniform3fv(program.materalAmbient, [1.0, 1.0, 1.0]);
// ...etc...
// ... draw mesh via gl.drawArrays or gl.drawElements
其中一些制服自上次调用 gl.draw(Arrays|Elements)
以来可能没有改变,因此加载它们通常是多余的。我应该担心这个开销吗?
我可以向客户端变量添加一个 dirty
位,并且只加载需要更改的统一变量;例如:
if (ModelView.dirty || Projection.dirty) {
gl.uniformMatrix4fv(program.ModelView, false, ModelView.array);
var MVP = Projection.mult(ModelView);
gl.uniformMatrix4fv(program.ModelViewProjection, false, MVP.array);
ModelView.dirty = Projection.dirty = false;
}
然后,每当 ModelView
或 Projection
发生突变时,我都会设置相应的 dirty
位。
尝试限制统一变量加载是否值得?
根据我的经验,与 openGL 相比,webGL 中的统一更新有明显的开销。话虽如此,您仍然可以期望每秒能够进行数千次这些统一更新,并且仍能达到 60 FPS。
实际上,我认为对于大多数应用程序,如果您使用统一作为模型实例化的手段,统一更新只会成为一个问题。那么您可能 运行 由于统一更新开销和所需绘制调用次数的组合而遇到问题。
否则,我不会太担心缓存制服。这样做当然不是一个坏主意,只是不要指望它会成为让你从 30 FPS 升到 60 FPS 的灵丹妙药。