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

时间:2015-02-10 12:17:52

标签: javascript three.js

我通过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遵循MaterialLoader,似乎没有处理纹理贴图的逻辑。

因此,我尝试也处理解析后的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.有点疯狂。

我在这里看到了几个处理类似问题的问题,但似乎没有明确的答案。我也尝试过在一些答案中提出的其他方法,我总是得到一个缺失的对象。

我正在使用trijs r70,尝试使用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);

2。在这里,如果我使用导入对象的几何体来制作新网格,则网格消失:

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 个答案:

答案 0 :(得分:3)

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

要解决第一个问题,我查看了源代码并通过pull请求找到了modification to the object loader。由于这些更改未编译到库中,因此我构建了一个混合的threejs,将当前版本的ObjectLoader替换为此pull请求中的一个。

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

拉取请求现在为merged with the dev branch of threejs

感谢@denzp的修改以及@mrdoob(和其他贡献者)对threejs的精彩工作。