【问题标题】:Three JS Map Material causes WebGL Warning三个 JS 地图材质导致 WebGL 警告
【发布时间】:2013-05-08 01:26:19
【问题描述】:

我正在尝试为我通过以下包装函数从 OBJLoader 加载的网格定义材质:

function applyTexture(src){
    var texture = new THREE.Texture();
    var loader = new THREE.ImageLoader();
    loader.addEventListener( 'load', function ( event ) {
        texture.image = event.content;
        texture.needsUpdate = true;

        // find the meshes from the loaded OBJ and apply the texture to it.
        object.traverse( function ( child ) {
            if ( child instanceof THREE.Mesh ) {
                if(child.name.indexOf("Lens") < 0){
                    child.dynamic = true;

                   child.material = new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading, map : texture } );
                   // also tried:
                   //child.material = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0x000000, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, map : texture} );
                   // and:
                   //child.material = new THREE.MeshBasicMaterial({map : texture});
                   child.material.map = texture; // won't throw the WebGL Warning, but won't show the texture either;
               } else {
                   // works just fine.
                   child.material = new THREE.MeshPhongMaterial( { color: 0x000000, specular: 0x666666, emissive: 0x000011, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.6, transparent: true } );
               }
            }
        });
    });
    loader.load( src );
}

当纹理已经加载并且是时候将材质应用到网格上时,我开始在控制台上收到以下警告:

.WebGLRenderingContext: GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0 

网格本身消失了。

我在这里做错了什么?

更新

正如@WestLangley 在 cmets 上指出的那样:永远不要在渲染后尝试应用纹理/材质。在将对象渲染到场景之前创建材质,然后使用以下方法更改它们:

obj.material.map = texture

【问题讨论】:

  • 如果从一开始就给材质添加纹理,那么第一次渲染mesh就包含了纹理,是否有效?
  • @WestLangley 在加载网格时应用纹理,然后将其添加到场景中,这就是失败的时候。当我尝试使用“child.material.map = texture”时,我没有收到 WebGL 警告,但没有应用纹理。无论出于何种原因,“child.material = new THREE.MeshLambertMaterial({ color: 0xdddddd, shading: THREE.FlatShading, map : texture });”将渲染器从 WebGL 更改为 Canvas 时应用纹理。完整代码在这里:gist.github.com/jrmoretti/81047c9d6821e4bbaac5
  • 在 WebGLRenderer 中,您不能事后添加纹理。不过,您可以只更改纹理。一种解决方法是从具有简单白色纹理的材质开始。
  • 这是有道理的。从加载的 .obj 材质中检查每个网格并得到:dropmocks.com/mBtEPg,这意味着它已经开始使用纹理,并且在加载时看起来像这样:dropmocks.com/mBsyrY。除了 obj.material.map / obj.material.lightMap 之外,还有其他方法可以只改变纹理吗?
  • 提供一个 simple 实例,我来看看。请使其成为演示您的问题的最简单示例。代码片段无法将我们带到任何地方。

标签: three.js texture-mapping


【解决方案1】:

使用WebGLRenderer,在网格渲染一次后,您无法从没有纹理的材质切换到有纹理的材质。这是因为,如果没有初始纹理,几何体将没有必要的烘焙 WebGL UV 缓冲区。

一种变通方法是从具有简单白色纹理的材料开始。

更新:或者,您可以从无纹理材质开始,然后在添加纹理时设置以下标志:

material.needsUpdate = true;
geometry.buffersNeedUpdate = true;
geometry.uvsNeedUpdate = true;

three.js r.58

【讨论】:

    【解决方案2】:

    我在从搅拌机加载场景时也遇到了这个错误。对我来说,当我为每个我想要有纹理的网格展开 uv 时,这个问题已经解决了。

    【讨论】:

    • 是的,当将纹理分配给没有纹理坐标的模型时,它只会出错。在您的代码或建模器中生成它们。 r69
    猜你喜欢
    • 2014-01-08
    • 2015-09-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多