2006. 06. 01. (keresztféléves vizsga!)
Ez az oldal a korábbi SCH wikiről lett áthozva.
Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!
Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.
1.)
Phong árnyalás (vigyázat, nem Phong BRDF modell)
- elv
- mi a különbség a Gouranud árnyaláshoz képest?
- milyen koordinátarendszerben vannak a pontok és vektorok
- az openGL-ben hogyan lehet bekapcsolni?
Megoldás 1.)
- elv és különbség a Gouraud-hoz képest: sünis könyv 209-210 oldalon <br
Phong-árnyalás | Gouraud-árnyalás |
Az árnyalási egyenletben szereplő, a fényforrás és a kamera irányába mutató egységvektorokat, illetve a normálvektort interpolálja a háromszög csúcspontjaiban érvényes adatokból, az árnyalási egyenletet minden pixelre külön értékeli ki. A műveleteket ezen vektorok világ-koordinátarendszerbeli koordinátáin kell végrehajtani. | A háromszögek csúcspontjaiban értékeli ki a fényforásból odajutó fény visszaverődést. Az illuminációs képlet alkalmazásánál az eredeti felület normálvektorával dolgozik, azaz a tesszeláció során kiadott pontokban a normálvektort is meg kell határozni. A háromszög belső pontjainak színét a csúcspontok színéből lineárisan interpolálja |
- Világkoordinátarendszer
- nem lehet (csak GL_FLAT (konstan árnyalás) és GL_SMOOTH (Gouraud árnyalás) van )
2.)
A z=0 síkon egy r sugarú, textúrázott golyó gurul az x tengely mentén v sebességgel. A t=0 időpillanatban éppen az origó felett van, a textúra kép felső része a gömb tetéjen z=2r, az alsó rész a gömb alján van z=0. Írjon egy c függvényt, mely az openGL-lel kirajzoltatja a golyót a saját színével (azaz illumináció nélkül) a t időpillanatban GL_QUADS primitívek felhasználásával. A golyó textúráját már átadtuk az openGL-nek a ==text== textúra azonosítóra hivatkozva. A kamera az 1 0 0 pontban van, mindig a gömb közepére néz, függőleges iránya 0 0 1 látószöge 90 fok, az ablak szélesség/magasság aránya 1, az első vágósík távolsaga 0.1, a hátsóé 1000. A következő függvények használata javasolt:
==glLoadIdentity, glRotatef, ...==
(A golyó mozgásállapotának meghatározása 1p, a gömb tesszellációja 5p transzformációk beállítása 4p)
Megoldás 2.)
Vö.:
- kamerabeállítás - Render() süni 23-25. oldal
- gomb animáció - Animate() süni 324. oldal
- gömb explicit egyenlete - getX(),getY(), getZ() süni 71. oldal.
- paraméteres felületek tesszellációja - Drawit() süni 101-102 oldal
class Gomb { float x0, y0, z0; // kezdeti poz float x, y, z; // aktual poz float R; // gomb sugar public: Gomb (float x00,float y00,float z00,float vx0,float vy0,float R0){ x0=x00; y0=y00; z0=z00; vx=vx0; vy=vy0; R=R0; } float getX(int u, int v){ return x0+R*cos(2*PI*u)*sin(PI*v); } float getY(int u, int v){ return y0+R*sin(2*PI*u)*sin(PI*v); } float getZ(int u, int v){ return z0+R*cos(PI*v); } void Animate(float t){ x=x0+vx*t; y=y0+vy*t; z=R; } void Drawit(int M, // u felosztások száma int N){ // v felosztások száma for (int i=0; i<M; i++){ for (int j=0; j<N; j++){ //az i,j négyzet négy csúcsa glBegin(GL_QUADS); //normálvektor kiszámítása float nx=getX((i+0.5)/M,(j+0.5)/N)-x0; float ny=getY((i+0.5)/M, (j+0.5)/N)-y0; float nz=getZ((i+0.5)/M,(j+0.5)/N)-z0; float sum=sqrt(nx*nx+ny*ny+nz*nz); glNormal3f(nx/sum, ny/sum, nz/sum); glTexCoord2f( i/M, j/N); glVertex3fv(getX( i/M, j/N), getY( i/M, j/N), getZ( i/M, j/N)); glTexCoord2f((i+1)/M, j/N); glVertex3fv(getX((i+1)/M, j/N), getY((i+1)/M, j/N), getZ((i+1)/M, j/N)); glTexCoord2f( i/M, (j+1)/N); glVertex3fv(getX( i/M, (j+1)/N), getY( i/M, (j+1)/N), getZ( i/M, (j+1)/N)); glTexCoord2f((i+1)/M, j+/N); glVertex3fv(getX((i+1)/M, (j+1)/N), getY((i+1)/M, (j+1)/N), getZ((i+1)/M, (j+1)/N)); glEnd(); } } } }; class Gombablak : public Application { Gomb * gomb float time; public: Gombablak() : application ("gomboc rajzolo moka", 300, 300) {time=0;} void Init(); void Render() { glClearColor(0,0,0,0); // képernyő törlése glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDrawBuffer(GL_BACK); // hátsó buffer használata glMatrixMode(GL_PROJECTION); //projekciós mátrix mód glLoadIdentity(); gluPerspective(90,1, 1, 1000) // látószög, ablak arány , első vágósík , hátsó vágósík. glMatrixMode(GL_MODELVIEW); // modell-nézeti mátrix glLoadIdentity(); gluLookAt(1.0, 0.0, 0.0 , // szem pozició gomb.x, gomb.y, gomb.z, // mindig a labda közepét nézzük 0.0, 0.0, 1.0) // függőleges irány gomb.Drawit(100,100); // mondvacsinált paraméterek az M és N-re SwapBuffers(wglGetCurrentDC()); //duplabuffer csere wglMakeCurrent(NULL,NULL); } Do_a_Step(float dt){ time+=dt; labda(Animate(time); Render(); } };
3.)
Adott a következő csúcspont árnyaló (Vertex Shader) és pixel árnyaló (pixel Shader)
struct inputs{ float4 pos:POSITION; float3 normal:NORMAL; float2 uv:TEXCOORD; } struct outputs{ float4 hpos:POSITION; float4 color:COLOR0; } float 4 main(in float3 color:COLOR0):COLOR { float 4 c; c.xyz=color.xyz; c.w=1; return c; } outputs main(inputs IN) { output OUT; OUT.hpos.x=IN.uv.x*IN.Pos.z; OUT.hpos.y=IN.uv.y*IN.Pos.z; OUT.hpos.z=IN.normal.z; OUT.hpos.w=IN.Pos.z; OUT.color=normalize(IN.normal); return OUT; }
Mit rajzol fel az ilyen árnyalók mellett a következő openGL program:
GlMatrixMode(GL_MODELVIEW); GlloadIdentity(); GlLookAt(100, 200, 300, 0,0,0, 0,1,0); GlMatrixMode(GL_PROJECTION); GlLoadIdentity(); GluPerspective(90, 1, 0.1, 100); GlNormal3d(2,0,0); GlBegin(GL_QUADS); GlTexCoord2f(0,0); glVertex3f(100,100,100); GlTexCoord2f(0,1); glVertex3f(-20, 30, 150); GlTexCoord2f(1,1); glVertex3f(220, -30, -110); GlTexCoord2f(1,0); glVertex3f(-30, 100, -150); GlEnd();
Válasz a kérdésre, rövid indoklással 5p
Megoldás 3.)
A PixelShader semmit nem csinál, csak beállítja az átlátszatlanságot 1-re:
c.xyz=color.xyz; c.w=1;
A VertexShader megváltoztatja a csúcspont koordinátait :
OUT.hpos.x=IN.uv.x*IN.Pos.z; OUT.hpos.y=IN.uv.y*IN.Pos.z; OUT.hpos.z=IN.normal.z; //3.koord. = normál vektor 3. koordinátája OUT.hpos.w=IN.Pos.z;
és a színét is
OUT.color=normalize(IN.normal); //látjuk, hogy a szín csak normálvektortól függ
A program négyszöget rajzol, és közös normálvektor (2,0,0) van. Ennek normalizáltja (1,0,0) tehát négyszög csúcsa piros szín lesz.
A csúcs koordináta számítás:
Pl első csúcsra:
GlTexCoord2f(0,0); glVertex3f(100,100,100); //(u,v)=(0,0)
OUT.hpos.x=IN.uv.x*IN.Pos.z = 0*100=0
OUT.hpos.y=IN.uv.y*IN.Pos.z = 0*100=0
OUT.hpos.z=IN.normal.z = 0
OUT.hpos.w=IN.Pos.z = 100
Ebből az első csúcs: (0,0,0,100) -> (0,0,0)
A többi hasonlóan kiszámíható: (0,1,0) (1,1,0) és (1,0,0)
-- NandorG - 2006.12.31.
-- nam - 2007.01.06.
-- adamo - 2007.05.28.