View Full Version : Mehrere Fragen zu Bsp 5
tschurlo
09-12-2002, 21:33
Hi!
Bevor ich mich auf das schoene Shading stuerze, noch ein paar Fragen zum z-Buffer.
Von der Theorie her, klingt das ganze mal ganz simpel. Ich habe
jetzt nur noch ein paar Probleme, dass im Programm umzusetzen.
Also:
1.) fuer den depth-Buffer nehme ich im Augenblick ein 2-dimensionales double [height][width]-Array. Einwaende?
2.) was soll man fuer den refresh-Buffer nehmen? Da speichere ich ja meine "Intensity" ab, die meinen wohl die Farbe, oder? Macht ihr dann ein Array vom Color?
3.) Der Vergleich der z-Werte ist ja an sich nicht schwer. Mein Problem ist nur, im Buch wird z ueber die Ebenengleichung und ueber deren Parameter A, B, C berechnet.
Grad beim Schreiben faellt mir ein, dass diese 3 Parameter ja der Normalvektor der Ebene sind, na okay.
Die sind dann wohl im Normals-Table gespeichert. Wenn da keine drinnen sind, wird man sich wohl aus dem Kreuzprodukt die Normalvektoren errechnen. Da findet in einem anderen Thread schon eine lange Diskussion darueber statt.
Kurz und praegnant, wie mache ich das am Geschicktesten?
4.) Wo baue ich im Code die Berechnung der Normalvektoren, bzw. von z ein?
Waere euch fuer ein paar Anstoesze dankbar. Im Augenblick stuerzt mein Programm ohne Fehlermeldung ab. :shinner:
lg
1.) mach ich auch so.
2.) ist mir auch noch unklar - gemeint ist aber "nur" die intensität der farbe
3.) ich rechne mir die normalen immer aus - dann kann nix schief gehen - aber mir ist noch nicht ganz klar, wie ich auf den z-wert komm!
4.) der code für die berechnung kommt in CG1Object.java - da gibt es ein entsprechendes TODO 5 in der draw-methode. den z-wert muß in CG1Polygon.java eingebaut werden - da gibt's auch ein entsprechendes TODO 5
hoffe, dass noch jemand die restlichen fragen beantworten kann ;)
lg, j
1) für depth kann man ein 1-dimensionales Array verwenden, wenn man es gleich verwendet wie das Array imgData in NewCanvas.
womit 2) auch beantwortet wäre, imgData[] ist schon der refresh-Buffer
tschurlo
09-12-2002, 22:35
Mit den Normalvektoren habe ich mir das mal so ueberlegt:
Die TODOS (jetzt habe ich sie auch schon gefunden) sind ja in einer for-Schleife drinnen, die von x bis anzFace laeuft.
Ich speichere mir jetzt zwei Vektoren ab, aus denen ich dann das Kreuzprodukt, also in weiterer Folge die Parameter der Ebene berechne.
Der erste Vektor ist einfach normalTable[x][X],...
der zweite Vektor ist normalTable[x + 1][X],....
wenn ich schon beim letzten Vektor bin nehme ich als zweiten Vektor [0][X].
Ist das ganz daneben? Geht das so aehnlich?
Gezeichnet wird bei mir noch nichts, also kann ich es so noch nicht ueberpruefen.
lg
1) Die Z-Werte der Vertices werden bei der Projektion nicht verändert i.e. auf das Z der Viewplane gesetzt, deshalb kann man direkt die Z-Werte der Vertices übernehmen...
wenn du zu dem Punkt, wo schließlich ein Polygon gezeichnet werden soll, kommst, dann enthalten transformed[i][X] und transformed[i][Y] Projektionskoordinaten, in transformed[i][Z] ist aber immer noch die Viewing Koordinate, also kannst sie auch fürs z-buffern verwenden...
Das "Entlanglaufen" einer Scanline an der Z-Achse bzw. das updaten der Z-Werte für die activelist ist bereits implementiert (in der Musterlösung von Bsp 4), man braucht also nur noch zStart und dzPerScan in die Edges eintragen...
2) Aus obigem Grund brauchst du auch keine Ebenengleichungen für das Berechnen der Z-Werte der Punkte auf der Scanline...
3) Die Normalen brauchst du in diesem Beispiel nur fürs Backface Culling und fürs Shading..
tschurlo
10-12-2002, 17:58
Beim Todo: Tiefe der Vertices merken, existiert irgendwie erst nur das projected, also nehme ich diese Werte und speichere sie in einem neuen Array, da habe ich mal die z-Werte.
Darf ich noch eine naive Frage stellen, was sind zStart und dzPerScan?
Ist zStart dieser kleine Intialisierungswert (im Buch 0, in VO - unendlich)?
Ist dz jetzt der tatsaechliche Abstand, also einfach die z-Koordinate der Punkte?
Jemand hat geschrieben, dass das int-Array imgData der Refresh-Buffer ist. Ja, aber was fuer einen int-Wert soll ich denn im Buffer speichern, wenn ich einen neuen Punkt speichere?
D.h. nur allein fuer die Sichtbarkeit muss ich nur in CG1NewCanvas Aenderungen vornehmen?
lg
Deep Thought
10-12-2002, 19:23
Beim Todo: Tiefe der Vertices merken, existiert irgendwie erst nur das projected, also nehme ich diese Werte und speichere sie in einem neuen Array, da habe ich mal die z-Werte.
Man erstelle neues z Array aus double werten, und jedesmal, wenn ein Punkt vom Clipping dazugefügt wird, speichert man den z-Wert mit.
Darf ich noch eine naive Frage stellen, was sind zStart und dzPerScan?
zStart ist der z Startwert der Kante (wer hätte das gedacht!).
Funktioniert genauso wie xStart!
Das heißt du nimmst einfach den z-Wert des ersten Punktes der Kante.
Und dzPerScan ist ganz einfach z-Wert des 2. Punktes minus z-Wert des 1. Punktes diviert durch v2[Y] - v1[Y];
Also die Änderung des z-Wertes der Kante bei jeder Scanline
Jemand hat geschrieben, dass das int-Array imgData der Refresh-Buffer ist. Ja, aber was fuer einen int-Wert soll ich denn im Buffer speichern, wenn ich einen neuen Punkt speichere?
Das steht schon im Code drinnen.
imgData[pos] = (c.getRed() << 16) | (c.getGreen() << 8) | c.getBlue();
Deine Aufgabe ist es vorher den z-Buffer zu prüfen, ob die oben stehende Anweisung überhaupt ausgeführt werden soll.
mal ne blöde frage:
mit was für einer formel kann ich denn die normalen berechnen?
nochwas:
wenn ichs richtig verstanden hab macht man folgendes:
man wendet erstmal das flatshading auf das gesamte object an.dann übergibt man die polygone mit den geänderten werten an "ScanfilledPolygon"
dann macht man depth-buffer um zu schauen was gezeichnet wird.das ergebniss wird dann normal geclippt etc?
Wofür ist eigentlich die double tn = new double[3] Zeile da??
Edit - ich nehm den einfach für den Normalvektor :D
Aber wie finde ich heraus, welche faces ich mittels Backface culling entfernen soll, da meine Normalvektoren alle in eine Richtung zeigen :(
Und noch was, wie krieg ich die Punkte für den normalvektor ? - ich hab gerade rausgefunden, das ich jedesmal den gleichen Normalvektor bekomm :(
P.S.: z-Buffer funkt schon :D
Äh, Frage:
wenn ich die z-Werte für jeden Punkt speichere, muss ich dann den Z-Wert für jeden geclippten punkt brechnen?
Weil wenn p1 und p2 unterschiedliche z-Werte haben, dan ist ja der z-Wert für den gechlippten Punkt irgendwo dazwischen!
wie bereits gesagt berechnet der Musterlösungscode für Clipping den Z-Wert etwaiger Schnittpunkte mit den Fensterkanten bereits mit...
@12gauge: Kann es zufällig sein, dass du deine Normalvektoren aus den transformed [] - Punkten berechnest? Die bleiben nämlich immer dieselben...
(Genauer gesagt sind das einfach alle Punkte, die in der ganzen Szene vorkommen, allerdings noch ohne Zuordnung zu irgendwelchen Polygonen)
Die jeweiligen, echten Punkte eines Polygons werden innerhalb der
for (int x = 0; x<anzFace; x++) Schleife
mit v[0 bis n-1] [X,Y,Z] angesprochen.
Äh, noch ne dumme Frage :bounce:
Ich mein, wie der zBuffer funktioniert ist ja recht logisch, aber ich als programmiergenie hab ein bisschen probleme damit das in java zu implementieren!
deshalb Frage:
Wie ungefair schaut bei euch die methode setPixel in NewCanvas aus?
lifelikebmx
12-12-2002, 12:48
Original geschrieben von 12gauge
Wofür ist eigentlich die double tn = new double[3] Zeile da??
Edit - ich nehm den einfach für den Normalvektor :D
Aber wie finde ich heraus, welche faces ich mittels Backface culling entfernen soll, da meine Normalvektoren alle in eine Richtung zeigen :(
Und noch was, wie krieg ich die Punkte für den normalvektor ? - ich hab gerade rausgefunden, das ich jedesmal den gleichen Normalvektor bekomm :(
P.S.: z-Buffer funkt schon :D
wenn deine normalen alle in die gleiche richtung schauen dann müsstest du ein objekt mit lauter parallel im raum angeordnete faces haben - in irgendeinem anderen bsp5topic steht mehr wie du die normalvektoren bekommst - oder im internat: http://www.scs.leeds.ac.uk/cuddles/hyperbks/Rendering/Background/vector_manip.html#poly_normal - herausfinden tust du welche entfernt werden müssen mit einer einfachen abfrage
vecDotproduct(np,n) > 0 wobei n der lineofsight vector ist
hoffe ich helf dir so weiter?
tschurlo
12-12-2002, 13:00
fuers Backface-Culling reicht einfach eine Abfrage
if (nt[Z] > )
Da wir gegen die z-Achse schauen, sind alle Vektoren, die einen negativen Z-Wert haben, von dir (Blickpunkt) weggerichtet, und du machst nur weiter, wenn die Normalvektoren in deine Richtung schauen.
hat wer zufällig eine antwort auf meine frage??
(Frade siehe 2 Posts weiter oben)
ich weiss nämlich nicht genau wo bei mir der Fehler liegt, sollt nämlich eigentlich funktionieren, tuts aber nicht :)
@tschurlo
bez if (nt[z] > 0)
so bekomm ich alle seiten die ich eigentlich wegschmeissen sollte
wenn ich das größerzeichen in ein kleinerzeichen umwandel funktioniert es einwandfrei
aber warum ist das so,
warum seh ich in die falsche z richtung ?
oder gehen die z - werte zu mir in - richtung und von mir weg in + richtung ?
leobasil
12-12-2002, 17:56
hmm... ich krieg beim berechnen der normalvektoren ein array out of bounds, weil die anzahl der faces anscheinend nicht mit der anzahl der normalen übereinstimmt... aber wie kann das sein ?
leobasil
12-12-2002, 18:03
transformedNormals werden ja mit anzNormal initialisiert, aber die normalen werden nur berechnet wenn anzNormal == 0 ist .... kleiner widerspruch ???
leobasil
12-12-2002, 18:54
btw: wie kann ich mit color arbeiten ? ich hab zwar da a kleine referenz, aber da stehen nur konstruktoren und diverse get anweisungen, aber keinerlei set's oder whatever
leobasil
12-12-2002, 20:54
noch ne frage in meiner liste :)
depth is ja von p1.zStart abhängig.... aber wo/wie wird zstart definiert ?
bzw is das überhaupt richtig ?
Mehr brauchst du auch nicht...
int r=col.getRed();
int g=col.getGreen();
int b=col.getBlue();
Color newCol = new Color (r,g,b);
Eine bestehende Farbe gezielt verändern kannst du allerdings nicht mehr.
leobasil
13-12-2002, 11:51
kann ich dann eine farbe eigentlich öfters "konstruieren" ?
also ich mein kann ich schreiben
col = new Color(r,g,b)
wenns eigentlich schon initialisiert wurde ?
sicher sollt das gehen, ich habs zwar net probiert, aber wraum net.
@wolk
ich habe das gleiche Problem, bei der Abfrage if (tn[Z] < 0)
funkt es, umgekeht nicht.
lg
leobasil
13-12-2002, 14:13
@ asterix: redest du von BackFace Culling ? is ja klar oder ? die kamera schaut ja von -z nach +z
tschurlo
13-12-2002, 15:08
Haeh? Woher weisz ich, dass die Kamera von Minus nach Plus sieht?
Ich dachte die Blickrichtung ist entgegen der positiven z-Achse?
leobasil
13-12-2002, 16:13
ä... wart mal..... z muss kleiner 0 sein, dann wirds gezeichnet das heisst .... ich schau dem - entgegen..... also in + richtung, ok du hast recht !
leobasil
13-12-2002, 16:15
aber gleich mal eine weitere frage: Normalvektor würde ich berechnen mit
double[] a = new double[3];
double[] b = new double[3];
a[X]=v[1][X]-v[0][X];
a[Y]=v[1][Y]-v[0][Y];
a[Z]=v[1][Z]-v[0][Z];
b[X]=v[2][X]-v[0][X];
b[Y]=v[2][Y]-v[0][Y];
b[Z]=v[2][Z]-v[0][Z];
N[X]=a[Y]*b[Z]-b[Y]*a[Z];
N[Y]=a[Z]*b[X]-b[Z]*a[X];
N[Z]=a[X]*b[Y]-b[X]*a[Y];
...nur irgendwie scheint das nicht zu stimmen... ich krieg wenn ich den winkel zwischen licht und N ausrechnen will (fast) immer ein ergebnis zwischen 0.7 und 0.9
die formel für winkel sollt auch stimmen:
phi = (N[X]*L[X]+N[Y]*L[Y]+N[Z]*L[Z]) / (Math.sqrt(N[X]*N[X]+N[Y]*N[Y]+N[Z]*N[Z])*Math.sqrt(L[X]*L[X]+L[Y]*L[Y]+L[Z]*L[Z]));
any suggestions ?
leobasil
13-12-2002, 16:17
achja, und wenn ich den NV aus matoff file übernehm scheints zumindest zum teil zu passen
wozu berechnest du den winkel zwischen NV und Licht?, bzw was hast du für einen wert fürs licht?
leobasil
13-12-2002, 19:38
licht is ein vektor ... im moment issa L[X]=1; L[Y]=1; L[Z]=3;
vBulletin® v3.7.1, Copyright ©2000-2008, Jelsoft Enterprises Ltd.