getAttribLocation return 总是相同的索引

getAttribLocation return always the same index

  attribute vec2 test; 
  attribute vec2 position;

  void main() {
    vTexCoord = position ; 
    vec2 gg = test;
    .....
  }

getAttribLocation 的作用是什么? 以前一直以为是代码中属性的索引, 但不,它总是 return 位置为 0,测试为 1

?

getAttribLocation 获取属性的位置。仅仅因为 GPU/driver returns 0 position1 test 并不意味着所有 driver 都会。

此外,在调试时通常会注释掉着色器的某些部分。如果不使用某个属性,driver 可能会将其优化掉。在您的情况下,如果您要注释掉使用 position 的任何行,则可能 test 会获得位置 0。如果您没有查找位置并且您假设 test 始终位于位置 1,您的代码将失败

另一方面,您可以通过调用 bindAttribLocation 在调用 linkProgram 之前设置位置 。例如

gl.bindAttribLocation(program, 10, "position");
gl.bindAttribLocation(program, 5, "test");
gl.linkProgram(program);

在这种情况下,您不必查找位置。

var vs = `
  attribute float position;
  attribute float test;
  
  void main() {
    gl_Position = vec4(position, test, 0, 1);
  }
`;
var fs = `
  void main() {
    gl_FragColor = vec4(0, 1, 0, 1);
  }
`;

function createShader(gl, type, source) {
  var s = gl.createShader(type);
  gl.shaderSource(s, source);
  gl.compileShader(s);
  if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
    console.log(gl.getShaderInfoLog(s));
  }
  return s; 
}

var gl = document.createElement("canvas").getContext("webgl");
var prg = gl.createProgram();
gl.attachShader(prg, createShader(gl, gl.VERTEX_SHADER, vs));
gl.attachShader(prg, createShader(gl, gl.FRAGMENT_SHADER, fs));
gl.bindAttribLocation(prg, 5, "position");
gl.bindAttribLocation(prg, 10, "test");
gl.linkProgram(prg);
if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
  console.log(gl.getProgramInfoLog(prg));
}
console.log("test location:", gl.getAttribLocation(prg, "test"));
console.log("position location:", gl.getAttribLocation(prg, "position"));