2015-02-10 66 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上的出色工作。