哪个 WebGL api 使统一值无效?
Which WebGL api's invalidate uniform values?
假设我们有以下代码:
gl.useProgram(p1);
gl.uniform1i(p1_u, 5);
gl.drawArrays(...);
gl.useProgram(p2);
g.uniform1i(p2_u, 100);
// on another loop of the application
// i will need to use p1 again
gl.useProgram(p1);
gl.uniform1i(p1_u, 5); // <<------- A
p1
& p2
是 WebGLProgram
s 和 p1_u
, p2_u
是 WebGLUniformLocation
s.
如果他们的值没有改变,可以跳过更新制服吗?
即使在切换 GLPrograms 之后?
或者换句话说:
哪个 WebGL api 使统一值无效,需要重新提交?
Which WebGL api's invalidate uniform values, and makes it necessary to re-submit them?
None:所有 WebGL 状态都与您设置的完全一样。除了 (deleteXXX)
之外,没有间接更改状态的 WebGL API
请注意,统一值是程序状态。换句话说,它们对于每个着色器程序都是唯一的。
示例:
const gl = document.querySelector('canvas').getContext('webgl');
const vsrc = `
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 40.0;
}
`;
const fsrc = `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}
`;
const vs = createAndCompileShader(gl, gl.VERTEX_SHADER, vsrc);
const fs = createAndCompileShader(gl, gl.FRAGMENT_SHADER, fsrc);
const redPrg = linkProgramAndSetColor(gl, vs, fs, [1, 0, 0, 1]);
const bluePrg = linkProgramAndSetColor(gl, vs, fs, [0, 0, 1, 1]);
function render(time) {
time *= 0.001; // convert to seconds;
gl.useProgram(redPrg);
gl.vertexAttrib2f(0, Math.cos(time), Math.sin(time));
gl.drawArrays(gl.POINTS, 0, 1);
gl.useProgram(bluePrg);
gl.vertexAttrib2f(0, Math.sin(time), Math.cos(time));
gl.drawArrays(gl.POINTS, 0, 1);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function createAndCompileShader(gl, type, src) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(s));
}
return s;
}
function linkProgramAndSetColor(gl, vs, fs, color) {
const p = gl.createProgram();
gl.attachShader(p, vs);
gl.attachShader(p, fs);
gl.bindAttribLocation(p, 0, 'position'); // force position to location 0
gl.linkProgram(p);
if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(p));
}
gl.useProgram(p);
gl.uniform4fv(gl.getUniformLocation(p, 'color'), color);
return p;
}
canvas { border: 1px solid black; }
<canvas></canvas>
假设我们有以下代码:
gl.useProgram(p1);
gl.uniform1i(p1_u, 5);
gl.drawArrays(...);
gl.useProgram(p2);
g.uniform1i(p2_u, 100);
// on another loop of the application
// i will need to use p1 again
gl.useProgram(p1);
gl.uniform1i(p1_u, 5); // <<------- A
p1
& p2
是 WebGLProgram
s 和 p1_u
, p2_u
是 WebGLUniformLocation
s.
如果他们的值没有改变,可以跳过更新制服吗?
即使在切换 GLPrograms 之后?
或者换句话说:
哪个 WebGL api 使统一值无效,需要重新提交?
Which WebGL api's invalidate uniform values, and makes it necessary to re-submit them?
None:所有 WebGL 状态都与您设置的完全一样。除了 (deleteXXX)
之外,没有间接更改状态的 WebGL API请注意,统一值是程序状态。换句话说,它们对于每个着色器程序都是唯一的。
示例:
const gl = document.querySelector('canvas').getContext('webgl');
const vsrc = `
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 40.0;
}
`;
const fsrc = `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}
`;
const vs = createAndCompileShader(gl, gl.VERTEX_SHADER, vsrc);
const fs = createAndCompileShader(gl, gl.FRAGMENT_SHADER, fsrc);
const redPrg = linkProgramAndSetColor(gl, vs, fs, [1, 0, 0, 1]);
const bluePrg = linkProgramAndSetColor(gl, vs, fs, [0, 0, 1, 1]);
function render(time) {
time *= 0.001; // convert to seconds;
gl.useProgram(redPrg);
gl.vertexAttrib2f(0, Math.cos(time), Math.sin(time));
gl.drawArrays(gl.POINTS, 0, 1);
gl.useProgram(bluePrg);
gl.vertexAttrib2f(0, Math.sin(time), Math.cos(time));
gl.drawArrays(gl.POINTS, 0, 1);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function createAndCompileShader(gl, type, src) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(s));
}
return s;
}
function linkProgramAndSetColor(gl, vs, fs, color) {
const p = gl.createProgram();
gl.attachShader(p, vs);
gl.attachShader(p, fs);
gl.bindAttribLocation(p, 0, 'position'); // force position to location 0
gl.linkProgram(p);
if (!gl.getProgramParameter(p, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(p));
}
gl.useProgram(p);
gl.uniform4fv(gl.getUniformLocation(p, 'color'), color);
return p;
}
canvas { border: 1px solid black; }
<canvas></canvas>