2013-08-26 10 views
6

Używam pliku three.js do utworzenia edytora tekstur minecraft, podobnego do this. Próbuję tylko zmniejszyć funkcjonalność "kliknij i pomaluj", ale nie mogę tego zrozumieć. Obecnie mam tekstury dla każdej powierzchni każdej kostki i stosuję je, tworząc materiały do ​​cieniowania z następującymi funkcjami.Aktualizacja obrazu Three.js

this.createBodyShaderTexture = function(part, update) 
{ 
    sides = ['left', 'right', 'top', 'bottom', 'front', 'back']; 
    images = []; 
    for (i = 0; i < sides.length; i++) 
    { 
     images[i] = 'img/'+part+'/'+sides[i]+'.png'; 
    } 
    texCube = new THREE.ImageUtils.loadTextureCube(images); 
    texCube.magFilter = THREE.NearestFilter; 
    texCube.minFilter = THREE.LinearMipMapLinearFilter; 
    if (update) 
    { 
     texCube.needsUpdate = true; 
     console.log(texCube); 
    } 
    return texCube; 
} 
this.createBodyShaderMaterial = function(part, update) 
{ 

    shader = THREE.ShaderLib['cube']; 
    shader.uniforms['tCube'].value = this.createBodyShaderTexture(part, update); 
    shader.fragmentShader = document.getElementById("fshader").innerHTML; 
    shader.vertexShader = document.getElementById("vshader").innerHTML; 

    material = new THREE.ShaderMaterial({fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: shader.uniforms}); 
    return material; 
} 

SkinApp.prototype.onClick = 
function(event) 
{ 
    event.preventDefault(); 
     this.change(); //makes texture file a simple red square for testing 
    this.avatar.remove(this.HEAD); 

    this.HEAD = new THREE.Mesh(new THREE.CubeGeometry(8, 8, 8), this.createBodyShaderMaterial('head', false)); 
    this.HEAD.position.y = 10; 
    this.avatar.add(this.HEAD); 
    this.HEAD.material.needsUpdate = true; 
     this.HEAD.dynamic = true; 
} 


Następnie, gdy użytkownik kliknie w każdym miejscu na siatce, sam plik tekstury jest aktualizacja za pomocą płótna. Aktualizacja występuje, ale zmiana nie jest wyświetlana w przeglądarce, chyba że strona zostanie odświeżona. Znalazłem wiele przykładów, jak zmienić obraz tekstury na nowy plik, ale nie w jaki sposób wyświetlać zmiany w tym samym pliku tekstur podczas środowiska wykonawczego, a nawet jeśli jest to możliwe. Czy to możliwe, a jeśli nie, jakie są alternatywy?

Odpowiedz

12

Po zaktualizowaniu tekstury, czy jego oparte na płótnie, wideo lub ładowane z zewnątrz, trzeba ustaw następującą właściwość na teksturę true:

Jeśli obiekt jest tworzony tak:

var canvas = document.createElement("canvas"); 
var canvasMap = new THREE.Texture(canvas) 
var mat = new THREE.MeshPhongMaterial(); 
mat.map = canvasMap; 
var mesh = new THREE.Mesh(geom,mat); 

Po faktura została zmieniona, należy ustawić następujące true:

Następnym razem, gdy wyrenderujesz scenę, wyświetli się nowa tekstura.

+1

Dzięki, to działało idealnie! Myślę, że miało to coś wspólnego ze mną przy użyciu ShaderMaterial, ale działa dobrze z MeshBasicMaterial. – shaqb4

+3

Tak naprawdę musiałem wykonać zarówno "materiał.map.needsUpdate = true; material.needsUpdate = true' –

+3

@ shaqb4 Następnie poprzyj tę odpowiedź i zaakceptuj ją! Tak właśnie rozwijamy się na stackoverflow. –

1

Oto wszystkie podstawy, co trzeba wiedzieć o „Aktualizacja” rzeczy w three.js: https://github.com/mrdoob/three.js/wiki/Updates

+0

Już wcześniej przeglądałem tę stronę, ale żadna z metod nie działa. Kiedy klikam, próbuję stworzyć zupełnie nową siatkę, materiał i materiał cieniowania, ale zmiana nie pojawia się na ekranie, mimo że flagi aktualizacji są ustawione na true. – shaqb4

+0

Czy możesz pokazać przykład? –

+0

Zaktualizowałem moje pytanie, aby wyświetlić więcej kodu. – shaqb4