three.js:WebGL:INVALID_OPERATION:bindTexture:对象不是来自此上下文

时间:2015-03-15 09:54:26

标签: three.js

在使用下面的代码行渲染天空框时,我得到“ WebGL:INVALID_OPERATION:bindTexture:object not from this context ”错误。因此,纹理不渲染,它给出黑色背景。

这种情况并非总是如此,有时它会完美呈现一些时间。我在添加到场景时比较了几何和材质数据,结果在这两种情况下都是相同的。

      var urls = [
              "img/bg/img-BACK.jpg",
              "img/bg/img-FRONT.jpg",
              "img/bg/img-TOP.jpg",
              "img/bg/img-BOTTOM.jpg",
              "img/bg/img-RIGHT.jpg",
              "img/bg/img-LEFT.jpg"
        ],

      textureCube = THREE.ImageUtils.loadTextureCube(urls); // load textures

      textureCube.format = THREE.RGBFormat;
      var shader = THREE.ShaderLib["cube"];
      shader.uniforms["tCube"].value = textureCube;

      var skyBoxMaterial = new THREE.ShaderMaterial({
        fragmentShader: shader.fragmentShader,
        vertexShader: shader.vertexShader,
        uniforms: shader.uniforms,
        depthWrite: false,
        side: THREE.BackSide
      });
      skyBoxMaterial.needsUpdate = true;

      var skybox = new THREE.Mesh(
            new THREE.CubeGeometry(10000, 10000, 10000),
            skyBoxMaterial
      );
      
      scene.add(skybox);

Screenshot

从上面的屏幕截图中,当我收到此错误时,点“1”是输出。点“2”屏幕在渲染时没有任何异常。

感谢您对修复此问题的支持。

1 个答案:

答案 0 :(得分:1)

我不确定这是解决问题的正确方法,但我认为解决了类似的问题。

在您的代码中,您有:

var shader = THREE.ShaderLib["cube"];
shader.uniforms["tCube"].value = textureCube;
// ....
var skyBoxMaterial = new THREE.ShaderMaterial({
    // ...
    uniforms: shader.uniforms,
});

这也是我在代码中的原因,也就是互联网上的所有例子。

更好的版本应该是:

var shader = THREE.ShaderLib["cube"];
var uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms["tCube"].value = textureCube;
// ....
var skyBoxMaterial = new THREE.ShaderMaterial({
    // ...
    uniforms: uniforms,
});

但是,这是一个共享变量:THREE.ShaderLib是一个单独的实例。因此,如果页面上有多个THREE.js内容,则它们共享THREE.ShaderLib。

因此,如果两个渲染器正在运行,并且两个渲染器都使用相同的着色器(在这种情况下是天空盒的tCube着色器),它们将错误地访问另一个的纹理(也可能是其他值)。

当发生这种情况时,webgl会抱怨来自一个上下文的纹理正在另一个上下文中使用。

通过克隆它们,我们创建了制服的本地副本,避免了这种干扰。

再次,这是我几分钟前的情况,克隆制服解决了它,希望它也可以帮到你。