Javascript threejs-将带有纹理贴图的材质应用于通过THREE.ObjectLoader加载的对象

Javascript threejs-将带有纹理贴图的材质应用于通过THREE.ObjectLoader加载的对象,javascript,three.js,Javascript,Three.js,我通过JSON文件引入几何体和材质。在大多数情况下,这很有效,但现在我尝试引入纹理贴图。据我所知,THREE.ObjectLoader会从加载的纹理中删除任何图像信息,因此材质无法访问图像源我尝试过几种方法,但它们都会产生相同的结果:如果我使用纹理贴图重新创建材质并将其应用于加载的对象,该对象将消失。 为了确保某些东西能够工作,我创建了一个简单的场景,其中包含一个立方体和一个材质。这很好: var textureDiff = THREE.ImageUtils.loadTexture( "img/

我通过JSON文件引入几何体和材质。在大多数情况下,这很有效,但现在我尝试引入纹理贴图。据我所知,THREE.ObjectLoader会从加载的纹理中删除任何图像信息,因此材质无法访问图像源我尝试过几种方法,但它们都会产生相同的结果:如果我使用纹理贴图重新创建材质并将其应用于加载的对象,该对象将消失。

为了确保某些东西能够工作,我创建了一个简单的场景,其中包含一个立方体和一个材质。这很好:

var textureDiff = THREE.ImageUtils.loadTexture( "img/brick_diffuse.jpg" ); 
textureDiff.wrapS = THREE.RepeatWrapping; 
textureDiff.wrapT = THREE.RepeatWrapping; 
textureDiff.repeat.set( 2, 2 );

var textureBump = THREE.ImageUtils.loadTexture( "img/brick_bump.jpg" ); 
textureBump.wrapS = THREE.RepeatWrapping; 
textureBump.wrapT = THREE.RepeatWrapping; 
textureBump.repeat.set( 2, 2 );

var material = new THREE.MeshPhongMaterial({map: textureDiff, bumpMap: textureBump});

var geometry = new THREE.BoxGeometry( 2, 2, 2 ); 

var cube = new THREE.Mesh( geometry, material ); 
cube.name = "myCube";
cube.position.set( 0, 1, 0 );
cube.castShadow = true;
cube.receiveShadow = true;
scene.add( cube );
我得到了一个砖纹理的立方体。伟大的我甚至可以混合这种顺序,例如,使用简单材质添加立方体,将其添加到场景中,按其名称查找立方体,然后使用新材质替换它。所有这些都有效

乍一看,通过THREE.ObjectLoader加载对象是有效的。对象就在那里,它们的材质颜色表示生成JSON的应用程序中为它们指定的材质。如果我询问在这个方法中加载的对象,几乎所有我期望的和存储在文件中的特征都在那里。但当我查看对象的材质时,贴图槽为空。因此,我查看了THREE.ObjectLoader的源代码,从中我发现可能没有加载材质纹理贴图。ObjectLoader遵从于似乎没有处理纹理贴图的逻辑的

因此,我还尝试处理来自已解析JSON场景对象的材质。这里我得到了JSON文件中的结构。我浏览了材质、纹理和图像,并由此创建了一个新的材质阵列。如果查询新材质数组,贴图将包含一个带有图像的纹理对象。我尝试了几种方式加载纹理:

首先,通过使用上面测试中的ImageUtils:

scene.children[i].material.map =  THREE.ImageUtils.loadTexture('img/brick_diffuse.jpg');
其次,通过实际构建一切,首先加载图像,然后制作纹理,然后制作材质,然后将其应用于对象(以下是材质构建代码)。在这种情况下,如果删除贴图,导入的对象将变为红色:

var loaderImg = new THREE.ImageLoader();
// load a image resource 
loaderImg.load( // resource URL 
    'img/brick_diffuse.jpg', 
    // Function when resource is loaded 
    function ( image ) { // do something with it // like drawing a part of it on a canvas 
console.log("image loaded!");

texture = new THREE.Texture({
    image : image,
    wrapS : THREE.RepeatWrapping,
    wrapT : THREE.RepeatWrapping,
    repeat : [1,1]
});

material = new THREE.MeshPhongMaterial({
    color: new THREE.Color('rgb(0,0,255)'),
    map: texture

    });

//add material to object    
scene.children[i].material = material;                          
},

function ( xhr ) { console.log( (xhr.loaded / xhr.total * 100) + '% loaded' ); }, 
// Function called when download errors 
function ( xhr ) { console.log( 'An error happened' ); } );
我尝试了上述多次迭代,所有结果都指向相同的结果:如果我向创建的材质添加贴图,对象不会出现,如果我忽略材质的贴图属性,导入的对象会更改材质(会看到新的颜色和其他属性)

我看到这里有几条路: 1.只需使用解析后的JSON场景,忘掉THREE.ObjectLoader,遍历文件中的所有对象,获取它们的相关材料,等等,一点一点地构建它。 2.扩展THREE.MaterialLoader以进入并实际加载图像 3.有点发疯了

我在这里看到了几个关于处理类似问题的问题,但似乎没有明确的答复。我还尝试了一些答案中建议的其他方法,我总是得到一个丢失的对象

我在ThreeJSR70上,已经在本地和远程服务器、Chrome和Firefox上进行了尝试

最后,我尝试了以下两种方法:

 var textureDiff = THREE.ImageUtils.loadTexture( "img/Cork.png" ); 
    textureDiff.wrapS = THREE.RepeatWrapping; 
    textureDiff.wrapT = THREE.RepeatWrapping; 
    textureDiff.repeat.set( 2, 2 ); 

    var material = new THREE.MeshPhongMaterial({
        color:new THREE.Color('rgb(255,0,0)'),
        map: textureDiff
        });

    var geometry = new THREE.BoxGeometry( 2, 2, 2 );            
    var mmm = new THREE.Mesh(geometry, material );
    scene.add(mmm);
二,。在这里,如果使用导入对象的几何体创建新网格,网格将消失:

var textureDiff = THREE.ImageUtils.loadTexture( "img/Cork.png" ); 
    textureDiff.wrapS = THREE.RepeatWrapping; 
    textureDiff.wrapT = THREE.RepeatWrapping; 
    textureDiff.repeat.set( 2, 2 );

    var geometry = new THREE.BoxGeometry( 2, 2, 2 ); 

    var material = new THREE.MeshPhongMaterial({
        color:new THREE.Color('rgb(255,0,0)'),
        map: textureDiff
        });

    var mmm = new THREE.Mesh(scene.children[i].geometry, material );
    scene.add(mmm);
如果我注释掉贴图(//map:textureDiff),则导入的几何体是红色的,呈现材质的颜色

很抱歉这么长时间的询问,我想确保我记录了我的尝试。我希望我把事情复杂化了,因为如果我尝试添加带有纹理的材质,我肯定会遗漏一条关于为什么我的对象会消失的简单信息。
谢谢。

我正在处理的问题有几个相关的子问题: 1.threejs的r70中的THREE.ObjectLoader不支持材质纹理加载。 2.我的JSON不包括任何面顶点UV

为了解决第一个问题,我查看了源代码和pull请求,发现了一个。由于这些更改没有编译到库中,所以我构建了一个混合的3JS,用这个pull请求中的版本替换当前的版本ObjectLoader

为了解决第二个问题,我将应用程序中的网格面顶点UV添加到正在编写的json文件中

拉动请求现在已被取消


感谢@denzp的修改和@mrdoob(以及其他贡献者)在threejs上的出色工作。

只是为了验证,THREE.ObjectLoader还不支持这一点:。尽管如此,我还是应该能够以某种方式将纹理贴图放到几何体上!下面是一个解决此问题的拉取请求:构建此版本后,loadmanager确实报告正在加载的图像,但我收到其他错误:THREE.WebGLRenderer:WEBGL_compressed_texture_pvrtc extension not supported THREE.js(第24404行)和TypeError:invalid'instanceof'Operator THREE.ImmediatenderObject THREE.js(第21582行)