Szécsi László 3D Grafikus Rendszerek 4. labor

Slides:



Advertisements
Hasonló előadás
Bevezetés a C# nyelvbe Az alapok összefoglalása Farkas Csaba.
Advertisements

A kifizetési kérelem összeállítása TÁMOP-3.2.9/B-08 Audiovizuális emlékgyűjtés.
MI A SEO? KÜLSŐS SEO CÉG VAGY SAJÁT SZAKEMBER? MIKOR MELYIKET VÁLASSZAM, ELŐNYÖK/HÁTRÁNYOK Horváth Ernő – WebSEO Kft
1 Niche Tárgya a fajok koegzisztenciájának problémája A fogalom fejlődése: Grinnell – térbeli Elton – funkcionális Hutchinson – hipertérfogat modell Juhász-Nagy.
avagy a háromszög technika
Gazdasági informatika - bevezető
Egészség, baleset-megelőzés és környezet
Geometriai transzformációk
3D grafika összefoglalás
Frekvencia függvényében változó jellemzők mérése
Becslés gyakorlat november 3.
Beck Róbert Fizikus PhD hallgató
Scilab programozás alapjai
Programozás III. Gyakorlás.
PHP - függvények.
A Menedék Alapítvány ÉRTÉKEI
RÁDIÓRENDSZEREK Képi jelek Győr.
Vizualizáció és képszintézis
Korrelációszámítás.
Ez az én művem Készítsünk tájképet! Készítette: Puskás Rebeka
Végeselemes modellezés matematikai alapjai
GUI.
Mikrovezérlők alkalmazástechnikája laboratóriumi gyakorlat
Szécsi László 3D Grafikus Rendszerek 1. labor
Programozás III. Ismétlés (Grafikai lehetőségek WPF-ben)
Animációk.
Vizualizáció és képszintézis
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
VB ADATTÍPUSOK.
Kamera, 3D, transzformációk Szécsi László
Material+ kioptimalizált uniformok
Grosz imre f. doc. Kombinációs hálózatok /43 kép
Számítógépes Hálózatok
OpenGL kiterjesztések (extensions)
3. A robot képernyőmenüje
A Dunához kapcsolódó lehetőségek Budapest közlekedésfejlesztésében
Tilk Bence Konzulens: Dr. Horváth Gábor
Ghost Hunter Game logic/HUD.
A Box-Jenkins féle modellek
Elektronikai Áramkörök Tervezése és Megvalósítása
AVL fák.
Informatikai gyakorlatok 11. évfolyam
B M Java Programozás 4. Gy: Java GUI IT A N Tipper, MVC kalkulátor
1.1. FOGYASZTÓI DÖNTÉS B fogyasztó A fogyasztó
Új pályainformációs eszközök - filmek
Fényforrások 3. Kisülőlámpák
3. előadás.
A Microsoft SharePoint testreszabása Online webhely
Weöres Sándor kombinatorikus versei
B M Java Programozás 9. Gy: Java alapok IT A N Adatkezelő 5.rész
Matematikai Analízis elemei
Mesh from file, OrthoCamera, PerspectiveCamera
Vasbeton falvasalás megadása és ellenőrzése EC2 szerint
A szállítási probléma.
I. HELYZETFELMÉRÉSI SZINT FOLYAMATA 3. FEJLESZTÉSI FÁZIS 10. előadás
Matematika 11.évf. 1-2.alkalom
Erasmus+ hallgatói mobilitásra jelentkezéshez
Műveletek, függvények és tulajdonságaik Mátrix struktúrák:
Mikro- és makroökonómia
Tájékoztató az EPER pályázati folyamatáról
3. előadás.
Szöveges adatok tárolása
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Bevezetés Tematika Számonkérés Irodalom
Erasmus+ hallgatói mobilitásra jelentkezéshez
Várhatóérték, szórás
OpenBoard Kezelő Tananyag közzététele a KRÉTA rendszerben.
Atomok kvantumelmélete
Oféliák színháza.
Összevont munkaközösség vezetői és igazgatótanácsi értekezlet
Előadás másolata:

Szécsi László 3D Grafikus Rendszerek 4. labor

Geometria JSON-ból IndexedTrianglesGeometry.js a QuadGeometry.js mintájára a konstruktor kapjon egy mesh-leíró objektumot (ahogy az a JSON fileból jön) azért nem a filenevet adjuk át, mert egy fileban több mesh lehet vertices tulajdonság: 3n db koordináta folyotonos tömbben normals tulajdonság: 3n db érték folyotonos tömbben texturecoords tulajdonság: 2n db értéket tartalmazó folyotonos tömbök tömbje (de tipikusan csak egy textúrakoordináta-készlet van) faces tulajdonság: 3 indexet tartalmazó tömböcskék tömbje egy folytonos tömböt lehet belőle gyártani így: [].concat.apply([], jsonObject.faces)

Index buffer az indexek száma nem fix a konstruktorban el kell tárolni tulajdonságként rajzoláskor fel lehet használni

MultiMesh.js - betöltés var MultiMesh = function( gl, jsonModelFileUrl, materials) { this.meshes = []; var request = new XMLHttpRequest(); request.open("GET", jsonModelFileUrl); var theMultiMesh = this; request.onreadystatechange = function () { // next slide }; request.send();

MultiMesh.js – betöltés után if (request.readyState == 4) { var meshesJson = JSON.parse(request.responseText).meshes; for (var i = 0; i < meshesJson.length; i++) { theMultiMesh.meshes.push( new Mesh( new IndexedTrianglesGeometry(gl, meshesJson[i]), materials[i] )); }

MultiMesh.js – rajzolás MultiMesh.prototype.draw = function(gl){ for (var i = 0; i < this.meshes.length; i++) { this.meshes[i].draw(gl); } };

Skálázni, forgatni kell

3D kamera PerspectiveCamera object must set view, projection matrices moveable by mouse and WASD keys

Kamera paraméterek var PerspectiveCamera = function() { this.position = new Vec3(0.0, 0.0, 0.0); this.ahead = new Vec3(0.0, 0.0, -1.0); this.right = new Vec3(1.0, 0.0, 0.0); this.up = new Vec3(0.0, 1.0, 0.0); this.yaw = 0.0; this.pitch = 0.0; this.fov = 1.0; this.aspect = 1.0; this.nearPlane = 0.1; this.farPlane = 1000.0;

Tagváltozók mozgatáshoz this.speed = 0.5; this.isDragging = false; this.mouseDelta = new Vec2(0.0, 0.0);

Mátrixok this.viewMatrix = new Mat4(); this.projMatrix = new Mat4(); this.rayDirMatrix = new Mat4(); this.viewProjMatrix = new Mat4(); this.updateViewMatrix(); this.updateProjMatrix(); this.updateRayDirMatrix(); };

Világ felfelé iránya PerspectiveCamera.worldUp = new Vec3(0, 1, 0);

View mátrix számítása PerspectiveCamera.prototype.updateViewMatrix = function(){ this.viewMatrix.set( this.right.x , this.right.y , this.right.z , 0, this.up.x , this.up.y , this.up.z , 0, -this.ahead.x , -this.ahead.y , -this.ahead.z , 0, 0 , 0 , 0 , 1).translate(this.position).invert(); this.viewProjMatrix.set(this.viewMatrix).mul(this.projMatrix); };

Proj mátrix számítása PerspectiveCamera.prototype.updateProjMatrix = function() { var yScale = 1.0 / Math.tan(this.fov * 0.5); var xScale = yScale / this.aspect; var f = this.farPlane; var n = this.nearPlane; this.projMatrix.set( xScale , 0 , 0 , 0, 0 , yScale , 0 , 0, 0 , 0 , (n+f)/(n-f) , -1, 0 , 0 ,2*n*f/(n-f), 0); this.viewProjMatrix.set(this.viewMatrix). mul(this.projMatrix); };

RayDir mátrix számítása PerspectiveCamera.prototype.updateRayDirMatrix = function(){ // önállóan megoldandó feladat // de ráér // az env mapping háttérhez kell csak };

Mozgatás: yaw, pitch drag PerspectiveCamera.prototype.move = function(dt, keysPressed) { if(this.isDragging){ this.yaw -= this.mouseDelta.x * 0.002; this.pitch -= this.mouseDelta.y * 0.002; if(this.pitch > 3.14/2.0) { this.pitch = 3.14/2.0; } if(this.pitch < -3.14/2.0) { this.pitch = -3.14/2.0; this.mouseDelta = new Vec2(0.0, 0.0);

Mozgatás: főirányok a szögekből this.ahead = new Vec3( -Math.sin(this.yaw)*Math.cos(this.pitch), Math.sin(this.pitch), -Math.cos(this.yaw)*Math.cos(this.pitch) ); this.right.setVectorProduct( this.ahead, PerspectiveCamera.worldUp ); this.right.normalize(); this.up.setVectorProduct(this.right, this.ahead); }

Mozgatás gombokkal if(keysPressed.W) { this.position.addScaled(this.speed * dt, this.ahead); } if(keysPressed.S) { this.position.addScaled(-this.speed * dt, this.ahead); if(keysPressed.D) { this.position.addScaled(this.speed * dt, this.right); if(keysPressed.A) { this.position.addScaled(-this.speed * dt, this.right); if(keysPressed.E) { this.position.addScaled(this.speed * dt, PerspectiveCamera.worldUp); if(keysPressed.Q) { this.position.addScaled(-this.speed * dt, PerspectiveCamera.worldUp);

Mátrixok frissítése this.updateViewMatrix(); this.updateRayDirMatrix(); };

Eseménykezelők – meg is kell hívni őket! PerspectiveCamera.prototype.mouseDown = function() { this.isDragging = true; this.mouseDelta.set(); }; PerspectiveCamera.prototype.mouseMove = function(event) { this.mouseDelta.x += event.movementX; this.mouseDelta.y += event.movementY; event.preventDefault(); PerspectiveCamera.prototype.mouseUp = function() { this.isDragging = false;

Képméretarány állítása – ezt is meg kell hívni! // ar: canvas.clientWidth / canvas.clientHeight PerspectiveCamera.prototype.setAspectRatio = function(ar) { this.aspect = ar; this.updateProjMatrix(); };

Rakjuk össze! ortho kamera lecserélése mélységteszt bekapcsolása eseményfigyelők bekötése GameObject2D jó lehet még de figyeljünk rá, hogy a modelViewProjMatrix beállítása rajzoláshoz összhangban legyen a PerspectiveCamera tulajdonságaival GameObject3D csak a forgatásban térne el

3D transzformáló vertex shader kell neki a modelViewProjMatrix továbbra is de kell egy modelMatrix uniform is nincs benne a kameratrafó modellből világkoordintákba transzformál új varying kimenet: worldPos és még kell egy modelMatrixInverse uniform a normálvektorok transzformálásához ezt most bal oldalról szorozzuk, mert az inverz transzponálttal kell a normálvektort transzformálni új varying kimenet: worldNormal

Fragment shader a 3D trafó ellenőrzéséhez rajzoljuk ki a worldNormal-t színként

Várt eredmény abs(normal)-lal

Egyszerű árnyaló FS legyen egy fényirány-vektor normálvektor és fényirány közötti szög koszinusza az irradiancia texúrából olvasott színt moduláljuk ezzel

Várt eredmény

Environment mapping doboztextúra betöltése új FS ami kiszámolja az ideális visszaverődési irányt és kiolvassa a textúrát

TextureCube.js - betöltés var TextureCube = function(gl, mediaFileUrls) { pendingResources[mediaFileUrls[0]] = ++pendingResources[mediaFileUrls[0]] || 1; this.mediaFileUrls = mediaFileUrls; this.glTexture = gl.createTexture(); this.loadedCount = 0; this.images = []; var theTexture = this; for(var i=0; i<6; i++){ this.images[i] = new Image(); this.images[i].onload = function() { theTexture.loaded(gl); } this.images[i].src = mediaFileUrls[i]; } };

TextureCube.js – erőforrás létrehozása TextureCube.prototype.loaded = function(gl){ this.loadedCount++; if(this.loadedCount < 6) return; gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture); for(var i=0; i<6; i++){ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.images[i]); } gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); gl.generateMipmap(gl.TEXTURE_CUBE_MAP); gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); if( --pendingResources[this.mediaFileUrls[0]] === 0 ) { delete pendingResources[this.mediaFileUrls[0]]; };

Ez nem kell, ha van reflection // akkor kéne, ha direktben akarnánk rákötni egy Sampler2D // uniformra. Ha van Material-unk reflectionnel, akkor // a WebGLMath Sampler2D objektuma ezt intézi TextureCube.prototype.commit = function(gl, uniformLocation, textureUnit){ gl.uniform1i(uniformLocation, textureUnit); gl.activeTexture(gl.TEXTURE0 + textureUnit); gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture); };

Tükröző objektum létrehozása fragment shader gyártsuk le a TextureCube-ot, kössük be a fenti FS-t használó Material-ba, a GameObject használja ezt az anyagot // kell egy sampler uniform uniform samplerCube envmapTexture; // kiolvasni a tükörirányban textureCube( envmapTexture, reflect(-viewDir, normal)) this.skyCubeTexture = new TextureCube(gl, [ "media/posx512.jpg", "media/negx512.jpg", "media/posy512.jpg", "media/negy512.jpg", "media/posz512.jpg", "media/negz512.jpg",] ); this.slowpokeMaterial0. envmapTexture.set ( this.skyCubeTexture);

Várt eredmény higany pokemon visszaveri a környezetét de maga a környezet nem látszik

Sugárirány kiszámítása NDC-ből extra (EVP)-1 -et nevezzük rayDirMatrix-nak

Környezet megjelenítése háttérként extra teljes képernyős téglalapot kell rajzolni (hurrá!) új VS: kiszámolja a sugárirányt át kell adni a képernyőkoordinátából-világkoordináta- mínusz-szempozíció-számító mátrixot (a.k.a. rayDirMatrix) a kamera ezt kiszámolja nem transzformál (mert full viewport quad) z=0.99999, minden mőgé FS megkapja a VS-től varying-ben a sugárirányt ezzel címzi a textúrát visszaadja a kapott színt

Ne felejtsük el a GameObject adja át a rayDirMatrix-ot extra Ne felejtsük el a GameObject adja át a rayDirMatrix-ot az új shadereket vegyük be az index.HTML-be gyártsuk le szükséges shader, program, material objektumokat ugyanazt a doboztextúrát kössük be a háttér anyagába, mint amit a tükröző objektuméba legyen quadGeometry legyen egy mesh a quadGeometry és a fenti material használatával legyen egy gameObject a mesh-sel

extra Várt eredmény tükröző objektum és háttér

Házi feladat válasszon egyet az alábbiak közül: Phong-Blinn + diffúz árnyalás objektum körül keringő pontfényforrás 3D-ben forgó, ütköző objektumok ütközőgeometria: két gömb per objektum procedurális normal mapping zajfüggvény: random (de fix) irányok mentén koszinuszok összege normálvektor perturbációja zajfüggvény gradiensével env mappinggel kombinálva (háttér is kell)