3D šiuolaikinėse interneto technologijose

Trimačių vaizdų technologijos neįtikėtinais greičiais skverbiasi į internetą kaip ir daugelis naujovių. Jos pritaikomos kuriant tiek trimačius (toliau – 3D) žaidimus, tiek įvairias animacijas ir vizualizacijas. 3D vizualizacija svarbi ne tradicinėje multimedijoje (animacija ir 3D grafika), bet ir kitur: inžinieriniai sprendimai, architektūra, medicina, geografija ar fantastinių filmų efektai. Patys vizualizacijos metodai vystomi dideliais tempais, nes IT rinkoje pastebimas neslopstantis internetinių programėlių su trimate grafika poreikis. Šiame straipsnelyje trumpai apžvelgsiu 3D grafikos vystymąsi ir paplitimą kuriant tinklalapius ar internetines aplikacijas.

Adobe Flash išstumiamas spartesnių 3D technologijų grafinio procesoriaus lygmenyje

Daugelį metų multimedijos turinys buvo kuriamas pasitelkiant tinklalapiuose įsidominavusią „Adobe Flash“ technologiją. „Adobe Flash“ buvo savotiškai uždara sistema, kuri ne visada laikėsi „W3C“ (angl. World Wide Web Consortium) rekomenduojamų standartų, o norint paleisti „Adobe Flash“ sukurtus interaktyvius vaizdus ir garsus reikėjo naršyklėje įdiegti ir nuolatos atnaujinti tam skirtą priedą (angl. plugin). „Adobe Flash“ buvo skirta dvimatei grafikai kurti, be to, jos pagrindu sukurtos grafikos atsiuntimui reikėjo didelių kompiuterio pajėgumų (gana lėtas grafikos paleidimas), tad jos populiarumas pradėjo stipriai ristis su pasišokinėjimais žemyn. Pastaruoju metu kalbama apie „Adobe Flash“ visišką pasitraukimą iš interneto pasaulio, aišku, kaip animacijų kūrimo įrankis ji dar nemažai gyvuos.

Paskutiniu metu 2D vaizdai piešiami naudojant SVG (angl. Scalable Vector Graphics) ar Javascript valdomu „Canvas“ (tiek „<svg>“, tiek „<canvas>“ yra įtraukti kaip „HTML5“ standarto elementai). 3D atsiradimas glaudžiai susijęs su 2D technologijų vystymusi. Iš esmės juk bet kokio įrenginio ekranas yra dvimatis, tad trimatis vaizdas perkeliamas ir atvaizduojamas („rendering“) kaip dvimatis. Atvaizdavimo metodai pasižymi skirtingu sudėtingumu, perskaičiavimo greičiu ir tikroviškumo kūrimu, pavyzdžiui, itin sudėtingi atspalvių („shaders“) atkūrimo būdai („radiosity“ ar „ray-tracing“) sukuria neįtikėtinai realistiškus 3D vaizdus dvimačiame ekrane. Iš esmės atvaizduojant kiekvieną pikselį realiu momentu grafinis procesorius (GPU – angl. Graphics Processing Unit) atlieka nemažai skaičiavimų: juo labiau kuriant animacijas ekrano taškų spalvos yra perskaičiuojamos kiekvienam kadrui. Iš esmės tarp GPU lygyje veikiančių sąsajų labiausiai paplitusios „Direct3D“ (dažnai naudojama kuriant „Microsoft“ žaidimus) ir OpenGL. Viena iš pastarosios atšakų yra WebGL (angl. Web Graphics Library).

WebGL standarto plitimas

3D grafikos populiarumas kuriant tinklalapius itin glaudžiai susijęs su WebGL technologijos taikymu. WebGL – tai yra aplikacijų programavimo sąsaja (API) Javascript pagrindu, kuri ir sąlygoja trimatės kompiuterinės grafikos interaktyvumą. WebGL ypač išpopuliarėjo dėl vienos svarbios priežasties – ji suteikia galimybę tiesiogiai programuoti grafinį procesorių  tiek grafinę plokštę turinčiuose stacionariuose ar nešiojamuosiuose kompiuteriuose, tiek mobiliuose įrenginiuose. Iš esmės WebGL yra žemesnio lygio sintaksės programavimo kalba, programuojanti grafinį procesorių ir įgalinanti 3D objektų atvaizdavimą naršyklėje. Savaime suprantama, iš žemesnio lygio sintaksės buvo sukurti ir aukštesnio lygio sintaksės programavimo būdai: pavyzdžiui,  „X3D“ ir „THREE.js“ yra aukštesnio lygio sintakse veikiančios bibliotekos (jos ir veikia WebGL pagrindu). Pavyzdžiui, „X3D“ standartas pavaizduoja WebGL objektus naršyklėje be jokių papildomų įskiepių. Tiesa, norint kurti trimatę grafiką su „THREE.js“, būtina prie projekto pridėti „THREE.js“ arba „THREE.min.js“ dokumentą.

2005 m. pradėjęs plisti „X3D“ standartas pakeitė prieš tai egzistavusį „VRML“ (angl. Virtual Reality Modeling Language) standartą. Apie 1995 m. atsiradęs „VRML“ buvo standartinis formatas trimatės vektorinės grafikos elementų atvaizdavimui tinklalapiuose kompiuterio ekrane. „X3D“ yra pirmiausia grįstas sceniniu trimačio pasaulio atvaizdavimu, t. y. sukuriama erdvė arba „scena” (metaforiškai kalbant tarsi analogija teatro scenai, kurioje vyksta veiksmas), būtent scenoje išdėliojami ir judinami (stumdomi ar sukami apie bet kurią ašį) visi trimačiai objektai. Naudojant „X3DOM Javascript“ biblioteką „X3D“ scenos tampa „HTML DOM“ dalimi, tai būtų savotiška analogija „SVG“ formatui dvimačio atvaizdavimo atveju.

3D turinys link kokybės ir kiekybės

Nors vis daugiau džiaugiamasi 3D turiniu naršant, visgi iki šiol neišnaudojamas visos 3D galimybės. Kalbant apie vartotojo įpročius naršant 3D turinį (Evans‘as ir kt. 2014), buvo pastebėta, kad dažniausiai apsiribojama vos keletą veiksmų: tinklalapio veiksmai (nuorodų paspaudimas ar paieška puslapyje) ir 3D užduotys ( navigacija erdvėje arba objektų pasirinkimas). Funkcionalumo, kuris galėtų būti įgyvendinamas, pavyzdžiu galėtų būti skaitytojų mėgstamo tekstinio turinio atvaizdavimas ant trimačių objektų, taip informacijos skaitymas įgytų kitokią atmosferą, o taip pat būtų pritaikoma efektyvesniam ir vaizdingesniam mokymuisi.

Ortiz‘as (2010) išskyrė tokias problemas, kurias reikėtų įveikti, jog 3D išplistų dar labiau: 1) visos naršyklės turėtų turėti 3D įrankius kaip standartinius nustatymus; 2) spartesnis turinio atvaizdavimas; 3) 3D technologijų standartizavimas išvengiant  įvairiausių formatų maišaties; 4) grafinių skaičiavimų perkėlimas iš dažniausiai ne itin spartaus vartotojo įrenginio į serverį. Iš esmės šie reikalavimai vis labiau įgyvendinami: WebGL tampa būtinu daugelio interneto naršyklių elementu kaip ir pačiu pagrindiniu standartu, grafiniai procesoriai tampa vis galingesni. Galiausiai paskutiniu metu kalbama apie nuotolinio atvaizdavimo svarbą, t. y. norima, kad visi sudėtingi grafinio procesoriaus skaičiavimai būtų perkelti iš vartotojo įrenginio į serverį. Vartotojo įrenginiu beliktų atvaizduoti iš serverio gaunamus trimačius vaizdus. Pavyzdžiui, tokio principo atviro kodo įrankio „ParaViewWeb“ skaičiavimus gali pasidalyti ir atlikti keli kompiuteriai (superkompiuteriai).

3D objektų taikymo pavyzdžiai ir naudojimo perspektyvos

Pabaigai norėtųsi pateikti kelis trimačio vaizdavimo pritaikymus. Daugiausia taikymų yra susiję su mokslu. JSMol yra „Javascript“ biblioteka, kuri tinklalapiuose atvaizduoja molekulių ir cheminių junginių 3D modelius (daugiau įdomių pavyzdžių rasite JSMol vikipedijos straipsnyje). Su JSmol sukurtos netgi organinės chemijos reakcijų vizualizacijos. BioJS yra skirta biologinių komponentų interakcijoms kurti (tiesa, nebūtinai 3D).

Vis daugiau atsiranda įrankių 3D grafikos kūrimui („Famous.js“), šalia 3D atvaizdavimo kuriama ir objektų fiziką atkuriančios bibliotekos: „THREE.js“ skirti „Physijs“ ar atskiros „cannon.js“, „microphysics.js“, „JigLibJS“, „Famous.js“.  Pastarosios pasižymi galimybėmis tiek atvaizduoti, tiek pritaikyti fizikos dėsnius atvaizduotiems objektams. Sugalvotas netgi toks „THREE.js“ ir „cannon.js“ pritaikymas kaip objektų jūros gelmėse atkūrimas – „Google Chrome“ eksperimentas „Sea3d Labs“.

Gana įdomi koncepcija yra CityGML (angl. City Geography Markup Language), su kuria planuojama kurti 3D miestų architektūros ir kraštovaizdžio vizualizacijas. Pasinaudojant tokiais vaizdai galima būtų modeliuoti nuo automobilių grūsčių, gyventojų saugumo ar miesto robotų judėjimo situacijų iki projektuojamų namų ir kitus inžinerinių objektų 3D erdvėje. 3D miestų atkūrimu ypač susirūpinę Vokietijos entuziastai.

Jau yra sukurta ir 3D internetinių parduotuvių pavyzdžiai: „Enjoy3D“ ar „Virtway World“. Jose prekės išdėstomos 3D erdvėje, o naudotojas pasirinkęs prekė mato jos kainą ir kitus įprastus atributus. Visinescu ir kt. (2015) tyrimas palygino tokių parduotuvių kognityvinę ir emocinę įtaką pirkėjams ir pastebėjo, kad vis dar vartotojų sąmonė atsilieka nuo tokių inovatyvių sprendimų: pirkėjai daug sunkiau jomis naudojosi (pavyzdžiui, lėčiau orientavosi joje), visgi tokie sunkumai pastebėti tik tarp mažiau įgūdusių vartotojų (IT guru ar įgudusiam paaugliui įtakos neturėjo).

Pradedant nuo mokslinių tyrimų ar medicinos intervencijų iki kasdieninių 3D parduotuvių ar restoranų: virtualus trimatis pasaulis vis labiau įsigalės mūsų įrenginiuose ir tai nebus tiktai filmų su specialiaisiais efektais ar žaidimų prerogatyva kaip buvo dažniausia iki šiol. Grafiniai procesoriai spartėja, internetas greitėja – tai ideali terpė trimačių technologijų atsiradimui šalia mūsų esančiuose mobiliuose telefonuose, o naudotojų patirtį bus galima tyrinėti tik plačiau joms paplitus. Prie straipsnio pateikiu pirmą praktinę kelionę sukuriant 3D modelį savo įrenginio ekrane.

3D planetų sistema: trimatės vizualizacijos kūrimas su „THREE.js“

Pats laikas susipažinti ir išmokti naudotis „THREE.js“, kuri leidžia realizuoti WebGL technologiją. Juo labiau jums nereikės įsigyti ar instaliuoti jokių papildomų programų, pakaks interneto naršyklės, kuri veikia kiekviename kompiuteryje. Šiame straipsnyje pabandysiu žingsnis po žingsnio pamokyti sukurti paprasčiausią saulės sistemos planetų trimatį modelį, kad per praktinį pavyzdį išmokyti tinklalapių 3D dizaino kūrimo pagrindų.

Pirmiausia naršyklėje reikia nustatyti, kad veiktų „THREE.js“ (pavyzdžiui, „Safari“ „Preferences>Advanced>Show Develop menu in menu bar“, o tada atsiradusiame meniu: „Develop>Enable WebGL“). Žinoma, reikia pasirūpinti ir „THREE.js“ karkaso „javascript“ pagrindu arba bibliotekos įskiepiu į jūsų kodą. Vienas būdas yra atsisiųsti ir patalpinti „THREE.js“ biblioteką į pasirinktą aplanką, pagrindiniams poreikiams užtenka minimalios „three.min.js“ versijos. Beje, tame pat puslapyje pateikta ir pačios bibliotekos dokumentacija anglų kalba, t . y. pagrindiniai patarimai, kaip naudotis „THREE.js“ kodu.  Dažniausia tokiam kodui sukuriamas aplankas pavadinimu „js“, ir jo viduje patalpinama atsisiųsta biblioteka.

Pridedu paprasčiausią HTML kodą, kuris padės naršyklės lange vėliau patalpinti kodą
(„javascript“ kodą), kurios atvaizduoja trimačius objektus. Tam sukuriamas naujas dokumentas „.txt“ (pavyzdžiui, „Windows Operacinėje Sistemoje“ su „Notepad“, o „Mac OS X“ su „TextEdit“ redaktoriais), kurį išsaugant „.txt“ galūnė pakeičiama „.html“:

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Planetos Juda</title>
        <style>
            body {
                margin: 0;
                padding: 0;
                width: 100%;
                height: 100%
            }
            canvas {
                width: 100%;
                height: 100%
            }
        </style>
    </head>
    <body>
    <script src="js/three.min.js" type="text/javascript"></script>
        <script type="text/javascript"> 
        	// Šioje vietoje bus rašomas tolesnis kodas!
        </script>
    </body>
</html>

Pastaba: šito kodo kaimynystėje turi būti sukurtas „js“ aplankas su minėta biblioteka (jie turi būti tame pačiame kataloge arba ant darbalaukio).

Toliau kursime paprasčiausią planetų sistemą. Kodas bus rašomas pažymėtoje vietoje su tekstu „Šioje vietoje bus rašomas tolesnis kodas!“.

Kiekvienai 3D scenai yra būtini tam tikri elementai, t. y. scena, kurioje bus vaizduojami mūsų objektai, kamera (per kurią žiūrėsime) ir vaizduotojas („renderer“). Iš tiesų daugelis terminų yra plačiai vartojami tarp 3D grafikų ir dizainerių. „THREE.js“ terminija atkartoja, pavyzdžiui, 3dsMax terminiją.

Pridedame minėtus elementus:

var camera, scene, renderer;

Kabliataškiu pabaigiamas kiekvienas sakinys, kaip ir įprastinėje kalboje kiekvienas sakinys pabaigiamas tašku (toks jau susitarimas). Toliau belieka aprašyti šių elementų parametrus („inicijuoti“), juos mes įdedame į tam tikrą kodo dalį (metodą) „init“:

function init() {
    renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 240;
    scene = new THREE.Scene();
}

Kameros pozicija nulems, kokio dydžio vaizdas bus matomas, todėl rekomenduotina pažaisti su „camera.position.z“ skaitine verte (aptariamu atveju pasirinkta „240“). Paprastai su „THREE.js“ naudojami dviejų tipų vaizdų interpretatoriai („renderer“): „WebGLRenderer“ arba „CanvasRenderer“. Šiuo atveju pasirinktas „WebGLRenderer“, kuris yra labiau 3D skirta technologija, o ne tiesiog patobulinta iki 3D galimybių kaip „CanvasRenderer“. Atitinkamai ir funkcionalumas pirmojo interpretatoriaus daug platesnis, nors ir sudėtingesnis, visgi tai ateities technologija, kuri leis išgauti įspūdingus 3D vaizdus. Kameros taip pat naudojamos įvairių rūšių, tačiau populiariausia yra „PerspectiveCamera“.

Pridedame saulę, Merkurijų, Venerą, Žemę ir Marsą:

var sun, mercury, venus, earth, mars;

Toliau pabandome pasirašyti saulės sukūrimo kodą (metodą):

function initSun() {
    var sunGeo = new THREE.SphereGeometry(12, 35, 35);
    var sunMat = new THREE.MeshPhongMaterial({
        color: 0xF7FE2E
    });
    sun = new THREE.Mesh(sunGeo, sunMat);
    sun.position.set(0, 0, 0);
    scene.add(sun);
}

Kurdami saulę, sukūrėme jos geometrinę formą (THREE.SphereGeometry), jos padengimą („material“) geltona spalva (THREE.MeshPhongMaterial({color: 0xF7FE2E})). Toliau panašiai pasirašome bendrą planetų sukūrimo metodą:

function initPlanet(r, vs, hs) {
    var planetGeo = new THREE.SphereGeometry(r, vs, hs);
    var planetMat = new THREE.MeshPhongMaterial({
        color: Math.random() * 0xFFFFFF
    });
    var planet = new THREE.Mesh(planetGeo, planetMat);
    scene.add(planet);
    return planet;
}

Skirtingos planetos turės skirtingus parametrus: r – planetos spindulys, vs – vertikalių segmentų skaičius, hs – horizontalių fragmentų skaičius. Metodas sukuria ir grąžina planetos modelį (tas pasiekiama pridedant sakinį, kuris turi raktažodį „return“ – metodų naudojimas kaip ir įprasto „javascript“ kodo rašymo atveju). Planetoms galima priskirti atsitikitinę spalvą, beje, jeigu spalvos laukelį paliktume neužpildytą, tai turėtume visas planetas baltas. Toliau belieka sukurti visas konkrečias planetas išlaikant tikrąsias proporcijas (tas pats metodas, kurį prieš tai apsirašėme, taikomas visoms planetoms kurti):

mercury = initPlanet (2, 15, 15);
venus = initPlanet (5, 22, 22);
earth = initPlanet (6, 22, 22);
mars = initPlanet (4, 22, 22);

Žinoma, atitinkamai sukuriame ir mūsų žvaigždę:

sun = initSun();

Kol kas sukūrėme keturias arčiausiai saulės esančias planetas. Taip pat reikėtų pridėti šviesos šaltinį, kad apšviestų saulę geltonai. Tą galima patalpinti „init“ metodo viduje:

var sunLight = new THREE.PointLight( 0xffffff, 1);
sunLight.position.set( 12,35,35 );
scene.add( sunLight );

Na, ir beliko suanimuoti, kad saulės sistemoje būtų tikra – planetos suktųsi ir  judėtų aplink centre esančią žvaigždę. Pritaikome tam apskritimo trigonometrines funkcijas, pasirašome dėl patogumo bendrą metodą planetų judėjimui aprašyti (kadangi turime net keturias planetas, tai taip bus daug patogiau negu rašant atskirus metodus kiekvienai planetai atskirai):

function movePlanet(planet, s, k) {
    planet.rotation.y += 0.03;
    planet.position.x = s * Math.cos(k * t) + 0;
    planet.position.y = s * Math.sin(k * t) + 0;
}

Šiame metode naudojame tokius kinatmuosius (parametrus): s – kokiu atstumu nuo saulės judės arba kokio dydžio apskritimu skries planetos; k – parametras naudojamas tam, kad planetos nepradėtų judėti nuo to paties taško (taip atrodys labai nenatūraliai). Planetos skrenda skirtingomis trajektorijomis (skirtingo dydžio apskritimais) ir skirtingu greičiu.

Galiausiai, apibrėžus laiko momentą (t), viską patalpiname „render“ metode, kartais kituose šaltiniuose jis standartiškai vadinamas „animate“, tačiau pavadinimas reikšmės neturi – svarbu, kad būtų metodas, kuris animuoja, o tai atlieka „render“ metodas:

var t = 0; //laiko momentas
function render(s) { 
    requestAnimationFrame(render); 
    t += 0.01; 
    movePlanet(mercury, 20, 3.8);
    movePlanet(venus, 50, 3);
    movePlanet(earth, 75, 2.3);
    movePlanet(mars, 100, 0.7);     
    renderer.render(scene, camera); 
} 

Savaime suprantama, kad taikydami „movePlanet“ metodą panaudojome skirtingų planetų judėjimo parametrus kiekvienai iš jų. Beje, laiko momento panaudojimas nėra būtinas animavimo metodo „render“ elementas, mes jį tiesiog įtraukėme, kad galėtume priversti planetas tvarkingai suktis. Aišku, galima panaudoti dar priversti ir saulę suktis aplink savo ašį su kodo eilute „sun.rotation.z+=0.01“. Beliko, iškviesti  metodus „init“ ir „render“, nes kiekvienas metodas turi būti iškviestas, jog būtų į jį kreipiamasi (kai kūrėme planetas ir saulę, kreipėmės į planetų ir saulės sukūrimo metodus):

render ();

Taigi, pridėjus ir paleidus visus metodus turėtume išvysti tokį vaizdą savo naršyklėje:

Saulės planetų sistema, sukurta su „THREE.js“.

Saulės planetų sistema, sukurta su „THREE.js“.

Taigi, šio praktinio supažindinimo pabaigai pridedu visą kodą, kurį galima tobulinti pridedant daugiau planetų, daugiau splavų ar kitų funkcionalumų, kurie pateikti mano minėtoje nurodoje į „THREE.js“ dokumentaciją. JSBin galite peržiūrėti mano sukurtą versiją.

Tiesa, dar pridėjau metodą „onWindowResize“  ir jo iškvietimą: „window.addEventListener( ‘resize’, onWindowResize, false );“, kuris leidžia išlaikyti mūsų animacijos proporcijas keičiant lango naršyklės dydį – jisai nėra būtinas sukurtos interakcijos veikimo elementas. Smagios ir vasariškos jums vizualizacijos su „THREE.js“!

Daugiau informacijos

  1. Evans, A., Romeo, M., Bahrehmand, A., Agenjo, J. ir J. Blat (2014) 3D graphics on the web: A survey. Computers & Graphics, 41: p. 43–61.
  2. Ortiz Jr., S. (2010) Is 3D finally ready for the web? Computer, 43: p. 14–16
  3. Visinescu, L. L., Sidorova, A., Jones, M. C. ir V. R. Prybutok (2015) The influence of website dimensionality on customer experiences, perceptions and behavioral intentions: An exploration of 2D vs. 3D web design. Information & Management, 52 (1): p. 1-17