如何处理纹理参数?

How are texture parameters handled?

在 HTML5 我正在处理将纹理加载到 WebGL 上下文的页面。但是,这个问题可能适用于任何 OpenGL (ES) 版本。

纹理上传到GPU后(通过glBindTextureglTexImage2D),可以调用glTexParameteriglTexParameterf函数。这些函数应该为纹理设置参数。

但是,我不清楚这些参数实际上是针对什么对象设置的。它们是否设置为在当前活动纹理槽中启用的实际纹理?它们是为当前活动的纹理槽本身设置的吗?或者它们是为所有纹理全局设置的?

由此引出的另一个疑点是: 我可以在多个纹理插槽中启用相同的纹理(在 GPU 上只加载一次),但参数不同吗?

根据OpenGL 3.x+ nomenclature(ES和WebGL共享),glTex*形式的所有函数修改绑定到具有给定纹理目标的当前纹理单元的纹理对象。

您可以将相同的纹理绑定到不同的纹理单元。但是你不能给它不同的参数。如果你想对相同的纹理使用不同的采样参数,你将不得不使用 Sampler Objects 你在 WebGL 中运气不好。

重复关于 SO 的大约 5 个其他答案,但是...

纹理操作是这样的。有一组全局纹理单元

internalGLState = { 
    activeTextureUnit: 0,
    textureUnits: [
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      { TEXTURE_2D: ?, TEXTURE_CUBEMAP: ?, }, 
      ...
    ], 
};

纹理由当前活动纹理单元和该单元的绑定点引用。

所以,gl.activeTexture 有效地做到了这一点

gl.activeTexture = function(unitId) {
  internalGlState.activeTextureUnit = unitId - gl.TEXTURE0;  // conver to index
}

所有其他纹理函数基本上都是这样工作的

function getTexture(bindPoint) {
  return internalGLState[internalGlState.activeTextureUnit][bindPoint];
}

例如gl.texParameteri

gl.texParameteri = function(bindPoint, settingId, value) {
  var texture = getTexture(bindPoint);
  texture.internalApplySetting(settingId, value);
}

设置在纹理上。 "texture units" 实际上只是一组对纹理的引用(除了每个单元的每个绑定点都有一个引用)

着色器通过纹理单元的索引引用纹理

gl.uniform1i(someSamplerUniformLocation, textureUnitIndex);

正如 Nicol 指出的那样,在 WebGL 1.0 中,不,您不能使用不同的参数获得相同的纹理。您可以在 WebGL 2.0 中使用采样器对象(希望很快发货)。

我的问题是,为什么要为相同的纹理设置不同的参数?作为从事大量商业视频游戏工作的人,我从未有过艺术家要求我这样做,所以我从未发现这是一个限制功能。

无论如何,如果您确实想在 WebGL 中执行此操作,则需要制作多个纹理或在使用之间更改参数(如果您不需要同时使用不同的参数)。