我加载了 2 个模型,它们都具有不同的纹理。东西在 Firefox 上运行完美,我可以将两种纹理应用于每个对象。但是,在Chrome上,第二个纹理永远不会显示。我大大简化了我的代码,发现这可能与我加载纹理的方式有关。
function texture() {
this.texture = null;
}
texture.prototype.loadTexture = function(gl, img) {
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
}
texture.prototype.load = function(gl, name) {
this.texture = gl.createTexture();
var img = new Image();
that = this;
img.onload = function() {
that.loadTexture(gl, img);
}
img.src = name;
}
我创建新纹理的方式是:
var texture = new texture();
texture.load(gl, "foo.bar");
当我单独渲染每个模型时,它会正确渲染它们。问题是当我在同一场景中使用两个模型时。我对火狐浏览器没有这个问题。我使用上述方法创建了一个包含 2 个纹理的数组,并强制两个模型渲染第一个纹理。这工作正常。但是,当我渲染第二个纹理时,Chrome 上没有任何反应,但它适用于 Firefox。Chrome 实际上会做很多不可预测的事情,具体取决于首先加载的纹理,以及我强制两种模型使用哪种纹理。通常,Chrome 会抛出"渲染警告:绑定到纹理单元 0 的纹理不可渲染"
因此,这让我相信我加载纹理的方式有问题。所以我的问题是:这是加载纹理的正确方法吗?我从在线教程中得到了这个,他们似乎一次只使用 1 个纹理/模型。我正在运行 Linux 版 Chromium,我还没有在 Windows 上测试过(如果有帮助的话)。
经过更多的研究,我解决了我的问题。我使用了Mozilla开发者网站上的加载函数:https://developer.mozilla.org/en-US/docs/Web/WebGL/Using_textures_in_WebGL
这和我的代码之间的唯一区别是Mozilla版本使用函数,而我使用对象(我也没有mimmap我的纹理,但我认为这不是问题)。
所以现在我很困惑为什么这有效,但我的原始实现没有。
如果您没有生成 mips,并且您没有将纹理过滤设置为不需要 mips,那么您的纹理不应该渲染。如果是,那就是浏览器中的错误。您上面的代码假设 mips 存在。要关闭对 mips 的需求,请将纹理包装设置为 CLAMP_TO_EDGE
并将过滤设置为NEAREST
或LINEAR
(这部分您已经在做)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
此行
that = this;
第二次调用全局变量时会破坏它。