Woah … Radiosity … das ich davon noch einmal höre! Sehr schön! :D Mein Wissen darüber ist etwas eingerostet, aber ich glaube ich krieg das noch gebacken. Erst einmal damit wir wissen, worüber wir sprechen, die Renderinggleichung auf Radiosity-Form gebracht:
\($$B(\mathbf x) = E(\mathbf x) + r(\mathbf x) \cdot \int_A B(\mathbf x') \, H(\mathbf x, \mathbf x') \cdot \frac{\cos(\vartheta_i) \cos(\vartheta_j)}{\|\mathbf x - \mathbf x'\|^2 \cdot \pi} \, \mathrm dA$$\)Das heißt also, wir sitzen aufm Punkt
\($\mathbf x$\) und integrieren über alle infinitesimal-großen Flächenelemente unserer Szene - das Zentrum dieses Flächenelements ist dabei mit
\($\mathbf x'$\) im Integral angegeben.
\($\vartheta_i$\) gibt den Winkel zwischen der Normalen der Fläche bei
\($\mathbf x$\) und der Verbindungsstrecke zwischen
\($\mathbf x$\) und
\($\mathbf x'$\) an. Analog gibt
\($\vartheta_j$\) den Winkel zwischen der Normalen der Fläche bei
\($\mathbf x'$\) und der Verbindungsstrecke zwischen
\($\mathbf x$\) und
\($\mathbf x'$\) an.
\($B(\mathbf x)$\) gibt die Energie vom Punkt
\($\mathbf x$\) an (d.h. nach obiger Formel ist das die Summe der von
\($\mathbf x$\) emmitierten Energie
\($E(\mathbf x)$\) und der auf diesen Punkt eingehenden Energie).
\($H(\mathbf x,v\mathbf x')$\) gibt den Sichbarkeitsterm an: 1 wenn der Punkt
\($\mathbf x$\) den Punkt
\($\mathbf x'$\) sehen kann, oder 0 wenn nicht (binäre Entscheidung - keine Werte dazwischen!).
\($r(\mathbf x)$\) gibt den diffusen Reflexiongrad der Oberfläche bei
\($\mathbf x$\) an.
Mit ein paar Annahmen (z.B. dass wir Patches haben, auf denen die Energiewerte konstant sind) kann man das in ein Gleichungssystem transformieren (aka
die Radiosity-Gleichung):
\($$B_i = E_i + r_i \cdot \sum_{j=1}^n B_j F_{ij} \qquad \text{ für } i = 1 \ldots n$$\)Die
\($B_i$\),
\($E_i$\) und
\($r_i$\) sind eigentlich wie oben, die
\($F_{ij}$\) sind die Formfaktoren:
\($$F_{ij} = \frac{1}{A_i} \int_{A_i} \int_{A_j} H(\mathbf x, \mathbf x') \cdot \frac{\cos(\vartheta_i) \cos(\vartheta_j)}{\|\mathbf x - \mathbf x'\|^2 \cdot \pi} \, \mathrm dA' \mathrm dA$$\)Dabei ist wieder wie oben
\($\mathbf x$\) das Zentrum von der infinitesimal-großen Fläche
\($A$\) und
\($\mathbf x'$\) ist das Zentrum der infinitesimal-großen Fläche
\($A'$\). Wie man sieht, gibt also der Formfaktor
\($F_{ij}$\) den Anteil der Energie an, welche von
\($A_i$\) abgestrahlt wird und bei
\($A_j$\) ankommt. Damit ist der Formfaktor auch einheitenlos: Bei dem Integral käme ja in SI-Einheiten die Einheit
\($\mathrm m^2$\) (Quadratmeter) raus, aber da wir ja am Anfang durch
\($A_i$\) (auch in
\($\mathrm m^2$\)) teilen, kürzt sich das alles raus! :) Jetzt zu deinen Fragen:
Punika hat geschrieben:Erstmal eine Frage zur Formel. Da ich meine Scene im Moment mit Patches so unterteile das jedes Patch die gleiche Größe hat, fallen quasi die Werte fast weg. z.B. ist bei mir die Differenz Fläche hauptsächlich bei 1. Das passiert bei mir im Moment nur bei Lichtern nicht. Da diese zusätzlich zu den Geometry Patches extra hinzugefügt werden. Die Sichtbarkeit Fläche wäre bei mir auch noch entweder 0 (fällt weg da vorher getestet wird ob emitter sicht hat zu collector oder nicht) oder eben 1.
OK, ich nehme erstmal an, du meinst mit der Formel die Formel zur Berechnung der Formfaktoren. Ich verstehe erst einmal nicht, was du mit „Differenzfläche“ meinst. Und wenn die Patches doch gleich groß sind, ist doch die Differenz der Flächeninhalte 0? Und viel scherwiegender: In der Formel für die Formfaktoren kommt doch eine Differenzfläche gar nicht vor! Über welche Formel sprechen wir hier nun?
Das Berechnen der Formfaktoren geht z.B. via das Verfahren von Wallace, was auch Raytracing benutzt, so wie du. Bei der häufig genutzten Approximation mittels einer Kreisscheibe mit Flächeninhalt a in Entfernung r gilt für den Formfaktor ungefähr (Halt! Das ist noch nicht die finale Form! Das ist nur für den Formfaktor zwischen genau zwei Kreisscheiben!):
\($$F_{ij} = \frac{a^2 \cdot \cos(\vartheta_i) \cos(\vartheta_j)}{a^2 + r^2}$$\)Aber wir haben ja eigentlich quadratische Patches und außerdem wurde in der obigen Formel viel mit der Sichbarkeit bzgl. der Orientierung der Flächen bei flachen Winkeln rumgehackt. Also eigentlich ist diese Formel ein gigantischer Hack. Aber er sieht gut aus. Also beim Verfahren von Wallace wird jetzt der Zielpatch nicht durch eine Kreisscheibe approximiert, sondern durch ganz viele. Dabei wird immer via Raytracing überprüft, ob die Kreisscheibe sichtbar ist (vom Zentrum des Ursprungspatches aus gesehen). Falls ja, wir das Ergebnis von obiger Formel zum Formfaktor hinzuaddiert, ansonsten halt nicht. Natürlich macht man zuerst ein paar Kollisionstests zwischen den Eckpunkten der Patches, ob überhaupt eine Okklusion stattfindet, und man überhaupt den Zielpatch weiter unterteilen möchte.
Punika hat geschrieben:Wenn ich nun einem Patch genug Energy gebe um im ersten Pass die Szene zu beleuchten funktioniert das auch tadellos. Doch im nächsten Pass ist viel zu wenig Energy da, da man durch Fij nur noch Werte im Bereich von 0.00001 hat. Wenn ich diese wieder durch eine Konstante in den Bereich bringe wo ich mit Arbeiten kann, wird das sehr unstabil. Entweder wird alles komplett Hell oder es bleibt quasi beim ersten Pass.
OK, wenn du dir sicher bist, dass deine Berechnung stimmt (wovon ich bei einem erfolgreichen ersten Pass erst einmal ausgehe, es sei denn, du machst dort irgendetwas anders als in den anderen Passes), wären meine ersten Ideen: Intensität der Lichtquelle rauf, Reflexionsanteile (die r_i oben) rauf oder die gesamte Szene gleichmäßig kleiner Skalieren (das vergrößert die Formfaktoren und ist somit eine Mischung aus den beiden vorherigen Sachen).
Punika hat geschrieben:Meine Frage ist nun wie ihr die Werte stabil bekommt -> zum sichtbaren 0 - 1 Bereich für die Texturen. Oder ob Radiosity nur stabil läuft mit Patch Subdivision -> Große Patch flächen am Anfang.
Das sollte eigentlich ohne weitere Hacks funktionieren. Hierachisches Radiosity macht dabei bzgl. der Korrektheit keinen Unterschied.
PS: Ich bin mit dem LaTeX-Bild-Server oben nicht wirklich zufrieden, da die Referrer gespeichert werden. Ich hatte vor einigen Wochen mal an einem eigenen Tool für phpbb gebastelt - insbesondere mit richtigem Subpixel-Antialiasing, und nicht dem Kack dort oben (ich habe mich dabei von dem 5-Tap-FIR-Filter der FreeType-Library inspirieren lassen) - aber im Augenblick liegt das aus Zeitmangel wieder auf Eis. Aber bald … bestimmt.
Nachtrag: Alles auf MathJax umgestellt.
PPS: Ich mag die von Radiosity erzeugte Beleuchtung sehr gern. Insbesondere in Mirror's Edge sieht man die Ergebniss sehr schön. Allgemein ist glaube ich die Half-Life-2-Engine das einzige Paket, welches einen Radiosity-Berechner eingebaut hat (das schon zu Half-Life-1-Zeiten - eines der großen Erweiterungen im Vergleich zur Quake-Engine).