Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

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

Hasonló előadás


Az előadások a következő témára: "Szécsi László 3D Grafikus Rendszerek 4. labor"— Előadás másolata:

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

2 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)

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

4 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();

5 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] )); }

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

7 Skálázni, forgatni kell

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

9 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 = ;

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

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

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

13 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); };

14 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); };

15 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 };

16 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);

17 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); }

18 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);

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

20 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;

21 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(); };

22 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

23 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

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

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

26 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

27 Várt eredmény

28 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

29 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]; } };

30 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]]; };

31 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); };

32 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);

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

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

35 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= , 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

36 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

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

38 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)


Letölteni ppt "Szécsi László 3D Grafikus Rendszerek 4. labor"

Hasonló előadás


Google Hirdetések