projekce 3D modelu do 2D s kamerou

Vývojová prostředí, aplikace, skripty, http://www... síťové programy, internet, sdílení...
Odpovědět
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

Zdravím, opět otravuji, ale snad už naposledy.


Snažím se už nějaký ten pátek vytvořit hru v HTML5 Canvasu. Nenašel jsem nikde hezký návod s příklady, proto se opět po měsíci obracím sem, protože jsem se do toho úplně zamotal.


Teď už otázky.


1. K čemu je inverzní matice?
2. Mám čtvercovou matici m x n. Mám správně vektory left, up a forward na obrázku?
Obrázek


3. Pokud mám cameru na pozici (0,0,0) a dívá se na (0,0,1) a bod je na (0,0,2). Kde bude bod ve View Space? Myslel jsem že bude na (0,0,2) pořád, když kamera se nehnula, ale vyjde mi (0,0,-2) čili se vlastně otočil o 180%.


Hodně mě zmátlo, že třeba OpenGL má translaci jednou na a31,a32,a33 a jindy zase na a13,a23,a33. Já samozřejmě chci používat druhou verzi (viz. obrázek struktury matice). Vím že OpenGL má matici typu n x m (sloupec x řádek) ale tu translaci opravdu nechápu.


4. Jak vlastně otočím pohled kamery? Myslel jsem si, že když otočím vektorem kam se dívá, tak to bude to pravé ořechové, ale není. Kameru vytvářm pomocí LookAt funkce jako je v XNA.


To je zatím asi vše. Za každou odpověď budu rád. Už se s tím trápím dlouho.
Abych nezapomněl, celé to dělám v javascriptu. To je ale celkem nepodstatná informace.
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

Má někdo tucha na kterém fóru by se tímto problémem mohli zabývat?
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
nou
Začátečník
Začátečník
Registrován: 11. pro 2009

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od nou »

1. inverzna matica sluzi na prevod suradnic opacnym smerom. maj modelview matica sluzi na prevod do priestoru kamery. pomocou inverznej matice sa dostanes naspet z priestoru kamery do priestoru modelu.
2. viac menej dobre. horna 3x3 matica je rotacna matica a posledny stlpec je translate.
3. OpenGL uklada matice po stlpcoch. teda ak mas pole 16 float tak translate bude na 12, 13, 14 poziciach.

Kód: Vybrat vše

|0 4 8 12|
|1 5 9 13|
|2 6 10 14|
|3 7 11 15|
potom sa to rata nasledovne P*V*M*v = v'
kde P-projection matrix z priestoru kamery do priestoru obrazovky
V - view matrix z priestoru sveta do priestoru kamery
M - model matrix z lokaleneho priestoru modelu do priestoru sveta
v - vektor pred transformaciou
v' - transformovany vektor
do OpenGL sa samozrejme posiela len jedna uz vynasobena matica kedze nasobenie dvoch matic je narocna operacia http://cs.wikipedia.org/wiki/N%C3%A1soben%C3%AD_matic myslim ze je nutne aby si vedel nasobit matice a vektor s maticou.
4. v OpenGL sa pozeras smerom -Z. teda to ze dostanes -2 po vynasobeni modelview maticou je spravne.

http://www.ceske-hry.cz/forum/
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

3. Já mám matici po řádkách.

Kód: Vybrat vše

|0 1 2 3|
|4 5 6 7|
|8 9 10 11|
|12 13 14 15|
respektive

Kód: Vybrat vše

|11 12 13 14|
|21 22 23 24|
|31 32 33 34|
|41 42 43 44|
a translate mám na 14,24,34.

Nenásobí se u OpenGL obráceně? Já bych to teoreticky měl mít tedy v' = v*MVP?

Násobení matic mám:

Kód: Vybrat vše

Matrix4.Multiply = function(a,b){
  if(!this.Equals(a)){ throw new Error("Error: M1"); }
  if(!this.Equals(b)){ throw new Error("Error: M2"); }
  
  return new this(a.n11 * b.n11 + a.n12 * b.n21 + a.n13 * b.n31 + a.n14 * b.n41,
	  a.n11 * b.n12 + a.n12 * b.n22 + a.n13 * b.n32 + a.n14 * b.n42,
	  a.n11 * b.n13 + a.n12 * b.n23 + a.n13 * b.n33 + a.n14 * b.n43,
	  a.n11 * b.n14 + a.n12 * b.n24 + a.n13 * b.n34 + a.n14 * b.n44,

	  a.n21 * b.n11 + a.n22 * b.n21 + a.n23 * b.n31 + a.n24 * b.n41,
	  a.n21 * b.n12 + a.n22 * b.n22 + a.n23 * b.n32 + a.n24 * b.n42,
	  a.n21 * b.n13 + a.n22 * b.n23 + a.n23 * b.n33 + a.n24 * b.n43,
	  a.n21 * b.n14 + a.n22 * b.n24 + a.n23 * b.n34 + a.n24 * b.n44,

	  a.n31 * b.n11 + a.n32 * b.n21 + a.n33 * b.n31 + a.n34 * b.n41,
	  a.n31 * b.n12 + a.n32 * b.n22 + a.n33 * b.n32 + a.n34 * b.n42,
	  a.n31 * b.n13 + a.n32 * b.n23 + a.n33 * b.n33 + a.n34 * b.n43,
	  a.n31 * b.n14 + a.n32 * b.n24 + a.n33 * b.n34 + a.n34 * b.n44,

	  a.n41 * b.n11 + a.n42 * b.n21 + a.n43 * b.n31 + a.n44 * b.n41,
	  a.n41 * b.n12 + a.n42 * b.n22 + a.n43 * b.n32 + a.n44 * b.n42,
	  a.n41 * b.n13 + a.n42 * b.n23 + a.n43 * b.n33 + a.n44 * b.n43,
	  a.n41 * b.n14 + a.n42 * b.n24 + a.n43 * b.n34 + a.n44 * b.n44
  );
};
Což je v pořádku, několikrát jsem to kontroloval.

A vektor s maticí násobím:

Kód: Vybrat vše

multiplyVector3:function(v){
	  d = 1 / ( this.n41 * v.x + this.n42 * v.y + this.n43 * v.z + this.n44 );

	  return new Vector3(
      ( this.n11 * v.x + this.n12 * v.y + this.n13 * v.z + this.n14 ) * d,
      ( this.n21 * v.x + this.n22 * v.y + this.n23 * v.z + this.n24 ) * d,
      ( this.n31 * v.x + this.n32 * v.y + this.n33 * v.z + this.n34 ) * d
    );
  }
Což by také mělo být správně.

Mám vše podle této stránky. I matice mi vycházejí stejně.
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
nou
Začátečník
Začátečník
Registrován: 11. pro 2009

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od nou »

no ano funguje ti to pretoze (A*B)' == B'*A' kde ' znaci transponovanie matice. teda prevratenie okolo diagonaly. ak si precitas specifikacie OpenGL tak vsade je pouzivana matematicka notacia. to len kretensky Microsoft aby nebol kompatibilny si vymyslel ze vektor je riadkovy a teda vsetko otocil na hlavu.

nasobenie matice a vektora ti vracia spravne vysledky ale nie je to spravny postup. OpenGL v skutocnosti pracuje s 4 rozmernym vektorom (x,y,z,w) pricom w moze byt 0 alebo 1. ak je 0 tak dany vektor reprezentuje smer. ak je 1 tak je to bod. toto jednoduche pravidlo nam obmedzuje povolene kombinacie medzi vektoromi. vysledkom musi byt vzdy vektor ktory ma w rovne 0 alebo 1 majme bod b=(x,y,z,1) a vektor v=(a,b,c,0). scitanie dvoch vektorov je povelna operacia kedze vysledkom je zase vektor kedze vysledkom je 0+0=0. scitanie vektora a bodu je tiez povelna opracie kedze vysledkom je 0+1=1. scitanie dvoch bodov je nezmysel kedze 1+1=2 teda sa to vymyka tomu ze w moze byt len 0 alebo 1.

pri tvojom nasobeni matice a vektora mozes vidiet tu zamlcanu 1 (this.n11 * v.x + this.n12 * v.y + this.n13 * v.z + this.n14 * 1)
to nasobenie d je tam ale navyse. je to v skustocnosti perspektivne delenie ktore sa vykonáva nakoniec po aplikovani perspektivnej projekcie. ta funkcia ale nie je normalne nasobnenie matice a vektora. odporucam precitat wiki.
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

Tak vektor transformuji při matici MVP, takže mi to přišlo logické.

Nedochází mi ale, jak z bodu xyz udělat xy ve screen space.

Mám i funkci multiplyVector4, tak tedy použiji tu.
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
nou
Začátečník
Začátečník
Registrován: 11. pro 2009

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od nou »

takze mame bod v(x,y,z,1) to prezenieme najprv cez modelview maticu http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
dostaneme bod v priestore kamery teda relativne voci kamere. kamera pozera v smere -Z
toto ide to projection matrix http://www.opengl.org/sdk/docs/man2/xht ... ective.xml to dostaneme suradnice v clip space.
v' = MVP*v;
teraz sa vykona perspektivne delenie. teda vydeli sa vektor suradnicou w.
n = v'/v'.w; tymto dostaneme normalizovane suradnice obrazovky ktore su v rozmedzi -1 az 1. dolny lavy roh je -1;-1 a horny pravy je 1;1 pricom stred obrazovky je 0;0. posledna operacia ktora sa vykona je pretransformovanie na pixelove suradnice teda x' = (x_normalized+1)*(width/2) y' = (y_normalized+1)*(height/2)

mal by si pouzivat OpenGL syntax pretoze ked zacnes pouzivat shadery tak tam sa nasobenie matic zapisuje od "konca".
out_Position = PerspectiveMatrix * ViewMatrix * ModelMatrix * in_Vertex;
samozrejme realne tam bude len jedna matica len demostrujem v akom presne poradi sa to zapisuje.

viac to mas rozpisane tuna http://www.songho.ca/opengl/gl_transform.html
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

Nemůžu používat shadery z OpenGL, protože jak jsem psal, je to javascript. Takže přiřazení matic objektu nepřipadá v úvahu. Respektive můžu napsat, že matice objektu se vynásobí maticí PV, ale to je tak všechno.

Homogenní souřadnice samozřejmě ve výsledku proháním již vaším zmíněným způsobem. Nejdřív ale zjišťuji, pokud je trojúhelník blíž vůči kameře. Jinak ho nevykresluji pokud je z < 0.
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
nou
Začátečník
Začátečník
Registrován: 11. pro 2009

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od nou »

bod sa nachadza v pohlade kamery ak su x,y,z suradnice medzi -w a w. teda p = MVP * v;
if(-w <= p.x <= w && -w <= p.y <= w && -w <= p.z <= w){ bod je vnutry pohladu kamery.
1Pupik1989
Začátečník
Začátečník
Registrován: 20. říj 2011
Bydliště: Dvůr Králové nad Labem

Re: projekce 3D modelu do 2D s kamerou

Příspěvek od 1Pupik1989 »

Tak děkuji moc za pomoc. Vše funguje jak má.

I matice násobím po vzoru OpenGL.

Ještě jednou děkuji mnohokrát.
CPU: AMD Phenom II x4 955BE @ 4GHz FAN: Arctic Cooling Freezer Xtreme rev.2
MB: MSI 760GM-E51
RAM: Kingston 2x4Gb RAM DDR3 1333 @ 1466MHz
GPU: Gigabyte Radeon HD 6850 OC 985/1260MHz
HDD: WD Caviar Green WD10EARX 1TB SATAIII/600, ZDROJ: Fortron FSP550-APN (550W)
Odpovědět

Zpět na „Programování a web“