2013-05-13 11 views
6

próbuję zdefiniować materiał oczek I ładowane od OBJLoader poprzez następującą funkcją Wrapper:Trzy JS Mapa Materiał powoduje WebGL Ostrzeżenie

function applyTexture(src){ 
    var texture = new THREE.Texture(); 
    var loader = new THREE.ImageLoader(); 
    loader.addEventListener('load', function (event) { 
     texture.image = event.content; 
     texture.needsUpdate = true; 

     // find the meshes from the loaded OBJ and apply the texture to it. 
     object.traverse(function (child) { 
      if (child instanceof THREE.Mesh) { 
       if(child.name.indexOf("Lens") < 0){ 
        child.dynamic = true; 

        child.material = new THREE.MeshLambertMaterial({ color: 0xdddddd, shading: THREE.FlatShading, map : texture }); 
        // also tried: 
        //child.material = new THREE.MeshPhongMaterial({ color: 0x000000, specular: 0x666666, emissive: 0x000000, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, map : texture}); 
        // and: 
        //child.material = new THREE.MeshBasicMaterial({map : texture}); 
        child.material.map = texture; // won't throw the WebGL Warning, but won't show the texture either; 
       } else { 
        // works just fine. 
        child.material = new THREE.MeshPhongMaterial({ color: 0x000000, specular: 0x666666, emissive: 0x000011, ambient: 0x000000, shininess: 10, shading: THREE.SmoothShading, opacity: 0.6, transparent: true }); 
       } 
      } 
     }); 
    }); 
    loader.load(src); 
} 

Gdy tekstura została załadowana i nadszedł czas, aby zastosować materiał do siatki, na konsoli zaczynam otrzymywać następujące ostrzeżenie:

.WebGLRenderingContext: GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0 

, a sama siatka znika.

co ja tu robię źle?

UPDATE

Jak @WestLangley wskazał na komentarze: Nigdy nie wolno stosować tekstury/materiały po rzeczy zostały wydane. Tworzenie materiałów przed renderowania obiekt do sceny, a następnie zmień je za pomocą:

obj.material.map = texture 
+0

Czy to działa, jeśli dodasz teksturę do materiału od samego początku, więc pierwsze renderowanie siatki zawiera teksturę? – WestLangley

+0

@WestLangley Teksturę stosuje się, gdy siatka jest załadowana i zanim zostanie dodana do sceny, a wtedy jest jej brak. Kiedy próbowałem użyć "child.material.map = texture" nie otrzymałem ostrzeżenia WebGL, ale tekstura nie została zastosowana. Bez względu na przyczynę, "child.material = new THREE.MeshLambertMaterial ({color: 0xdddddd, cieniowanie: THREE.FlatShading, map: texture});" stosuje teksturę podczas zmiany renderera z WebGL na Canvas. Pełny kod tutaj: https://gist.github.com/jrmoretti/81047c9d6821e4bbaac5 – JayMoretti

+0

W WebGLRenderer nie można dodać tekstury po fakcie. Możesz zmienić tylko teksturę. Obróbka rozpoczyna się od materiału o prostej białej teksturze. – WestLangley

Odpowiedz

11

Z WebGLRenderer, nie można przełączyć z materiału bez tekstur, z materiału o fakturze, po siatka została renderowane raz. Dzieje się tak dlatego, że bez początkowej tekstury geometria nie będzie zawierała potrzebnych zapakowanych buforów UV WebGL.

Obejście problemu rozpoczyna się od materiału o prostej białej teksturze.

UPDATE: Ewentualnie możesz może zaczynać się textureless materiału, a następnie ustawić następujące flagi kiedy tekstury dodaje:

material.needsUpdate = true; 
geometry.buffersNeedUpdate = true; 
geometry.uvsNeedUpdate = true; 

Three.js r.58

+0

dzięki. ta sztuczka działa dobrze. – magirtopcu

2

Dostałam też ten błąd podczas ładowania sceny z blendera. Dla mnie problem został rozwiązany po rozpakowaniu uv dla każdej siatki chcę mieć teksturę.

+0

Tak, po prostu powoduje błędy podczas przypisywania tekstury do modelu, który nie ma współrzędnych tekstury. Wygeneruj je w swoim kodzie lub w programie do modelowania. r69 – StackHola