3D kanvaal - webGL


Kaasajal suudavad/oskavad modernsed brauserid (isegi IE 11 !) näidata kanvaal ka 3D kujundid liikumist, mis põhinevad WebGL kasutamisel.

Brauser ja 3D

Ruumilise (3D) graafika näitamine nõuab väga palju arvutamist ja tavalised PC protsessorid ei tule sellega veel toime, selleks on tarvis graafikaprotsessori tasemel programmeerimiskeskkonda.

Personaalarvutites tuntuim neis on Google poolt arendatud OpenGL-il põhinev WebGL, mis toimib Chromes, Firefoxis, Operas ja isegi IE versioonis 11,
kuigi Microsoft on kogu aeg püüdnud OpenGL-ile eelistada oma graafikaprogrameerimissüsteemi DirectX.

Kanvaal on WebGL-i kasutamiseks loodud mitmeid teeke, neist kõige arenenum (praehu) on three.js ; sellega koos tuleb ka palju näiteid, mis selgitavad teegi kasutamist. WebGL-i kasutava html-dokumendi loomisel tuleb luua 4 põhikomponenti:

  • THREE stseen (scene)
  • renderer - 3D objekti kirjeldavast koodist pikslite värviinfo arvutaja
  • kaamera, et stseeni vaadelda mingist komemõõtmelise ruumi punktist
  • mõned ruumilised (3D) objektid ; 3D objektide kirjeldamisel peamine on nende geomeetria (kuju), sellele lisatakse väljanägemist määravad materjalid
  • Three.js dokumendi elementaarne struktuur on üsna lihtne:

    <html> 
    	<head> 
    	<title> Three.js 3D dokument 
    	<style>canvas { width: 100%; height: 100% }</style> 
    	</head> 
    	
    	<script src="../build/three.min.js"> //mahalaetud paketti näidetes on asukoht selline 
    	<body> 
    	<script> // Meie skript. 
    	</script> 
    	
    	</body> 
    	</html>

    Kõigis paketti näidetes on www-lehe vasakus ülanurgas väike aken, milles näidatakse esitamiskiirust (FPS - Frames Per Sec) - see on väga kasulik ja võimaldab kohe näha, kui skripti lisamisel midagi läks valesti - kaadrivahetuskiirus muutub nulliks. Kasulik on ka automaatne hoiatus kasutajale, kui selle brauser 8veel) ei suuda WebGL-i näidata. Nende kasutamiseks peab dokumendi päises importima veel kaks skripti:

    <script src="js/Detector.js"></script>
    		<script src="js/libs/stats.min.js"></script>

    Hoiatuse saamiseks alustame oma skripti reaga

    if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
    	

    Lisame ülalesitatud skripti stseeni ja renderdaja loomise:

    var scene = new THREE.Scene(); 
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); 
    var renderer = new THREE.WebGLRenderer(); 
    renderer.setSize( window.innerWidth, window.innerHeight ); 
    document.body.appendChild( renderer.domElement );

    Loome ka ühe 3D-objekti - punase kuubi:

    var geometry = new THREE.CubeGeometry(1,1,1); 
    var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); 
    var cube = new THREE.Mesh( geometry, material ); 
    scene.add( cube ); 
    camera.position.y = 2;
    camera.position.z = 5;

    Teegi three.js koordinaadistik on nagu enamusel 3D graafikapatettidel: x-telg ekraanil paremale, y - üles, z- ekraanilt vaataja suunas, seega kaamera on tõstetud veidi kõrgemale ja nihutatud ekraanilt vaataja suunas.

    Lisame ka renderdaja; et pilt elavam oleks, paneme kuubi ümber x-teje (horisontaaltelg) ja y-telje (püsttelg) pöörlema

    var render = function () { 
    requestAnimationFrame(render); 
    cube.rotation.x += 0.1; 
    cube.rotation.y += 0.1; 
    renderer.render(scene, camera); };

    Statistika saamiseks tuleb enne animatsiooni algust lisada html-dokumendi kehale objekt statistika näitamiseks ja käivitada kell:

    	stats = new Stats();
    	stats.domElement.style.position = 'absolute';
    	stats.domElement.style.top = '0px';
    	document.body.appendChild( stats.domElement );
    	var t = 0;
    	var clock = new THREE.Clock();
    ja lisada renderdamisfunktsiooni statistika uuendamine:
    stats.update();

    Tekstuuride importimine

    Kuna lihtsalt punane kast on igav, teeme sellest puukasti - defineerime uue materjali:

    var crateMaterial = new THREE.MeshLambertMaterial( {map: THREE.ImageUtils.loadTexture('textures/crate.jpg')});  
    ja muudame kasti definitsioonis materjali:
    var cube = new THREE.Mesh( geometry, crateMaterial );

    tekstuuri nägemiseks on ka valgust vaja, lisame ühtlase hajutatud valguse (ambient - umbes nagu sombus päeval - valge, kuid varje ei teki):

    scene.add( new THREE.AmbientLight( 0xcccccc ) );

    3D objektide importimine

    Lisame põõrlevale kastile ka selle imetleja. Three.js oskab importida mitmeid 3D formaate (.obj, .wrm, .dae jne). Siin on kasutatud Collada formaati .dae; pisike Furby-robot on eksporditud Sketchup-ist. Selle lisamiseks tuleb dokumendi peas laadida Collada importer

    <script src="js/loaders/ColladaLoader.js"></script>

    Skript algab Collada objekti laadimisega. Nagu piltidega, ei tohi ka siin alustada ülejäänud skripti enne kui 3D objekt on laetud, sellepärast on ülejäänud skript tehtud uueks funktsiooniks, mis käivitatakse alles pärast edukat .dae-faili laadimist:

    var loader = new THREE.ColladaLoader();
    			loader.options.convertUpAxis = true;
    			
    			loader.load( './models/R2-D2F-F02x10.dae', function ( collada ) { //good, with textures !
    				player = collada.scene;
    				skin = collada.skins[ 0 ];
    
    				player.scale.x = player.scale.y = player.scale.z = 0.002;
    				//player.scale.y = 2;
    				//player.rotation.y = Math.PI; //pöörame näoga saali poole
    				player.updateMatrix();
    				init();
    				//animate();
    
    			} );
    :

    Ülesandeid

    1. Lisa erinevaid kehasid (ka näit kera)!

     

    © Jaak Henno

    Küsimused, probleemid : e-mail