2014-03-12 78 views
4

我正在用THREE.js創建我的第一款遊戲(紙牌遊戲),適用於Firefox和Chrome,我目前陷入了一些間歇性錯誤,這使得我的一些紋理看不見。重複使用幾何導致間歇性THREE.JS紋理錯誤

我的這篇文章的目的是爲了理解爲什麼會發生這種情況,所以我可以在解決方案上工作。我將在帖子末尾添加我的問題。

在加載場景之前切換瀏覽器選項卡時發生更多頻率。

我已經檢查了我的代碼,以驗證是否將新材料設置爲已加載的網格,並且不是這種情況。

我正在使用帶鋁箔卡片的高光貼圖,並且我在Stack Overflow中嘗試了沒有成功的相關解決方案。我也嘗試刪除高光貼圖。

我還閱讀了關於設置對象在場景中後添加的材質的更新標誌,它也不起作用。

我也看過類似的帖子,但這兩個概括了我必須嘗試解決問題的選項。

錯誤:

256 [.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0 
WebGL: too many errors, no more errors will be reported to the console for this context. 

的卡對象創建步驟: 1 - 創建的遊戲負載鹼幾何 2 - 重用它用於被創建的

基地幾何創建的所有卡(頂點/臉部操作是爲vertexColors:THREE.VertexColors的邊界創建黑灰色 - 黑色梯度:

(function createGeometry() { 
DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg"); 

DBZCCG.Card.cubeGeo = 
    new THREE.CubeGeometry(
     DBZCCG.Card.cardWidth, 
     DBZCCG.Card.cardHeight, 
     DBZCCG.Card.cardDepth 
    ); 

/* Vertex and face alterations */ 
var cube = DBZCCG.Card.cubeGeo; 
var vertices = cube.vertices; 
var faces = cube.faces; 

vertices.push(vertices[7].clone()); 
vertices.push(vertices[5].clone()); 
vertices.push(vertices[0].clone()); 
vertices.push(vertices[2].clone()); 

vertices[5].color = vertices[0].color = vertices[2].color = vertices[7].color 
     = new THREE.Color(0x777777); 

vertices[5].z = vertices[0].z = vertices[2].z = vertices[7].z = 0; 

faces[8].a = 9; 
faces[8].b = 8; 
faces[8].c = 10; 

faces[9].a = 8; 
faces[9].b = 11; 
faces[9].c = 10; 

faces.push(new THREE.Face3(9, 5, 7)); 
faces.push(new THREE.Face3(9, 7, 8)); 

faces.push(new THREE.Face3(0, 10, 2)); 
faces.push(new THREE.Face3(10, 11, 2)); 

faces.push(new THREE.Face3(8, 7, 2)); 
faces.push(new THREE.Face3(8, 2, 11)); 

faces.push(new THREE.Face3(5, 9, 0)); 
faces.push(new THREE.Face3(0, 9, 10)); 

for (var i = 0; i < faces.length; i++) { 
    if (vertices[faces[i].a].color === undefined) { 
     faces[i].vertexColors[0] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[0] = vertices[faces[i].a].color; 
    } 

    if (vertices[faces[i].b].color === undefined) { 
     faces[i].vertexColors[1] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[1] = vertices[faces[i].b].color; 
    } 

    if (vertices[faces[i].c].color === undefined) { 
     faces[i].vertexColors[2] = new THREE.Color(0x000000); 
    } else { 
     faces[i].vertexColors[2] = vertices[faces[i].c].color; 
    } 
} 

})(); 

這裏是創建卡的功能:

function createCard(texturePath) { 
     var card = new THREE.Object3D(); 
     DBZCCG.loadCounter++; 
     var frontTexture = texturePath ? 
      THREE.ImageUtils.loadTexture(texturePath, 
      THREE.UVMapping, 
      DBZCCG.incrementLoad) 
      : null; 
     DBZCCG.loadCounter++; 
     var specularMap = 
      THREE.ImageUtils.loadTexture(
       'images/DBZCCG/saiyan/specularmap.jpg', 
       THREE.UVMapping, DBZCCG.incrementLoad); 

     var cardCoverBackMaterials = []; 
     for (var i = 0; i < 4; i++) { 
      cardCoverBackMaterials.push(new THREE.MeshBasicMaterial(
        { 
         transparent: true, 
         emissive: 0xFFFFFF, 
         vertexColors: THREE.VertexColors 
        })); // sides 
     } 

     cardCoverBackMaterials[4] = new THREE.MeshBasicMaterial(
       { 
        transparent: true, 
        emissive: 0xFFFFFF, 
        map: DBZCCG.Card.backTexture 
       }); // back 

     cardCoverBackMaterials[5] = new THREE.MeshBasicMaterial(
      { 
       transparent: true, 
       reflectivity: dataObject.foil ? 
        dataObject.foil.reflectivity : 1, 
       specularMap: specularMap, 
       envMap: dataObject.foil ? dataObject.foil.texture : null, 
       emissive: 0xFFFFFF, 
       map: frontTexture 
      }); // front 

     for (var i = 0; i < 4; i++) { 
      cardCoverBackMaterials.push(
       new THREE.MeshBasicMaterial({ 
        transparent: true, 
        emissive: 0xFFFFFF 
      })); // sides 
     } 

     var cube = new THREE.Mesh(
      DBZCCG.Card.cubeGeo, 
      new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

     card.add(cube); 

     return card; 
    } 

問題:

1 - 有什麼我可以做嘗試解決這個問題?

2 - 這是否與對象添加到場景之前渲染的場景相關?

3 - 這與在紋理加載之前渲染的場景有關嗎?

4 - 對於Q2和Q3,我嘗試添加窗口間隔的負載檢查。我時常還是遇到了錯誤。

5 - 是否有一個選項可以捕獲webgl錯誤並再次渲染所有內容?這是一個很好的選擇嗎?

TL/DR;我的代碼在加載時發生間歇性的WebGL錯誤。我正在使用THREE.js。

謝謝

three.js所R66

編輯: 我加入兩張截圖,一個與錯誤和一個一切正常。

Error

One reload later, everything is normal


編輯後我國解決:

基本上我用的是相同的幾何形狀爲現場所有的卡對象。

我只是改變:

var cube = new THREE.Mesh(DBZCCG.Card.cubeGeo, 
new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

分爲:

var cube = new THREE.Mesh(DBZCCG.Card.cubeGeo.clone(), 
new THREE.MeshFaceMaterial(cardCoverBackMaterials)); 

不應該被我重用相同的幾何?

我仍然不明白爲什麼它會導致錯誤消失,我想解釋爲什麼它解決了錯誤(也可能是爲什麼它導致錯誤)。

當我製作了50行代碼試圖重現錯誤時,我重複使用了幾何圖形,並且錯誤從未發生過。我還使用相同的功能來創建產生問題的對象。

+0

您可以製作一個演示問題的50行程序嗎? – WestLangley

+0

我製作了一個50行的程序,完成與我的問題相同的步驟,但是50行程序根本沒有產生錯誤。我可以提供顯示工作版本的輸出和錯誤發生時間的屏幕截圖。但是,如果這變成了「help-me-debug-my-program」,我明白沒有什麼可以回答我的,我將刪除我的問題。 – hawaii

+0

如果可以,我會很樂意盡力幫助你。試着用一個簡單的例子重現問題。您是否在運行時添加了紋理,之前沒有紋理? – WestLangley

回答

2

我會嘗試使用onLoad事件的回調來控制代碼的時間和執行。例如改變

DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg"); 

DBZCCG.Card.backTexture = THREE.ImageUtils.loadTexture(
    "images/DBZCCG/back.jpg", new THREE.UVMapping(), function() { ... }); 

使用回調函數,以確保負載已取得進展之前完成。

嘿,抱歉,我沒有登錄到堆棧的延遲。我認爲這裏的問題是你試圖將多個紋理應用於同一個幾何體。我認爲他們應該相互對待,但我猜不是。克隆幾何圖形允許將每個紋理應用到它自己的對象。或者至少這是我的東西。

+0

已經改變了。我添加了一個onLoad回調函數,用於統計我要添加到遊戲中的紋理,並且在檢查是否已達到預期的紋理數量之前有一個window.interval。只有在這之後,我才能進行渲染遊戲。另外,我在onError回調中添加了一個console.log調用。發生錯誤時,控制檯中沒有任何額外的內容顯示在onError函數中。我正在嘗試縮減代碼。我從頭開始重建場景,但沒有顯示任何錯誤。試圖從除了錯誤的元素之外的所有元素中剝離場景使錯誤發生。 – hawaii

+0

錯誤仍然存​​在。我試圖解決這個問題的方法是縮小css和js,加上緩存紋理而不是創建新的紋理。 – hawaii

+0

我能夠解決這個錯誤,但我現在需要了解它爲什麼會發生。 – hawaii

1

我做了一件讓錯誤再也沒有發生的事情。

我在編輯我的問題,因爲我想了解爲什麼會發生。

相關問題