PDA

View Full Version : [PROBLEM] - Bsp 5) Illumination


Flowyes
09-11-2004, 00:51
Ich versuche die Methode CG1IlluminationModelDiffuse.doIllumination() zu implementieren.

Aus den beiden Vektoren (Lichtvektor und faceNormal) hab ich mir cos(alpha) berechnet. Was mach ich als nächster Schritt? Ich vermute, dass ich diffuseIntensity mit cos(alpha) multiplizieren muss, damit ich die Intensität der Lichtquelle berechne, die ja durch diesen Einfallswinkel bestimmt wird.
Muss ich dann diesen Wert noch mit ambientIntensity multiplizieren vielleicht? Ist das nicht der Reflektierungsgrad einer Fläche unabhängig davon, von wo das Licht herkommt? Ist das richtig?

Und wenn das so stimmt und ich die richtigen Intensitäten ermittlet habe, wie kann ich diese Information an eine Farbe übergeben? Color hat ja nur RGB Eigenschaften oder lieg ich da völlig falsch. Das versteh ich überhaupt nicht. Was für eine Berechnung soll ich da mit der Farbe machen?

ChrisChiu
09-11-2004, 01:12
Ich versuche die Methode CG1IlluminationModelDiffuse.doIllumination() zu implementieren.

Aus den beiden Vektoren (Lichtvektor und faceNormal) hab ich mir cos(alpha) berechnet. Was mach ich als nächster Schritt? Ich vermute, dass ich diffuseIntensity mit cos(alpha) multiplizieren muss, damit ich die Intensität der Lichtquelle berechne, die ja durch diesen Einfallswinkel bestimmt wird.

Muss ich dann diesen Wert noch mit ambientIntensity multiplizieren vielleicht? Ist das nicht der Reflektierungsgrad einer Fläche unabhängig davon, von wo das Licht herkommt? Ist das richtig?

Und wenn das so stimmt und ich die richtigen Intensitäten ermittlet habe, wie kann ich diese Information an eine Farbe übergeben? Color hat ja nur RGB Eigenschaften oder lieg ich da völlig falsch. Das versteh ich überhaupt nicht. Was für eine Berechnung soll ich da mit der Farbe machen?

Die RGB Komponenten von Color werden ja als float von 0.0 bis 1.0 gespeichert (bzw. auch alternativ von 0 bis 255). Das gibt die jeweilige Intensität der einzelnen Farbkomponenten an.

Es gibt eine diffuseIntensity und eine ambientIntensity, und nur diffuseIntensity ist winkelabhängig.

Die jeweiligen diffuse und ambient Intensities mußt du jedenfalls multiplizieren mit jeder Einzelkomponente (also R, G, B einzeln) der Farbe in der Art:

Endfarbe = (Ambiente_Lichtfarbe * Ambiente_Materialfarbe * Diffuse_Intensität) + (Diffuse_Lichtfarbe * Diffuse_Materialfarbe * Diffuse_Intensität * Skalarprodukt(Lichtvektor, Normalvektor))

EDIT: obiges ist falsch, es muß natürlich lauten:

Endfarbe = (Ambiente_Lichtfarbe * Ambiente_Intensität) + (Diffuse_Lichtfarbe * Diffuse_Intensität * Skalarprodukt(Lichtvektor, Normalvektor))



(wobei hier die Farbkomponenten und Intensitäten hier alle im 0.0 - 1.0 Bereich angenommen werden - gegebenenfalls mußt du im Code einen 0-255 Farbwert erst in den 0.0 - 1.0 Bereich umkonvertieren)

(PS: Im Grunde ist eine RGB-Farbe auch nichts anderes als eine Datenstuktur mit 3 "Koordinaten", also ähnlich eines Punktes oder Vektors)

thebigMuh
09-11-2004, 03:08
Der Teil AmbientLight * AmbientColor wird noch mit DiffuseIntensity multipliziert? Ich stand immer unter dem Eindruck, daß die diffusen Eigenschaften eines Materials nichts mit dem Ambient Illumination cheat zu tun haben, a la:

color = Ka + L * (D*Kd + S*Ks)

Der Teil S*Ks fällt hier halt flach.

Ciao, ¡muh!

PS: Ich hab Nr. 5 noch nicht implementiert, also wenn ihr das nur irgendwie anders benamst habt in dem Framework, dann ignoriert mich einfach... :engel:

ChrisChiu
09-11-2004, 11:47
Der Teil AmbientLight * AmbientColor wird noch mit DiffuseIntensity multipliziert? Ich stand immer unter dem Eindruck, daß die diffusen Eigenschaften eines Materials nichts mit dem Ambient Illumination cheat zu tun haben, a la:

color = Ka + L * (D*Kd + S*Ks)

Der Teil S*Ks fällt hier halt flach.


Schau genau: der AmbientLight * AmbientColor Anteil wird nicht mit DiffuseIntensity multipliziert.

Ich nehm an mit S*Ks meinst du den Specular Anteil, der ist eh bei IlluminationModelDiffuse noch nicht relevant.

Ansonsten stimmt es eh überein mit meiner Formel, außer dass es halt noch einen Ambient-Anteil gibt der sich aus A*Ka zusammensetzt (statt nur Ka).

Flowyes
09-11-2004, 16:27
Verständnisfrage:

Wenn ich z.B. die ambiente Lichtfarbe berechnen will: Tu ich dann für jede Farbkomponente (also R, G und B mit Werten zwischen 0.0-1.0) mit ambientIntensity multiplizieren und aus diesen 3 Werten, eine neue Farbe erstellen, die dann nichts anderes als meine gesuchte ambiente Lichtfarbe ist?

Wenn ja, sind dann die Berechnungen für die ambiente Materialfarbe, diffuse Licht- und Materialfarbe analog zu dem wie ich es oben beschrieben hab?

Wenn auch ja, dann wird hoffentlich meine doIllumination() funktionieren...

Noch eine Frage:

Wie ruf ich diese Funktion in CG1FlatShadedPolygon() auf? Welches Objekt? illuminationModel?

thebigMuh
09-11-2004, 17:40
Schau genau: der AmbientLight * AmbientColor Anteil wird nicht mit DiffuseIntensity multipliziert.


Hehe, schau genau:


Endfarbe = (Ambiente_Lichtfarbe * Ambiente_Materialfarbe * Diffuse_Intensität) ...


Aber macht nix, jetzt weiß ich, daß es ein vertippsler war :thumb:

Ciao, ¡muh!

ChrisChiu
09-11-2004, 18:50
Hehe, schau genau:



Aber macht nix, jetzt weiß ich, daß es ein vertippsler war :thumb:

Ciao, ¡muh!


Ah, Mist! Das kommt davon wenn Hirn und Hand (und Augen) was jeweils anderes tun! Sorry!

Matthias
10-11-2004, 01:59
Wenn ich z.B. die ambiente Lichtfarbe berechnen will: Tu ich dann für jede Farbkomponente (also R, G und B mit Werten zwischen 0.0-1.0) mit ambientIntensity multiplizieren und aus diesen 3 Werten, eine neue Farbe erstellen, die dann nichts anderes als meine gesuchte ambiente Lichtfarbe ist?


Ja, also du wendest für jede Farbkomponente das Illumination Model, wie in der Vorlesung bzw. im Buch (S 567) besprochen an. Die Werte dürfen dann am Ende nur zwischen 0 und 1 sein, richtig (also auch vorher nur mit Farbwerten zwischen 0 und 1 rechnen, nicht 0 und 255 - eh logisch).

Zur 2. Frage: Bei Flatshaded musst du die Berechnung der Beleuchtung nur einmal pro Polygon ausführen ... welche Methode eignet sich dafür am besten? Richtig :) Bei komplexeren Beleuchtungsmodi wie Gouraud Shading sieht das dann schon anders aus.

ChrisChiu
10-11-2004, 02:07
Ah! Probiert folgendes:

Sagen wir, P1, P2, und P3 sind die ersten Punkte jedes Polygons.

Ihr macht - vermute ich mal - einen Vektor V1 = P1 - P2 (also von P2 nach P1) und V2 = P3 - P2 (also von P2 nach P3).

Probiert einmal, den Vektor V1 = P2 - P1 (also von P1 nach P2) sowie V2 = P3 - P1 (also von P1 nach P3) zu nehmen.

Die Faces könnt ihr ruhig als planar annehmen, deswegen funktioniert das auch so.

EDIT: ups, falscher Thread... ich sollte mir abgewöhnen Sachen parallel zu machen...

Flowyes
10-11-2004, 10:48
Zur 2. Frage: Bei Flatshaded musst du die Berechnung der Beleuchtung nur einmal pro Polygon ausführen ... welche Methode eignet sich dafür am besten? Richtig :) Bei komplexeren Beleuchtungsmodi wie Gouraud Shading sieht das dann schon anders aus. Hmm... Das hat mir irgendwie nicht geholfen. Ich muss ja irgendwo im CG1FlatShadedPolygon.fillScan() die Methode CG1IlluminationModelDiffuse.doIllumination() aufrufen, oder? In CG1Object.draw() wird ein Objekt illuminationModel erzeugt. Dieses hat die Beleuchtungseigenschaften dieses Polygons, die ich brauche, oder? Wie kann ich auf dieses Objekt zugreifen? Oder lieg ich schon wieder falsch?

Matthias
10-11-2004, 13:43
Hmm... Das hat mir irgendwie nicht geholfen. Ich muss ja irgendwo im CG1FlatShadedPolygon.fillScan() die Methode CG1IlluminationModelDiffuse.doIllumination() aufrufen, oder?

Nein, eben nicht. Bei FlatShaded reicht es - im Gegensatz zu Gouraud und Phong Shading - aus, einmal für das gesamte Polygon die Farbe zu berechnen. D.h. du musst das Illumination Model, welches du übergeben bekommst (es gibt 3 Methoden in der Klasse, eine davon hat das Illumination Model als Parameter, schau einfach mal), gar nicht speichern, sondern kannst direkt die Farbe des Polygons berechnen, diese speichern und dann später im fillScan verwenden.

Flowyes
10-11-2004, 14:31
Ich glaub jetzt werd ich um eine Erklärung für Dummies bitten müssen :)

in FlatShaded gibt's ja einen Konstruktor, der den Parameter illuminationModel enthält, diesen aber nicht speichert (also diesen Parameter kann ich schon gar nicht verwenden)
(...) Bei FlatShaded reicht es - im Gegensatz zu Gouraud und Phong Shading - aus, einmal für das gesamte Polygon die Farbe zu berechnen. (...) Muss ich nicht für jede Fläche des Polygons die Farbe dem Lichteinfallswinkel entsprechend berechnen? Das ergibt ja im Allgemeinen für jede Fläche eine andere Farbe (also Intensität), oder? "Ein mal für das gesamte Polygon die Farbe zu berechnen" hab ich nicht verstanden.

D.h. ich werde doIlluminations() in der Klasse CG1FlatShadedPolygon gar nicht verwenden. Wo und wie mach ich aber dann die Berechnungen mit den Licht- und Normalvektoren und so?

Matthias
10-11-2004, 14:35
Ich glaub jetzt werd ich um eine Erklärung für Dummies bitten müssen :)
in FlatShaded gibt's ja einen Konstruktor, der den Parameter illuminationModel enthält, diesen aber nicht speichert (also diesen Parameter kann ich schon gar nicht verwenden)


Warum nicht? Was hindert dich daran, die Berechnung mit doIllumination() gleich im Konstruktor auszuführen und die Farbe dann in der Variable color zu speichern?


Muss ich nicht für jede Fläche des Polygons die Farbe dem Lichteinfallswinkel entsprechend berechnen?


Ja schon. Aber ein Polygon = eine Fläche. Ein Objekt setzt sich aus mehreren Polygonen zusammen

ChrisChiu
10-11-2004, 15:58
Ich glaub jetzt werd ich um eine Erklärung für Dummies bitten müssen :)

in FlatShaded gibt's ja einen Konstruktor, der den Parameter illuminationModel enthält, diesen aber nicht speichert (also diesen Parameter kann ich schon gar nicht verwenden)
Muss ich nicht für jede Fläche des Polygons die Farbe dem Lichteinfallswinkel entsprechend berechnen? Das ergibt ja im Allgemeinen für jede Fläche eine andere Farbe (also Intensität), oder? "Ein mal für das gesamte Polygon die Farbe zu berechnen" hab ich nicht verstanden.

D.h. ich werde doIlluminations() in der Klasse CG1FlatShadedPolygon gar nicht verwenden. Wo und wie mach ich aber dann die Berechnungen mit den Licht- und Normalvektoren und so?

Beim TODO steht ja dabei "Think about when is the right time to do the illumination". D.h. es steht dir frei, wo du die Illumination berechnest (muß nicht unbedingt bei einer Stelle sein, die mit TODO markiert ist). Dass du im Konstruktor ein IlluminationModel Objekt überliefert bekommst - das nicht gespeichert wird, ist ja schon ein Hinweis. Irgendwas wirst du speichern müssen - und irgendwann wirst du die Illumination berechnen müssen.

Flowyes
10-11-2004, 17:49
Aber ein Polygon = eine Fläche. Ein Objekt setzt sich aus mehreren Polygonen zusammen :hewa: Ja, stimmt.

Okay, jetzt kann ich mir schon vorstellen, wie ich's angehe. Danke, ich glaub, dass es hinhaut!

Flowyes
11-11-2004, 14:15
So..., nachdem ich auch meine IllegalArgumentExceptions losgeworden bin - ich hatte vergessen, cos(alpha) auf 0 zu setzen, sobald es negativ wird - werden die Objekte wunderschön "glattschattiert" (flat shaded). Es passiert aber folgendes und ich will wissen, ob das ein Fehler ist oder nicht:

Ich öffne das Programm und lade z.B. die Sphäre. Nachdem der Lichtvektor jetzt (0,0,1) ist (also entlang der Z-Achse) ist die Sphäre sehr hell. Okay, und jetzt rotiere ich die Sphäre um die eigene X-Ache um sagen wir 180°. Und jetzt auf einmal ist alles schwarz!

Irgendwie würd ich erwarten, dass das nicht passiert, sondern dass bei einer Rotation um die X-Achse um 180° die Späre wieder genau gleich belichtet wird und genau gleich ausschaut (nur sehen wir halt die andere Seite)
Ist das eigentlich eh normal?
Wenn nicht, woran liegt das?

Matthias
11-11-2004, 14:24
Ich öffne das Programm und lade z.B. die Sphäre. Nachdem der Lichtvektor jetzt (0,0,1) ist (also entlang der Z-Achse) ist die Sphäre sehr hell. Okay, und jetzt rotiere ich die Sphäre um die eigene X-Ache um sagen wir 180°. Und jetzt auf einmal ist alles schwarz!


Wie rotierst du das Objekt? Mit den Buttons rechts oben oder indem du mit der Maus die Kamera änderst? In zweiterem Fall wäre das Verhalten korrekt, da du ja die Kamera änderst, das Licht aber nach wie vor von der selben Stelle kommt. In ersterem Fall, also wenn das Objekt selbst gedreht wird, Kamera aber gleich bleibt, dann sollte der nach vorne gedrehte Teil nicht schwarz sein.

Flowyes
11-11-2004, 14:30
Ich drehe das Objekt mit den Buttons rechts oben.
Mit der Maus drehen ist schon in Ordnung, da wirds auch wieder schwarz, also so wie's sein sollte.
Aber mit den Buttons...

Übrigens passiert das nur bei Drehungen um die X- und Y-Achsen. Bei der Drehung um die Z-Achse gibt's keine Probleme...

Der Lichtvektor bleibt bei den Drehungen immer gleich. Also immer (0, 0, 1) solang ich ihn links auf den Buttons selber nicht drehe.

Da muss irgendwas mit meinen faceNormals falsch sein...

Matthias
11-11-2004, 14:42
Du scheinst bei der X und Y Rotation die modelMatrixVector nicht richtig (oder gar nicht?) zu setzen, bei Z dann anscheinend schon. Das ist dir bis jetzt nur noch nicht aufgefallen. Also einfach modelMatrixVector genauso wie modelMatrixPoint rotieren, sollte dein Problem beheben.

Flowyes
11-11-2004, 14:48
Das hab ich mir auch gedacht, aber daran liegt es nicht! Denn, bei diesen beiden Rotationen verändere ich modelMatrixVector schon entsprechend und in transform() multipliziere ich diesen modelMatrixVector mit meiner compositeMatrix, die zum Schluss in transform() aus den faceNormals (die in calcFaceNormals() berechnet wurden) die transFaceNormals berechnet.
Komisch... Ah, woran könnte es noch liegen, das macht mich verrückt.

Matthias
11-11-2004, 15:00
Das hab ich mir auch gedacht, aber daran liegt es nicht! Denn, bei diesen beiden Rotationen verändere ich modelMatrixVector schon entsprechend und in transform() multipliziere ich diesen modelMatrixVector mit meiner compositeMatrix, der zum Schluss in transform() aus den faceNormals (die in calcFaceNormals() berechnet wurden) die transFaceNormals berechnet.
Komisch... Ah, woran könnte es noch liegen, das macht mich verrückt.

Hm, das hört sich alles richtig an. Was ist bei dir die "compositeMatrix"? Den modelMatrixVector musst du eigentlich nur mit der viewMatrixVector der Camera multiplizieren, mit der entstandenen Matrix machst du dann das transformVectors.

Bist du sicher, dass die modelMatrixVector Rotationen usw. passen? Starte vielleicht mal den Debugger und schau dir an, was bei der Z Rotation anders ist.

Flowyes
11-11-2004, 15:07
Meine compositeMatrix3x3 besteht tatsächlich nur aus der Zusammensetzung von modelMatrixVector und viewMatrixVector. Dann wird gleich transformiert.

Bei den rotateX() rotateX() und rotateZ() sind die Buchstaben der einzige Unterschied.

Ich werd mal jeder Spur folgen :ausheck: