2D képszintézis Szirmay-Kalos László
2D képszintézis Modell szín (200, 200) Kép Kamera ablak (window) viewport Unit=pixel Saját színnel rajzolás Világ koordinátarendszer
Pixel vezérelt megközelítés: Tartalmazás (objektum, pont) Határ implicit görbe: Határ parametrikus görbe: kívül belül > 0 : egyik oldalon f(x, y) = 0 : határon < 0 : másik oldalon 3 2 1 határ végtelen kívül van!
Objektum vezérelt megközelítés: 2D megjelenítési csővezeték Referencia helyzet (modellezési koord) Világ vektorizáció Modell Transzf. ablak Képernyő v. appwindow (1,1) nézet nézet Vágás + nézet transzf. Kamera transzformáció raszterizáció (-1,-1) Normalizált eszköz Képernyő
Objektum vezérelt megközelítés: Referencia helyzet (modellezési koord) (-1,-1) Normalizált eszköz 2D megjelenítési csővezeték CPU program C++ vektorizáció Modell Transzf. Képernyő v. appwindow Világ (1,1) nézet nézet Vágás + nézet transzf. GPU Fixed pipeline GPU VAO-k Képernyő Kamera transzformáció raszterizáció GPU Vertex shader GLSL ablak GPU Fragment Shader GLSL GPU Frame buffer
r(t), t in [0,1] Vektorizáció r 0 r 1 r n [0,1]: t 0 = 0, t 1 = 1/n,..., t n =1 r 0 =r(t 0 ), r 1 = r(t 0 ),, r n = r(t n )
Poligon háromszögekre bontása Konvex Konkáv Nem-diagonál diagonál Tétel: Minden 4+ csúcsú egyszerű sokszögnek van diagonálja, azaz mindegyik felbontható diagonálok mentén. Konvex csúcs
p i-1 Fül diagonál p i p i fül, ha p i-1 p i+1 diagonál Fül levágható! Fülvágás: keress fület és nyissz! p i+1 Két fül tétel: Minden legalább 4 csúcsú egyszerű sokszögnek van legalább 2 füle. Minden fának van legalább két levele.
Fülvágó algoritmus 1 43 0 2 3 Szakasz-szakasz metszés: x 1 (t 1 )=x 11 t 1 +x 12 (1-t 1 ) y 1 (t 1 )=y 11 t 1 +y 12 (1-t 1 ), t 1 (0,1) x 2 (t 2 )=x 21 t 2 +x 22 (1-t 2 ) y 2 (t 2 )=y 21 t 2 +y 22 (1-t 2 ), t 2 (0,1) x 1 (t 1 )= x 2 (t 2 )? t y 1 (t 1 )= y 2 (t 2 ) 1,t 2 (0,1)
Modellezési transzformáció S x 0 0 cos f sin f 0 1 0 0 [x w, y w, 1] = [x m, y m, 1] 0 S y 0 0 0 1 -sin f cos f 0 0 0 1 0 1 0 p x p y 1 (x m, y m ) j (x w, y w ) i o (x w, y w ) = o + x m i + y m j
Mátrixok: mat4 struct mat4 { // row-major matrix 4x4 float m[4][4]; }; mat4(float m00, float m01, float m02, float m03, ) { } mat4 operator*(const mat4& right) const { } inline vec4 operator*(const vec4& v, const mat4& m) { } inline mat4 TranslateMatrix(vec2 t) { return mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, 0, 1); } inline mat4 ScaleMatrix(vec2 s) { } inline mat4 RotationMatrix(float angle) { return mat4( cosf(angle), sinf(angle), 0, 0, -sinf(angle), cosf(angle), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
View transzformáció: V() kameraablak közepe az origóba világ w x w x (x w, y w ) (c x,c y ) w y x v = x w -c x y v = y w -c y (x v, y v ) w y ablak ablak 1 0 0 [x v, y v, 1] = [x w, y w, 1] 0 1 0 -c x -c y 1
Projekció: P() kameraablak a (-1, -1)-(1, 1) négyzetbe w x (x v, y v ) w y x c = x v * 2/w x y c = y v * 2/w y Normalizált eszköz (1,1) (x c,y c ) ablak (-1,-1) 2/w x 0 0 [x c, y c, 1] = [x v, y v, 1] 0 2/w y 0 0 0 1
2D kamera class Camera2D { vec2 wcenter;// center in world coords vec2 wsize; // width and height in world coords public: mat4 V() { return TranslateMatrix(-wCenter); } }; mat4 P() { // projection matrix: return ScaleMatrix(vec2(2/wSize.x, 2/wSize.y)); } mat4 Vinv() { return TranslateMatrix(wCenter); } mat4 Pinv() { // inverse projection matrix return ScaleMatrix(vec2(wSize.x/2, wsize.y/2)); } void Zoom(float s) { wsize = wsize * s; } void Pan(vec2 t) { wcenter = wcenter + t; }
Pont vágás: Vágás x > x min = -1 x < x max = +1 y > y min = -1 y < y max = +1 y max (x, y) x max Belül x min y min Kívül
Vágás x > x min x min (x, y) Kívül Belül
Vágás y > y min Belül (x, y) y min Kívül
Vágás x < x max x max (x, y) Belül Kívül
Vágás Kívül y < y max Belül (x, y)
Szakasz vágás: x < x max x 1, y 1 x max x 1, y x 1 2, y 2 x i, y i x 1, y 1 x 2, y 2 x 2, y 2 x(t) = x 1 + (x 2 - x 1 )t, y(t) = y 1 + (y 2 - y 1 )t x = x max Metszés: x max = x 1 + (x 2 - x 1 )t t = (x max -x 1 )/(x 2 -x 1 ) x i = x max y i = y 1 + (y 2 - y 1 ) (x max -x 1 )/(x 2 -x 1 )
Sutherland-Hodgeman poligonvágás p[2] q[m++] = Intersect(p[i], p[i+1], vágóegyenes); q[m++] = Intersect(p[i], p[i+1], vágóegyenes); PolygonClip(p[n] q[m]) m = 0; p[5] for( i=0; i < n; i++) { p[1] if (p[i] belső) { p[0] q[4] q[m++] = p[i]; if (p[i+1] külső) q[1] q[0] } else { if (p[i+1] belső) } } } q[2] p[3] p[4] Első pontot még egyszer a tömb végére q[3]
Viewport transzformáció: Normalizáltból képernyő koordinátákba Normalizált eszköz (1,1) (x c,y c ) (-1,-1) X = v w (x c +1)/2+v x Y = v h (y c +1)/2+v y v h (v x,v y ) Képernyő v w (X,Y) nézet Egység=pixel glviewport(vx, vy, vw, vh);
Raszterizáció modell Műveletek: 2-3 csúcs / primitív 6 szorzás + 4 összeadás + 4 komparálás / csúcs transzformáció vágás raszterizáció Sok pixel művelet / pixel = nsec Pixel műveletek rasztertár
Szakasz rajzolás Pont raszterizáció: koordináták kerekítése Egyenes egyenlete: y = mx + b x1 x2 Egyeneshúzás for(x = x1; x <= x2; x++) { Y = m*x + b; y = Round( Y ); write( x, y ); }
Inkrementális elv Egyenlet: Y(X) = mx + b = Y(X-1) + m DDADrawLine(int x1, int y1, int x2, int y2) { float m = (y2 - y1)/(x2 - x1); float y = y1; for(int x = x1; x <= x2; x++) { int Y = round(y); WRITE(x, Y, color); y = y+m; } }
DDA szakaszrajzoló hardver X X számláló Y y regiszter CLK x1 y1 S m
Háromszög kitöltés (X 3,Y 3 ) y = mx + b 1/m 1/m (X 2,Y 2 ) y x(y) x(y+1) x(y+2) (X 1,Y 1 ) x(y+1) = x(y)+1/m
Uniform Milyen színű legyen a pixel? Csúcspont tulajdonságokból színszámítás majd interpoláció a pixelekre Csúcspont tulajdonságokból interpoláció a pixelekre majd színszámítás Textúrázás (2D): Csúcspont textúrakoordináták interpolációja a pixelekre, majd textúra kiolvasás.
Lineáris interpoláció (vigyázat csalok) R (X 2,Y 2,R 2 ) R(X,Y) = ax + by + c (X 3,Y 3,R 3 ) Y (X 1,Y 1,R 1 ) R(X,Y) X R(X+1,Y) = R(X,Y) + a Képernyő
Interpolációs hardver X R(X,Y) X számláló R regiszter CLK S a
R (X 2,Y 2,R 2 ) n Y R(X,Y) = ax + by + c n x X+n y Y+n R R+d = 0 (X 1,Y 1,R 1 ) (X 3,Y 3,R 3 ) -n R 3 -R 1 = a(x 3 -X 1 ) + b(y 3 -Y 1 ) x R 2 -R 1 = a(x 2 -X 1 ) + b(y 2 -Y 1 ) X n = (r 3 - r 1 ) (r 2 - r 1 ) = a= Triangle setup R 1 = ax 1 + by 1 + c R 2 = ax 2 + by 2 + c R 3 = ax 3 + by 3 + c (R 3 -R 1 )(Y 2 -Y 1 ) - (Y 3 -Y 1 )(R 2 -R 1 ) (X 3 -X 1 )(Y 2 -Y 1 ) - (Y 3 -Y 1 )(X 2 -X 1 ) i j k X 3 -X 1 Y 3 -Y 1 R 3 -R 1 X 2 -X 1 Y 2 -Y 1 R 2 -R 1 n R
2D Textúrázás v x=a x u+b x v+c x y=a y u+b y v+c y Paraméterezés X=A X x+b X y+c X Y=A Y x+b Y y+c Y Képszintézis 1 (u 1,v 1 ) (x1,y1) Y (X 1,Y 1 ) (u 1,v 1 ) (u 3,v 3 ) (u 2,v 2 ) Textúra tér: egység négyzet 1 u y (x3,y3) Világ (x2,y2) x u=a u X+b u Y+c u v=a v X+b v Y+c v (X 3,Y 3 ) (u 3,v 3 ) Kép (X 2,Y 2 ) (u 2,v 2 ) X
Textúra szűrés u=a u X+b u Y+c u v=a v X+b v Y+c v v Y u Textúra tér X Képtér
Textúratér és képtér kapcsolata Magnification Minification
Mip-map (multum in parvo) Y X
Bi-linear textúra szűrés Mip-map is van: Az a default: gltexparameteri(gl_texture_2d, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gltexparameteri(gl_texture_2d, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Textúra szűrési módok Bi-linear filtering Mip-mapping
Ellenőrző kérdések Bizonyítsa be, hogy bármely 4+ csúcsú sokszögnek van diagonálja! Bizonyítsa be a kétfül tételt! Van értelme egy kört raszterizáló algoritmusnak (van ilyen)? Írjon sokszögkitöltő algoritmust, amely nem egyszerű (határ önmagát metszi és több határ is van) sokszögeket is ki tud tölteni. Implementálja a vágás és raszterizálás algoritmusait! Írjon programot, amely eldönti, hogy egy koordinátatengelyekkel párhuzamos téglalap tartalmaz-e egy szakaszból vagy egy sokszögből valamennyit? Adja meg egy 2D szerkesztő (pl. egyszerűsített Powerpoint) osztálydiagramját. Mi az értelme a normalizált eszköz-koordinátarendszer bevezetésének?