2015-02-10 67 views
0

我正在通过JSON文件引入几何和材质。大多数情况下,这个效果很好,除了现在我正在尝试引入纹理贴图。从我所知道的情况来看,THREE.ObjectLoader会从加载的纹理中去除任何图像信息,因此材质无法访问图像源。 我已经尝试了几件事情,但它们都导致相同的结果:如果我使用纹理贴图重新创建材质并将其应用于加载的对象,对象将消失。threejs - 将具有纹理贴图的材质应用于通过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.稍微坚果一下。

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

我在threejs 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),则导入的几何图形将呈红色,并显示材质的颜色。

对长查询的道歉,我想确保我记录我的企图。我希望我已经完成了复杂的事情,因为我肯定错过了一些关于为什么我的对象会消失的简单信息,如果我尝试添加具有纹理的材质。 谢谢。

+0

只是为了验证,THREE.ObjectLoader目前还不支持:https://github.com/mrdoob/three.js/issues/4967。不过,我应该能够以某种方式将纹理贴图贴到几何图形上!这是一个解决这个问题的请求:https://github.com/denzp/three.js/commit/c069ec1b26014b55bc961846feaf7f7554fc2bb2 构建这个版本后,loadmanager报告正在加载的图片,但是我得到了其他错误:THREE.WebGLRenderer: WEBGL_compressed_texture_pvrtc扩展名不支持three.js(第24404行)和TypeError:无效的'instanceof'操作数THREE.ImmediateRenderObject three.js(第21582行) – 2015-02-10 15:35:44

回答

3

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

为了解决第一个问题,我查看了源代码并通过拉请求,发现一个modification to the object loader。由于这些更改没有被编译到库中,所以我构建了一个混合的threejs,将当前版本的ObjectLoader替换为该请求中的那个。

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

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

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