Photonmapping - Wie kann man gleichmäßig helle Wände erzeugen?
-
rapso schrieb:
andererseits brauchst nicht tweaken und 'ideen' ausprobieren, denn dann ist erstmal grundsaetzlich was falsch.
So ist das!
Die ganzen Tweaks müssen später, wenn der dicke Fehler gefunden wurde, wieder alle weggemacht werden. Und den dicken Fehler findet man irgendwann vor lauter Tweaks nicht mehr.
-
An welcher Stelle Tweake ich?
Hier mal ein Vergleichsbild zwischen verschiedenen Photonenzahlen und Mindestanzahl der Photnen für die Abschätzung für ein Pixel:
http://image-upload.de/image/VHKgbo/0c6d35f8ed.jpg
Beim Aussehnden multipliziere ich bei jeder Reflektion den Diffusfaktor (Einschalgwinkel * Flächennormale) mit der aktuellen Photonenfarbe. Sonst mache ich nichst.
Nachdem alle Ausgesendet wurden, wichte teile ich alle Photenfarben durch die Anzahl der ausgesendeten Photonen.
Beim Einsammeln nehme ich bei ein Pixel z.B. die 600 nächstne Phonten und bilde einfach nur die Summe. Diese Summe teile ich durch den FLächeninhalt des Suchkreises.
Wo also ist hier ein Tweak?
-
XMAMan schrieb:
An welcher Stelle Tweake ich?
z.B.
Dabei ist mir eine wichtige Sache aufgefallen, die ein im Internet über Photonmapping nicht gesagt wird:...
es gibt im internet etwas was dazu nicht gesagt wird? du klingst als ob du nur zusammenfassungen gelesen haettest statt paper die das bis ins detail erklaeren.
tweak:
Photonen haben eine Lebensdauer.
nein, haben sie nicht, nur eine von der reflektierenden flaeche gegebene wahrscheinlichkeit absorbiert zu werden. steht in den papern.
Das heißt nun nicht, dass man sie nach paar Zeitschritten aus der Photonmap löschen muss, aber man muss beim Erstellen der Photonmap so vorgehen, dass die Rekurionstiefe für jedes Photon variert.
das passiert automatisch durch:
Außerdem MUSS man den Wänden auch die Möglichkeit zur Photonabosorbation geben.
steht ja auch in jedem paper.
Sonst wird immer mehr Lichtenergie in den Raum geschossen und der wird ins unermessliche heller.
wie soll das gehen, jedes photon hat dieselbe energiemenge, du verschickst N photonen, lichtmenge ist N*photonstaerke. egal wie oft reflektiert wird.
Bei dünnen Objekten (Stuhlbein, Tischlampe) ist die Verteilung der Photonen kein Kreis oder Kugel sondern ein dünner Weg.
die in den papern verwendeten techniken funktionieren nicht? das problem schien mir schon lange geloest zu sein.
das meinte ich mit 'tweaks'.
wie waere es, wenn du dir mal ein referenz rendering generierst? es schaut ziemlich inkorrekt aus, wenn auch smooth auf den letzten bildern. du koenntest in blender oder pov ray deine scene mit photonmapping rendern und dann wuerdest du besser sehen was zu erwarten ist.
bei dir sieht man kaum schatten, es gibt helle spots z.b. auf tueren, stuhl, tisch, boden. es gibt parallel zu den kanten dunkle streifen auf den waenden. das licht schimmert ueberall durch (z.b. am regal).Beim Aussehnden multipliziere ich bei jeder Reflektion den Diffusfaktor (Einschalgwinkel * Flächennormale) mit der aktuellen Photonenfarbe. Sonst mache ich nichst.
den "diffusfaktor" der getroffenen flaeche? des photons? und was machst du mit dem diffusfaktor?
wenn du nichts anders machst (wie du sagst), klingt das falsch.Nachdem alle Ausgesendet wurden, wichte teile ich alle Photenfarben durch die Anzahl der ausgesendeten Photonen.
kannst du ja schon beim aussenden machen, die photonenzahl ist ja bekannt.
Beim Einsammeln nehme ich bei ein Pixel z.B. die 600 nächstne Phonten und bilde einfach nur die Summe. Diese Summe teile ich durch den FLächeninhalt des Suchkreises.
was ist wenn im suchkreis mehr oder weniger als 600 photonen sind? z.b. fast unbeleuchteter teil im schrank oder direkt an der decke decke wo im selben radius vom suchkreis fat jedes photon mal trifft.
-
Im Internet habe ich zum Thema: Dünne Objekte, lediglich den Tipp gesehen, dass man mit ein kleinen Suchradius beginnt und dann schrittweise die Kugel immer weiter vergrößert, bis man genug Photonen für die Abschätzung hat.
Ich hab das bis jetzt noch nicht so hinbekommen. Es könnte daran liegen, dass ich zwar Schrittweise den Suchradius immer weiter erhöhe, aber ich brech dann nicht rechtzeitig ab, wenn es trotz Radiusvergrößerung keine weiteren Photonen mehr gibt.
Die Idee mit den Referenzrendering in Blender oder Pov Ray halte ich für sehr gut. Ich mach das echt mal. So finde ich hoffentlich mein Fehler schneller. Schön wärs ja auch, wenn man eine bissel Quellcode oder eine Formel von den beiden hätte, so dass ich schauen könnte, was ich anders mache.
Wenn ein Photon eine Fläche trifft, berechne ich folgendes:
var schnittpunkt = rayOktree.GetSchnittpunktStrahlOktree(lichtstrahl, ersterAufruf ? false : true); Schnittpunkt S = (Schnittpunkt)schnittpunkt; if (S != null) { Vektor einschlagwinkel = -lichtstrahl.richtung; float diffuseFaktor = Math.Max(0, (S.InterpolierterSchnittpunkt().normale * einschlagwinkel)); Vektor color = S.NoLightColor(); //Filter die Farbe aktuellePhotonfarbe.x = Math.Min(color.x, aktuellePhotonfarbe.x); aktuellePhotonfarbe.y = Math.Min(color.y, aktuellePhotonfarbe.y); aktuellePhotonfarbe.z = Math.Min(color.z, aktuellePhotonfarbe.z); aktuellePhotonfarbe *= diffuseFaktor ; ...Photon speichern oder reflektieren und weiter verfolgen...
Ich mach das mit den Diffusfaktor so, weil ich in der Rendergleichung ja auch den Term N * w' drin habe. Da erschien mir das logisch^^
Wenn mehr als 600 Photonen im Suchkreis sind, dann wird diese Stelle heller, da ja die Summe aller Photonenenergie geteilt durch Flächeninhalt des Kreises dann eine größer Zahl ergibt. Weniger als 600 Photonen können es nicht werden, da ich den Radius des Suchkreises so einstelle, dass er an jeder Stelle des Bildes mindestens 600 findet.
-
XMAMan schrieb:
Im Internet habe ich zum Thema: Dünne Objekte, lediglich den Tipp gesehen, dass man mit ein kleinen Suchradius beginnt und dann schrittweise die Kugel immer weiter vergrößert, bis man genug Photonen für die Abschätzung hat.
kann es sein dass du auf deutsch suchst? so wird das nichts
Ich hab das bis jetzt noch nicht so hinbekommen. Es könnte daran liegen, dass ich zwar Schrittweise den Suchradius immer weiter erhöhe, aber ich brech dann nicht rechtzeitig ab, wenn es trotz Radiusvergrößerung keine weiteren Photonen mehr gibt.
lese dir den ersten externen artikel durch der verlinkt wird: http://en.wikipedia.org/wiki/Photon_mapping
in dem paper steht wie das mit dem photonen-rad ist und du musst es nicht selbst neu erfinden.Die Idee mit den Referenzrendering in Blender oder Pov Ray halte ich für sehr gut. Ich mach das echt mal. So finde ich hoffentlich mein Fehler schneller. Schön wärs ja auch, wenn man eine bissel Quellcode oder eine Formel von den beiden hätte, so dass ich schauen könnte, was ich anders mache.
beide hab ich erwaehnt, weil es die open source gibt. aber es koennte etwas aufwendiger sein durch code durchzusteigen wenn du die theorie nicht kennst, entsprechend... lies das paper!
Wenn ein Photon eine Fläche trifft, berechne ich folgendes:
var schnittpunkt = rayOktree.GetSchnittpunktStrahlOktree(lichtstrahl, ersterAufruf ? false : true); Schnittpunkt S = (Schnittpunkt)schnittpunkt; if (S != null) { Vektor einschlagwinkel = -lichtstrahl.richtung; float diffuseFaktor = Math.Max(0, (S.InterpolierterSchnittpunkt().normale * einschlagwinkel)); Vektor color = S.NoLightColor(); //Filter die Farbe aktuellePhotonfarbe.x = Math.Min(color.x, aktuellePhotonfarbe.x); aktuellePhotonfarbe.y = Math.Min(color.y, aktuellePhotonfarbe.y); aktuellePhotonfarbe.z = Math.Min(color.z, aktuellePhotonfarbe.z); aktuellePhotonfarbe *= diffuseFaktor ; ...Photon speichern oder reflektieren und weiter verfolgen...
Ich mach das mit den Diffusfaktor so, weil ich in der Rendergleichung ja auch den Term N * w' drin habe. Da erschien mir das logisch^^
ich wuerde broetchen auch mit keksteig backen :). schmeckt besser, logisch
Wenn mehr als 600 Photonen im Suchkreis sind, dann wird diese Stelle heller, da ja die Summe aller Photonenenergie geteilt durch Flächeninhalt des Kreises dann eine größer Zahl ergibt. Weniger als 600 Photonen können es nicht werden, da ich den Radius des Suchkreises so einstelle, dass er an jeder Stelle des Bildes mindestens 600 findet.
das erklaert ein wenig weshalb es ausschaut wie es ausschaut. stell dir vor da ist eine kleine kugel mitten im raum an der 599 photonen haengenbleiben. sie wird dunkel weil du den radius so gross machst, dass du noch ein photon von den waenden einfaengst. das ist weshalb die flachen flaechen zur mitte scheinbar ganz hell werden.
das soll nicht bedeuten dass du das jetzt mit ideen tweaken sollst bis es besser aussieht... schau wie es richtig geht im paper.
-
Ich schau mir jetzt echt mal diese Papers durch. Ich hab halt nur so eine deutsche Anleitung dazu mir angesehen, aber die hat das ganze nur kurz erklärt^^
Zeit, dass ich jetzt mal anfange mir diese ganzen Theorien reinzuziehen^^
-
Ok. Ich fang mit der Fragerrei jetzt mal mit folgenden 1. Dokument an:
http://graphics.ucsd.edu/~henrik/papers/photon_map/global_illumination_using_photon_maps_egwr96.pdf
Seite 3: Pass 1: Constructing the Photon Maps
Every time a photon hits a surface
it is stored within the photon map and Russian roulette [2] is used to determine
whether the photon is absorbed or reflectedWenn ich bei jeden Treffer mit einer Wand das Photon speicher, mit welcher Energie soll das Photon gespeichert werden, wie viel Energie bekommt das Photon, was Reflektiert wird und weiter fliegt?
Laut meinen Verständnis muss die Summe aller Photonenenergien == Energie der Lichtquelle sein(Bei Szene, wo nur eine Lichtquelle ist)
Wenn das so wäre, dann kann ich beim speichern z.B. 50% der Energie speichern, und 50% fliegt weiter. Vermutlich soll hier aber irgenteine Formel angewendet werden, wo berechnet wird, wie viel Energie gespeichert, und wie Energie weiter fliegt. Welche Formel ist das?
-------------
Seite 5: Rendergleichung:Ls(x,Ψr) = Le(x,Ψr) +ZΩ fr(x,Ψi;Ψr)Li(x,Ψi)cosθi dωi
Sieht aus wie bei Wikepedia. Also ist mir das klar. Den 2. Abschnitt nennt er hier Lr.
Nun schreibt er aber auf Seite 7, Gleichung (3) folgendes für Lr
Lr(x,Ψr)=ZΩ fr(x,Ψr,Ψi) * (d2Φi(x,Ψi)) / (dA dωi) dωi
Was bedeutet das dA und d2Φ?
Wieso sieht das so anders aus wie in der Rendergleichung?Gleich daneben schreibt er:
≈X N p=1 fr(x,Ψr,Ψi,p) ∆Φp(x,Ψi,p)πr2
Er bildet also die Summe der Photonenenergien. Wo ist der Faktor cosθi geblieben, welcher in der Rendergleichung steht?
Wie kommt er von den linken Teil der Gleichung (3) auf den rechten Teil von (3)?
---------
Seite 7 ganz unten:
We use the same approximation of ∆A as [15] where a sphere centered at x is
expanded until it contains N photons and has radius r. ∆A is then approximated
as πr2.Er vergrößert also die Kugel Schrittweise, bis sie N Photonen enthält. Was macht er bei Tischkanten und Stuhlbeinen? Dort würde die Kugel ja bis zum Maximum gehen und trotzdem nicht genug Photonen enthalten, da ja nur die Hälfte der Kugel Photonen enthält. Die andere Hälfte hängt in der Luft.
----
Seite 15:
Bild 4: Direkte Darstellung der globalen Photonmap. Hier sieht man das Rauschen wie bei mir.Auf Seite 9 ganz unten schreibt er:
The blur in the photon map is actually
an advantage since it reduces noise in the final gathering step where Monte Carlo
sampling is used to render the initial reflections accurately.Heißt das nun, er bekommt das Rauschen weg, indem er für jeden Pixel mehrere Primärstrahlen sendet und dann den für jeden Forml (3) anwendet. Der Durchschnitt daraus ist dann der Pixelwert? Hab ich das so richtig verstanden oder wie hat er Bild 3 aus Bild 4 berechnet?
...
Das waren jetzt erstmal die Fragen zum 1. Link. Die anderen Sachen schaue ich mir auch noch an.
Anmerkung: Ich sehe gerade, dass es von Wann Jensen auch eine lange Anleitung fürs Photonmapping gibt.
Außerdem habe ich gesehen, dass man Irradiance Caching und Irradiance Gradients speziell bei Diffuser Beleuchtung verwenden soll.
Vielleicht kann ich mir die ganzen Fragen ja selber beantworten, wenn ich mir das angesehen habe. Wenn aber trotzdem jemand hier helfen will, nur zu
-
ein wenig genauer und praktischer ist es beschrieben in hier.
die weiterfliegenden photonen behalten ihre energie, durch das russian roulette reduzierst du halt ihre menge sodass der durschnitt von denen der reflektierten energie entspricht. wenn farben ins spiel kommen wird es ein wenig komplexer (deswegen war mein vorschlag dass du erstmal nur alles grau machst).
ich nehm an
dA ist wohl die differential area
d2Φ ist die quadratische strecke die das photon gewandert ist.Heißt das nun, er bekommt das Rauschen weg, indem er für jeden Pixel mehrere Primärstrahlen sendet und dann den für jeden Forml (3) anwendet. Der Durchschnitt daraus ist dann der Pixelwert? Hab ich das so richtig verstanden oder wie hat er Bild 3 aus Bild 4 berechnet?
so wuerde ich final gathering verstehen.
-
So Leute, da bin ich wieder^^
Viele dachten bestimmt schon ich habe die letzten Wochen rumgegammelt und schon längst aufgegeben.
Natürlich nicht.
Ich habe mich intensiv mit Globalen Beleuchtungsverfahren beschäftigt, um nun endlich mal Photonmapping zu verstehen. Dazu habe ich mir erstmal PathTracing angesehen, um ein Verfahren zu haben, was zwar langsam ist aber dafür ein gutes Referenzbild erzeugt. Dieses Verfahren ist stabil und hat keine geheimen Stellschrauben.
Danach habe ich mir dann Radiosity angesehen, einfach weil es bekannt ist. Danach dann ein Verfahren, dessen Namen ich nicht kenne. Dieses Erzeugt aber genau so gute Bilder wie all die anderen Verfahren und ist noch dazu recht schnell. Das ganze ist von der Beschreibung ein Monte Carlo PathTracer, wo man aber für jeden Punkt die lokale Radiance berechnet, und über den Solid Angle(Raumwinkel) das ganze dann auf den Punkt projektziert.
Nachdem ich dass alles dann durch hatte, hab ich mir nochmal Photonmapping angesehen und bin fast durchgedreht, wie schwer es sein kann, wenn man keine gescheite Erklärung hat. Durch Zufall bin ich dann aber auf diese Seite gestoßen:
Ich habs dann einfach so nachgemacht und siehe da. Es klappt. Diese Seite läßt zwar immer noch die Frage auf, ob die Final Gather-Rays über ein Raumwinkel gewichtet werden müssen oder nicht. Da ich aber ein paar Refernzbilder hatte, konnte ich nun durch probieren den richtigen Algorithmus 'ermitteln'
Hier ist nun mein Vergleichsbild:
http://image-upload.de/image/EOyFNh/03f3b1d026.jpg
Ich habe all meine Forschungen erstmal in ein kleinen Extra-Mini-Projekt gemacht. Jetzt muss ich das gelernte Wissen nur noch auf mein Hauptprojekt übertragen. Das ist jetzt zum Glück nicht mehr schwer.
-
gut job
solide dass du dich da so verbissen hast bis es gute resultate gibt!
das radiosity bild schaut nicht ganz richtig aus, als ob irgendwas mit texture mapping falsch waere.
wir wollen hier jetzt natuerlich deinen raum sehen mit photonmapping (und den anderen versionen falls du die muesse hast )
-
Klar hab ich die Muse den Raum nun in all den gezeigten Verfahren zu rendern. Jetzt hab ich mir das ganze soweit nun durchgearbeitet, da will ich nun endlich auch mein Raum ordentlich haben.
-
Hier ist mein aktueller Fortschritt:
http://image-upload.de/image/WAdVzq/ea781006eb.png
Als nächstes Versuche ich ein Glasobjekt dort einzubauen. Außerdem fehlt noch Radiosity und Bidirectional PathTracing.
Der Glanzpunkt beim PathTracing muss auch noch gemacht werden.
Ich bin für die nächsten Monate also noch gut mit Aufgaben versorgt^^
-
schaut sehr gut aus, haette nicht gedacht dass du das so gut hinbekommst nach dem thread start
was genau ist die global lighting? die fireflies dort schauen aus als ob das eigentlich path tracing waere.
-
Bei GlobalLighting gehe ich wie bei PathTracing auch von einen Strahl, der von der Kamera startet in Richtung Szene und reflektiere dann immer wieder Diffuse. An jeden Punkt wo ich Auftreffe berechne ich, wie viel Licht direkt von allen Lichtquellen dahin scheinen. Ich benutze dafür den SolidAngle(Raumwinkel). Mit der BRDF-Funktion berechne ich dann, wie viel von der einstrahlenden Energie in die Richtung strahlt, aus der der Strahl kam.
Ich berechne mehrere solcher Lichtstrahlpfade und bilde daraus dann den Durchschnitt. Wenn ich zu wenig Samples nehme, dann kommt es halt zu einzelnen hellen Pixeln auf einer Wand.
-
So hier ist nun mein China-Raum^^
http://www.m-i-u.de/images-i90501bamlef.jpg
Ich habe das Ding jetzt erstmal mit PathTracing gerendert. Das hat übelst lange gedauert. Mir gings hier diesmal um eine Scene, wo vie indirektes Licht und Glasobjekte sind.
Mit Photonmapping geht das Rendern zum Glück dann schneller.
-
eine schoene szene. Bin gespannt wie es mit photonmapping ausschaut. wie lange hast du dran gepathtraced? rechnest du dir mit photonmapping lightmaps aus oder renderst du einzelbilder? (deine anfaenge sahen nach lightmaps aus)
du solltest irgendwo noch etwas platzieren was stark reflektiert und etwas, was refraktiert, im light natuerlich, das ist eine der staerken von photonmapping. Mit path tracing wirst du da recht lange rendern bis sowas konvergiert.
irgendwas an der texturierung am boden stimmt nicht. sicher dass dein filter richtig funktioniert? hast du ausreichend primary rays? (der glassscheibe nach sieht es zwar danach aus, das texture filtering sagt aber das gegenteil).
-
rapso schrieb:
eine schoene szene. Bin gespannt wie es mit photonmapping ausschaut. wie lange hast du dran gepathtraced?
rechnest du dir mit photonmapping lightmaps aus oder renderst du einzelbilder? (deine anfaenge sahen nach lightmaps aus)
du solltest irgendwo noch etwas platzieren was stark reflektiert und etwas, was refraktiert, im light natuerlich, das ist eine der staerken von photonmapping. Mit path tracing wirst du da recht lange rendern bis sowas konvergiert.
irgendwas an der texturierung am boden stimmt nicht. sicher dass dein filter richtig funktioniert? hast du ausreichend primary rays? (der glassscheibe nach sieht es zwar danach aus, das texture filtering sagt aber das gegenteil).
Ich habe 44 Tage fürs rendern gebraucht. Pro Pixel habe ich 30.000 Strahlen ausgesendet.
Natürlich speicher ich die ausgesendeten Photonen in einer Lightmap. Wie meinst du das mit Einzelbilder rendern? Das jedes Pixel seine eigene Photonmap hat?
Als nächstes will ich ein Schachbrett mit Glasfiguren rendern. Dort wird es dann farbige Kaustiken geben. Dort kann Photonmapping dann mal zeigen was es kann.
Wenn ich die Szene mit DirectX oder OpenGL render, dann sehen die Texturen genauso aus. Wenn da also ein Fehler ist, dann wohl eher in mein UV-Koordinaten oder den Bilddaten an sich.
-
XMAMan schrieb:
Ich habe 44 Tage fürs rendern gebraucht.
was fuer einen rechner nutzt du dafuer?ich erinnere mich an meinen ersten lightmapper, hab dafuer 3 high end "Pentium 90" bekommen. hab die angeworfen und bin dann 2 wochen in den urlaub gegangen als ich wiederkam waren die bei <50% fertig
30.000 ist natuerlich eine ZAHL
Natürlich speicher ich die ausgesendeten Photonen in einer Lightmap. Wie meinst du das mit Einzelbilder rendern? Das jedes Pixel seine eigene Photonmap hat?
ohne dass du sie abspeicherst, einfach nur das bild rendern. wie man es fuer filme macht.
Als nächstes will ich ein Schachbrett mit Glasfiguren rendern. Dort wird es dann farbige Kaustiken geben. Dort kann Photonmapping dann mal zeigen was es kann.
ich hoffe es liegt auf dem tisch in der jetztigen szene, die ist echt nett
Wenn ich die Szene mit DirectX oder OpenGL render, dann sehen die Texturen genauso aus. Wenn da also ein Fehler ist, dann wohl eher in mein UV-Koordinaten oder den Bilddaten an sich.
das vorhin war vom handy aus
jetzt auf dem grossen screen sehe ich dass du auch unmengen von aliasing hast.
ich vermute mal du verwendest kein mipmapping und daher dein aliasing auch bei den texturen.
beim pathtracing kannst du beide probleme loesen, indem du bei jedem der 30k strahlen pro sample einen ganz kleinen offset (subpixel) machst. entweder random oder halt ein grid. ist ja sonst schade um die 30k strahlen wenn du am ende doch noch aliasing hast.
-
Darf ich vorstellen: Das angekündigte Schachbild:
http://www.imageupload.co.uk/images/2014/12/16/Schachbild.jpg
-
XMAMan schrieb:
Darf ich vorstellen: Das angekündigte Schachbild:
http://www.imageupload.co.uk/images/2014/12/16/Schachbild.jpggeil!