首页 > 解决方案 > WebGL 检查哪个纹理单元绑定到制服

问题描述

是否可以使用javascript检查哪个纹理单元绑定到制服?例如(伪代码!):

let samplerRef = gl.getUniformLocation(program, 'textureSampler'); 
gl.uniform1i(samplerRef, 0);
console.log(samplerRef.textureUnit);  // texture unit 0

我正在尝试调试一些代码,这将帮助我确保我的纹理单元连接到正确的采样器。但是我在网上找不到任何可以让我这样做的代码。

标签: webgl

解决方案


您可以通过调用 ` 获取制服的当前值

const currentValue = gl.getUniform(program, uniformLocation);

您还可以通过调用获取绑定到当前活动纹理单元的纹理对象

const texture2D = gl.getParameter(gl.TEXTURE_BINDING_2D);
const textureCubeMap = gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP);

因此,如果您想获取纹理对象,如果您调用 gl.drawXXX,则某些 uinform 会使用您可能会执行类似的操作

const unit = gl.getUniform(program, samplerUniformLocation);
gl.activeTexture(gl.TEXTURE0 + unit);
const texture2D = gl.getParameter(gl.TEXTURE_BINDING_2D);

例子

const gl = document.createElement('canvas').getContext('webgl');

const vs = `
uniform int abc;
uniform vec3 def;
void main() {
  gl_Position = vec4(def, abc);
}
`;

const fs = `
precision highp float;
uniform sampler2D tex;
void main() {
  gl_FragColor = texture2D(tex, vec2(0));
}
`;

const program = twgl.createProgram(gl, [vs, fs]);

gl.useProgram(program);
gl.uniform1i(gl.getUniformLocation(program, 'abc'), 123);
gl.uniform3fv(gl.getUniformLocation(program, 'def'), [4, 5, 6]);
gl.uniform1i(gl.getUniformLocation(program, 'tex'), 7);

gl.activeTexture(gl.TEXTURE0 + 7);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);

log('----texture units-----');

// get all the currently bound textures
const numTextureUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
for (let unit = 0; unit < numTextureUnits; ++unit) {
  gl.activeTexture(gl.TEXTURE0 + unit);
  log(unit, '2D', gl.getParameter(gl.TEXTURE_BINDING_2D) || 'null', 'CUBE_MAP', gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP) || 'null');
}

log('----uniforms-----');

// get all the uniforms values
const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (let i = 0; i < numUniforms; ++i) {
  const uniformInfo = gl.getActiveUniform(program, i);
  const location = gl.getUniformLocation(program, uniformInfo.name);
  const value = gl.getUniform(program, location);
  log(uniformInfo.name, glEnumToString(gl, uniformInfo.type), value, value === tex ? 'this is tex' : '');
}

function glEnumToString(gl, v) {
  for (let k in gl) {
    if (gl[k] === v) {
      return k;
    }
  }
  return v;
}


function log(...args) {
  const elem = document.createElement('pre');
  elem.textContent = [...args].join(' ');
  document.body.appendChild(elem);
}
pre { margin: 0; }
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>


推荐阅读