Skip navigation

Textúrakép külső fájlból

Textúra kép

Főbb jellemzők

  • A mintázatot egy 2D raszterkép írja le. A szín információk mellett átlátszósági (alfa) értéket is hordozhat.
  • A raszterképet előállíthatjuk pl. képlet segítségével programból (lásd a vászonból textúra résznél), de a legjellemzőbb az, hogy külső képfájlból töltjük be. A Three.js ismeri a szokásos képfájl formátumokat, mint a JPG, PNG.
  • Hardveres okok miatt a WebGL olyan képekkel dolgozik a legoptimálisabban, amelyek négyzet alakúak, és méretük 2 egész kitevős hatványa (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, ...). Használhatunk más méretet is, de a Three.js át fogja méretezni.
  • A textúra mintákat a GPU tárolja. Képességeitől függően többet vagy kevesebbet, és arra is számítsunk, hogy nagyon nagy méretű textúrát az olcsóbb kártyák nem tudnak kezelni.

TextureLoader

Textúrák külső képfájlból való létrehozása nagyon egyszerűen megy Three.js-ben. Létre kell hozni egy TextureLoader objektumot, majd meghívni a load() függvényét. Paraméterként a betöltendő képfájl nevét kell átadnunk, eredményként a textúra objektumot kapjuk.

A textúra betöltése aszinkron, vagyis a függvény visszatér, mielőtt a textúra betöltése befejeződött volna! Viszont a rendszer gondoskodik arról, hogy a betöltés után a textúra az anyaghoz megfelelően hozzárendelődjön.

Vigyázzunk arra, hogy a futtatást webszerveren keresztül végezzük, mert lokálisan megnyitva a böngészők biztonsági okokból nem engedik a fájl hozzáférést!

Használati példa

Töltsük be a külső képfájlt pl. az init() függvényben. A textúrát az anyaghoz rendelhetjük hozzá a map attribútumán keresztül.

var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load( 'assets/texture/tc-earth_daymap_surface_rs.jpg' );

var geometry = new THREE.SphereGeometry( 8, 80, 80 );
var material = new THREE.MeshPhongMaterial();
material.map = texture;
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

Példaprogram

Próbáljuk ki a ThreeJsTextureTester példaprogramot! Nézzük meg mi történik, ha a gömböt kockára vagy körlapra cseréljük!

Aszinkron betöltés pontosabb kezelése (kiegészítő anyag)

Nagyobb mennyiségű képi adat betöltése esetén célszerűbb ezt aszinkron módon, a háttérben megtenni, a felhasználót pedig tájékoztatni, hol tart a dolog. A TextureLoader erre is lehetőséget ad. Figyeljünk arra, hogy a rendereléskor ne használjunk olyan objektumot, amelynek a betöltése még nem fejeződött be!

var loader = new THREE.TextureLoader();
loader.load(
'assets/tc-earth_daymap_surface_rs.jpg',
function ( texture ) {
// Ha a betöltés kész...
var geometry = new THREE.SphereGeometry( 8, 80, 80 );

//var geometry = new THREE.BoxGeometry( 8, 8, 8 );
var material = new THREE.MeshPhongMaterial();

material.map = texture;
mesh = new THREE.Mesh( geometry, material );
// Aszinkron betöltés, egy ideig nem lesz érvényes mesh!
scene.add( mesh );

},
// Betöltés előrehaladása
function ( xhr ) {

console.log( (xhr.loaded / xhr.total * 100) + '% betöltve.' );
},
// Hiba betöltés közben
function ( xhr ) {

console.log( 'Hiba történt textúra betöltés közben!' );
}
);

Figyeljünk arra, hogy a fájl betöltése aszinkron módon történik! Vagyis a program futása folytatódik a betöltés közben. Emiatt elképzelhető, hogy a render() függvény meghívódik, mielőtt a mesh hozzáadásra kerülne a színtérhez. A render() függvényben csak akkor próbáljunk hozzáférni a mesh objektumhoz, ha az már létezik.

if( mesh ) {
// Ha már létezik az objektum...
mesh.rotation.y += 0.01;

}

Megtehetjük azt is, hogy az objektumot a textúra betöltése előtt létrehozzuk és a színtérhez adjuk. Ekkor a rendelesénél textúrázatlanul meg fog jelenni. Ha a betöltés kész, hozzárendelhetjük az anyaghoz. Ha ennek ellenére nem jelenik meg a mintázat, az anyag objektumnak jelezzük, hogy változott, frissítése szükséges.

material.needsUpdate = true;

LoadingManager

Több erőforrás betöltése esetén célszerű egy betöltést vezérlő menedzser objektumot használni. Ez követi a folyamatban lévő betöltéseket, és akkor hívja meg az onLoad függvényét, ha minden elem sikeresen betöltődött.

Használatára a ThreeJsLoadingManagerTester.html program mutat példát.

Először definiáljuk a menedzser objektumot és rendeljük hozzá a kezelőfüggvényeket.

var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( 'Manager onProgress: loading of', item, 'finished; ', loaded, ' of ', total, ' objects loaded.' );
var progressString = 'Loading of ' + item + ' finished;<br/>' + loaded + ' of ' + total + ' objects loaded.';
appendInfoPanelText( progressString );
};
manager.onLoad = function () {
console.log( 'Manager onLoad called, render started.' );
appendInfoPanelText( 'Manager onLoad called, rendering started.' );
render();
};

A textúrák és JSON adatok betöltése az eddigiekhez hasonlóan megy, a betöltő objektumok konstruktorának át kell adni paraméterként a manager objektumot.

var textureLoader = new THREE.TextureLoader( manager );
var texture = textureLoader.load( 'assets/texture/tc-earth_daymap.jpg' );
var moonTexture = textureLoader.load( 'assets/texture/moonmap1k.jpg' );
var jsonLoader = new THREE.JSONLoader( manager );
jsonLoader.load( 'assets/models/uvsphere.json', function ( geom, mat ) {
// ...
} );