Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Material+ kioptimalizált uniformok
Szécsi László 3D Grafikus Rendszerek hack
2
Használatlan uniformok
kioptimalizálva nem jelenik meg a reflectionben hibát okoz, pedig gyakran csak tesztelés miatt hagyunk ki valamit legyen csak warning
3
Közös uniformok – hozzuk létre előre
Material.shared = { // csak példa modelMatrix : new Mat4(), modelMatrixInverse : new Mat4(), modelViewProjMatrix : new Mat4(), rayDirMatrix : new Mat4(), eyePos : new Vec3(), texOffset : new Vec2(), }; // Lehet ennél kifinomultabb megoldást is alkalmazni // ahol nem kell megismételni JS-ben a uniform típusát. // De a közös uniform úgyis több shaderben is megjelenhet, // ahol a típusoknak azonosnak kell lennie. // Így a legegyszerűbb.
4
Material uniformok – csak warning legyen a hiányzó tulajdonság, ne hiba
// Material konstruktor végén return new Proxy(this, { get : function(target, name){ if(!(name in target)){ console.error( "WARNING: Ignoring attempt" + " to access material property '" + name + "'. Is '" + name + "' an unused uniform?" ); return Material.dummy; } return target[name]; }, });
5
Dummy objektum //bármely függvényhívás vagy tulajdonságelérés //megengedett, de hatástalan Material.dummy = new Proxy(new Function(), { get: function(target, name){ return Material.dummy; }, apply: function(target, thisArg, args){ });
6
Szintfelület sugárkövetése
Szécsi László 3D Grafikus Rendszerek 4. labor
7
Környezet megjelenítése háttérként
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
8
Sugárirány kiszámítása NDC-ből
(EVP)-1 -et nevezzük rayDirMatrix-nak
9
TextureCube.js - betöltés
var TextureCube = function(gl, mediaFileUrls) { gl.pendingResources[mediaFileUrls[0]] = ++gl.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]; } };
10
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( --gl.pendingResources[this.mediaFileUrls[0]] === 0 ) { delete gl.pendingResources[this.mediaFileUrls[0]]; };
11
Háttér 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 sugárirányban textureCube( envMapTexture, rayDir) this.skyCubeTexture = new TextureCube(gl, [ "media/posx512.jpg", "media/negx512.jpg", "media/posy512.jpg", "media/negy512.jpg", "media/posz512.jpg", "media/negz512.jpg",] ); this.backgroundMaterial. envMapTexture.set ( this.skyCubeTexture);
12
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 a doboztextúrát kössük be a háttér anyagába legyen quadGeometry legyen egy mesh a quadGeometry és a fenti material használatával legyen egy gameObject a mesh-sel
13
Várt eredmény – egér forgat
14
Terep textúrából uniform sampler2D noiseTexture; float f(vec3 p){ return texture2D(noiseTexture, p.xz * 0.01).r - p.y; } freki y = 0 sík implicit egyenlete, ehhez keverjük a 2D zajt terep implicit függvénye
15
Kilépési, belépési pont
uniform vec3 eye; varying vec3 rayDir; uniform samplerCube background; void main(void) { vec3 d = normalize(rayDir); float t1 = (1.0 - eye.y) / d.y; float t2 = (0.0 - eye.y) / d.y; float tstar = max(min(t1, t2), 0.0); float tend = max(max(t1, t2), 0.0);
16
Ray marching vec3 p = eye + d * tstar; vec3 step = d * min((tend - tstar)/128.0, 0.05); //feladat: // ciklus fut 128-szor // p léptetése step-pel // ha elértük a felületet, break
17
Magasság szerinti árnyalás
ha az utolsó tesztnél még nem értük el a felületet, akkor adjuk vissza a háttérszínt különben p.y-t
18
Várt eredmény
19
Normálvektor megjelenítése
vec3 gradient = vec3( f(p + vec3(+0.05, 0.0, 0.0) ) - f(p + vec3(-0.05, 0.0, 0.0) ) , f(p + vec3(0.0, +0.05, 0.0) ) - f(p + vec3(0.0, -0.05, 0.0) ) , f(p + vec3(0.0, 0.0, +0.05) ) - f(p + vec3(0.0, 0.0, -0.05) ) ); //normalizáljuk, adjuk vissza, mint színt
20
Várt eredmény
21
Változó lépéshossz ray marchingban minden ciklusban növeljük a lépést 2%-kal kezdeti lépés nem a teljes táv 128-ada, hanem 580- ada (geometriai sor)
22
Várt eredmény
23
Bináris keresés ray marching ciklus után, ha volt metszés, az eredmény pontosítása pozíció visszállítása fél lépéssel ciklusban lépés felezése előre vagy hátralépés attól függően, hogy a felület alatt vagy felett vagyunk-e
24
Várt eredmény
25
Cseréljük le az implicit függvényt 3D zajra
nem magasságmező, lesznek hidak is normálvektor analitikusan számolható
26
Egyszerű zaj freki float f(vec3 r) { vec3 s = vec3(7502, 22777, 4767); float w = 0.0; for(int i=0; i<16; i++) { w += sin( dot(s - vec3(32768, 32768, 32768), r * 40.0) / ); s = mod(s, ) * floor(s / ); } return w / r.y; y = 0 sík implicit egyenlete, ehhez keverjük a 3D zajt
27
Egyszerű zaj gradiense
vec3 fGrad(vec3 r) { vec3 s = vec3(7502, 22777, 4767); vec3 w = vec3(0.0, 0.0, 0.0); for(int i=0; i<16; i++) { w += cos( dot(s - vec3(32768, 32768, 32768), r*40.0) / ) * (s - vec3(32768, 32768, 32768)) * 40.0; s = mod(s, ) * floor(s / ); } return w / vec3(0, 1, 0);
28
Várt eredmény
29
Köd elnyelődés csillapítás kiszóródás kibocsájtás forráshatás
radiancia változása beszóródás csillapítási tényező forrástag egység hosszon a sugár mentén radiancia épp itt
30
Diffegyenlet megoldása
elveszett százalék radiancia a sugár-felület metszéspontban radiance a sugár keződponjában, a metszésponttól távolságra összeszedett többletradiancia
31
Feladat: köd válasszunk csillapítást és forrástagot, tudjuk ezeket könnyen változtatni ergo érdemes ezekre változót gyártani lehet skalár, vagy RGB, ha színes a köd a fenti képletet értékeljük ki a FS végefelé a háttér végtelen messze legyen
32
Várt eredmény nulla forráshatás, fekete köd
33
Várt eredmény színes köd, nem látszik a háttér (nyilván)
34
Nem-konstans köd lejjebb sűrűbb, feljebb ritkább, exponenciálisan
extra Nem-konstans köd lejjebb sűrűbb, feljebb ritkább, exponenciálisan y a sugáron
35
Diffegyenlet megoldás
extra Diffegyenlet megoldás
36
extra Várt eredmény
37
Házi feladat metaball ray marching
implicit függvény mozgóközéppontú radiális bázisfüggvények összege ebben keressük a szintfelületet
38
Várt eredmény kb.
39
Metaball implicit egyenlet általában
f t -A
40
2 metaball: A szintérték hatása
41
Lehetséges metaball-súlyfüggvények
Blinn Perlin Wyvill f r ha r > 1, akkor 0 ha r > 1, akkor 0
42
Ray marching f t
43
Házihoz legyen Phong BRDF vagy env mapping legalább 3 labda legyen
animálódjanak a labdák középpontjai Blinn bázisfüggvény teljesen elég a többi akkor hasznos ha véges tartójú kell, hogy a távoliakat ne kelljen hozzáadni Gradiens számítása analitikusan nem differenciákkal közelítve
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.