簡體   English   中英

重用幾何會導致間歇性的THREE.JS紋理錯誤

[英]Reusing Geometry causes Intermittent THREE.JS Texture Error

我正在使用THREE.js為Firefox和Chrome創建我的第一個游戲(紙牌游戲),目前我遇到了間歇性錯誤,這使得我的一些紋理看不見。

這篇文章的目的是了解為什么會這樣,所以我可以解決問題。 我將在帖子的最后添加我的問題。

當我在加載場景之前切換瀏覽器選項卡時,它會以更高的頻率發生。

我已經檢查了我的代碼以驗證我是否在場景中已經加載了網格設置新材料,但事實並非如此。

我正在使用帶有箔卡的高光貼圖,我試圖在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

編輯:我正在添加兩個截圖,一個有錯誤,一個有一切正常。

錯誤

一次重裝后,一切正常


解決后編輯:

基本上我對場景中的所有卡片對象使用相同的幾何體。

我改變了:

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行代碼試圖重現錯誤時,我正在重用幾何體並且錯誤從未發生過。 我也使用相同的函數來創建生成問題的對象。

我會嘗試使用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() { ... } ); 

使用回調函數確保在進行之前完成加載。

嘿抱歉延遲我沒有登錄堆棧。 我認為這里的問題是你試圖將多個紋理應用於相同的幾何體。 我認為他們應該相互懷疑,但我猜不是。 克隆幾何體允許將每個紋理應用於它自己的對象。 或者至少那是我對事物的看法。

我做了一些讓錯誤永遠不會再發生的事情。

我正在編輯我的問題,因為我希望了解它為什么會發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM