Photonmapping - Wie kann man gleichmäßig helle Wände erzeugen?
-
rapso schrieb:
XMAMan schrieb:
Leider bringt dieses 4-Pixel-Interpolieren voll wenig. Kann es sein, dass ich einfach ein anderen Filter noch nehmen muss? Was würdest du mir empfehlen?
ich denke du sprichst hier ueber textur filtering, oder? ich sprach eher vom bild.
ein pixel in deinem bild ist eine flaeche, du zeichnest jedoch immer nur die farbe eines speziellen unktes innerhalb dieser flaeche.
zumindestens beim path tracing (als referenz) solltest du versuchen bei jedem neuen strahl von einer anderen position innerhalb des pixels zu feuern. im simpelsten fall hast du sowasfor(int x=0;x<width;x++) { float3 Direction(float(x)/width,...); }
das solltest du in sowas aendern koennen
for(int x=0;x<width*AA;x++) { float3 Direction((float(x)+float(rand())/RAND_MAX)/(width*AA),...); }
damit hast du pro pixel einen zufaelligen wert innerhalb des pixels.
das geht natuerlich noch viel besser, aber fuer den anfang sollte das, gerade mit den tausenden von strahlen pro pixel die du abfeuerst, gut resultate liefern.
das filtern aus 4 punkten einer textur hilft dir beim hochskalieren. das macht aber nicht wirklich etwas besser, selbst wenn es aliasing loest, weil es dann matsch gibt (wobei das meine persoenliche meinung ist).
fuer gute qualitaet wuerdest du eigentlich mehr texel als pixel brauchen.der richtige filter ist dann ein wenig aufwendig. du musst nicht einfach einen punkt haben aus dem du interpolierst, du musst den pixel im screen auf die textur projezieren und dort jeden texel entsprechend der abdeckung einbeziehen. das wird aber noch aufwendiger wenn du reflektionen einbeziehen moechtest, ein pixel projeziert auf eine spiegelnde kugel kann dann eventuell eine ganze textur abdecken.
deswegen ist das supersampling mittels antialiasing, wie oben beschrieben, zu bevorzugen. denn zum antialiasing von geometrie und shading, bekommst du texture-antialiasing 'for free'.
Meine Funktion zur Erzeugung eines Primärstrahls sieht bereits so aus:
public static Strahl GetPrimärStrahlForPixel(Kamera kamera, int screenWidth, int screenHight, int x, int y, Random rand) { float kameraAbstand = kamera.GetKameraAbstandFromBildebene(); float f = (float)screenWidth / (float)screenHight; float fx = 0, fy = 0; if (rand != null) { //Gleichverteilung (Sieht nicht so cool aus) //fx = (float)rand.NextDouble() * 2 - 1; //fy = (float)rand.NextDouble() * 2 - 1; //Tent-Filter (Erzeuge mit größerer Wahrscheinlichkeit in der Mitte des Pixels ein Strahl) (Die Verteilungsfunktion ist ein Dreieck/Zelt). Deswegen Tent-Filter float r1 = 2 * (float)rand.NextDouble(); float r2 = 2 * (float)rand.NextDouble(); fx = r1 < 1 ? (float)Math.Sqrt(r1) - 1 : 1 - (float)Math.Sqrt(2 - r1); //Erzeugt Zahl zwischen -1 und +1 fy = r2 < 1 ? (float)Math.Sqrt(r2) - 1 : 1 - (float)Math.Sqrt(2 - r2); //-1 + +1 } //Die Bildebene ist f Breit und 1 Hoch Vektor bildEbenenPunkt = new Vektor(+((x + fx + 0.5f) / (float)screenWidth * f - f / 2), -(((y + fy + 0.5f) / (float)screenHight) - 0.5f), 0); return new Strahl(new Vektor(0, 0, 0), Vektor.Normiere(bildEbenenPunkt - new Vektor(0, 0, kameraAbstand))); }
Die Zahlen fx und fy sind meine Zufallszahlen, welche den Strahl so versetzen, dass er nicht immer nur durch die Pixelmitte geschossen wird. Trotzdem habe ich das Gefühl das bringt kein sichtbaren Effekt. Woran kann das liegen?
-
versuch etwas sehr simples, tent glocke ist nicht wirklich sinnvoll. ein camera sensor hat auch keinen bias.
zudem samplest du immer ueber 2 pixel, 1pixel sollte reichen fuers erste (mehr pixel koennen in der realitaet passieren, aber in einer simplen, idealisierten welt reicht erstmal 1pixel).public static Strahl GetPrimärStrahlForPixel(Kamera kamera, int screenWidth, int screenHight, int x, int y, Random rand) { float kameraAbstand = kamera.GetKameraAbstandFromBildebene(); float f = (float)screenWidth / (float)screenHight; float fx = 0, fy = 0; assert(rand!=null); //Gleichverteilung (Sieht nicht so cool aus) fx = (float)rand.NextDouble(); fy = (float)rand.NextDouble(); //Die Bildebene ist f Breit und 1 Hoch Vektor bildEbenenPunkt = new Vektor(+((x + fx) / (float)screenWidth * f - f / 2), -(((y + fy) / (float)screenHight) - 0.5f), 0); return new Strahl(new Vektor(0, 0, 0), Vektor.Normiere(bildEbenenPunkt - new Vektor(0, 0, kameraAbstand))); }
poste mal ein bild davon.
wenn das holz auf dem fussboden immer noch aliast, nimmfx = (float)rand.NextDouble()*10-5; fy = (float)rand.NextDouble()*10-5;
dann sollte es sehr verschwommen aussehen.
zudem waere dein resolve der pixel interesant, vielleicht hast da ja noch ein bug. (also die stelle wo du alle samples zu einem pixel verrechnest.
-
So sieht Variante 1 von dein Vorschlag aus:
http://s3.postimg.org/hmbydgcbz/rapso1.png
So sieht Variante 2 aus:
http://s3.postimg.org/3rdnuzhwv/rapso2.png
Pro Pixel sende ich 100 Strahlen. Ich bilde einfach die Summe von diesen 3 Floatzahlen und teile das Ergebniss dann durch 100. Klingt erstmal nicht nach viel Möglichkeiten zum falschmachen.
-
der boden schaut doch schonmal sehr viel besser aus.
an den fenstern gibt es noch aliasing weil der kontrast zu gross ist. in spielen machen wir deswegen erst das tonemapping und dann den resolve. nicht ganz korrekt, aber bei wenig samples ist das resultat netter.
aber an sich richtig, oder hast du an irgendwas etwas auszusetzen?
-
Naja... Wenn ich Variante 1 von dir mit mein Radiosity-Bild vergleiche, dann finde ich, sieht der Boden relativ gleichverpixelt noch aus. Der Fußboden, der sehr Nah am Betrachter liegt, ändert sich nicht sichtbar für mich. Der Bereich, welcher weiter hinten liegt wird ein wenig weicher/weniger Pixelig. Dafür habe ich nun das Problem an den Fensterkanten. Die sehen bissel ausgefranst aus.
Ich glaube, wenn man wirklich eine pixelfreie Textur haben will, dann geht das nur über Prozedural erstellte Texturen.
Eine Idee hätte ich übrigens auch noch und will mal wissen was dazu sagst.
Was passiert, wenn ich über ein prozedurales Verfahren eine Bumpmap erstelle, welche die Oberfläche von Holz darstellen soll, welche aber so genau ist, dass ein einzelnes Pixel gleich mehrere Huckel/Löcher enthält. Über Aliasing werde ich alles bei jeden Bumpnormal-Auslesen aus diesen Pixel verschiedene Bumpnormalen erhalten. Wenn ich damit dann die Beleuchtungsformel/Photonmap-Erstellung anwende. Könnte es dann klappen, dass ich so realistisches Holz erhalte?
-
XMAMan schrieb:
Naja... Wenn ich Variante 1 von dir mit mein Radiosity-Bild vergleiche, dann finde ich, sieht der Boden relativ gleichverpixelt noch aus. Der Fußboden, der sehr Nah am Betrachter liegt, ändert sich nicht sichtbar für mich. Der Bereich, welcher weiter hinten liegt wird ein wenig weicher/weniger Pixelig. Dafür habe ich nun das Problem an den Fensterkanten. Die sehen bissel ausgefranst aus.
die pixel nah dran sind keine Aliasing pixel. aliasing hast du wenn du zuviele daten hast bzw daten nicht genau genug samplen kannst. ganz nah hast du jedoch viel zu wenig daten.
die fenster sind ein HDR problem. die bekommst du entweder mit
-mehr samples
-besseren samples
in den gruff. bei filmen variiert die sample anzahl manchmal zwischen 7x7 und 33x33.
besseres samplen waere z.B. stratified sampling. statt 100 zufaellige samples zu nehmen, nimmst du 10x10 auf einem grid, wobei du jedes einzelne dann mit der random funktion um 0.1 pro achse random versetzt (so wie du das jetzt mit 1.0 random gemacht hast).Ich glaube, wenn man wirklich eine pixelfreie Textur haben will, dann geht das nur über Prozedural erstellte Texturen.
nicht zwingend, eine einfache moeglichkeit ist dass du eine detail textur benutzt. im einfachsten fall erstellst du eine z.b. 128x128 textur die du im einfachsten fall pro texel der holz textur anwendest.
bei einer detail textur ist grau (128,128,128) die neutrale farbe, darueber oder darunter verdunkeln oder erhellen die eigentliche textur. sowas wiecolor = tex2d(holz,UV)*(tex2d(detail,UV*128)*2.f-1.f)
du kannst verschiedene skalierungen der intensitaet nehmen, statt 2.f
du kannst mit verschiedenen UV skalierungen probieren
du kannst mehrere male die detail texture mit untershiedlichen UV und intensitaetsskalierungen anwenden.Eine Idee hätte ich übrigens auch noch und will mal wissen was dazu sagst.
Was passiert, wenn ich über ein prozedurales Verfahren eine Bumpmap erstelle, welche die Oberfläche von Holz darstellen soll, welche aber so genau ist, dass ein einzelnes Pixel gleich mehrere Huckel/Löcher enthält. Über Aliasing werde ich alles bei jeden Bumpnormal-Auslesen aus diesen Pixel verschiedene Bumpnormalen erhalten. Wenn ich damit dann die Beleuchtungsformel/Photonmap-Erstellung anwende. Könnte es dann klappen, dass ich so realistisches Holz erhalte?
damit simulierst du micro facet lighting.
das ist dann eher schon ein shading improvement. ist nicht wirklich relevant dafuer dass du nicht genug holz-textur-aufloesung hast. du wirst dann dennoch die texel vom holz sehen.holz ist eines der einfachsten prozeduralen materialien, mit ein wenig tweaken kannst du sowas realistisches erreichen:
http://modo.docs.thefoundry.co.uk/modo/701/help/pages/shaderendering/ShaderItems/Wood.html
gibt einige paper dazu, z.b.
http://developer.amd.com/wordpress/media/2012/10/ShadingCourse_Mitchell.pdf ab seite 18
-
rapso schrieb:
nicht zwingend, eine einfache moeglichkeit ist dass du eine detail textur benutzt. im einfachsten fall erstellst du eine z.b. 128x128 textur die du im einfachsten fall pro texel der holz textur anwendest.
bei einer detail textur ist grau (128,128,128) die neutrale farbe, darueber oder darunter verdunkeln oder erhellen die eigentliche textur. sowas wiecolor = tex2d(holz,UV)*(tex2d(detail,UV*128)*2.f-1.f)
du kannst verschiedene skalierungen der intensitaet nehmen, statt 2.f
du kannst mit verschiedenen UV skalierungen probieren
du kannst mehrere male die detail texture mit untershiedlichen UV und intensitaetsskalierungen anwenden.Erhalte ich dadurch nicht ein Schachbrettmuster, wenn ich für jeden Texel die gleiche Detail-Textur nehme? Stell dir mal vor ich nehme das jetzt für mein Holzfußboden. Die Pixel ganz vorne bei der Kamera kann man ja deutlich sehen. Wenn nun jeder dieser Pixel über eine Detail-Textur aufgehellt/abgedunkelt wird, dann müsste man doch dieses Muster dann immer-wieder-kehrend erkennen oder?
-
Ich habe heute mal etwas mit prozeduralen Texturen rumgespielt. Hat jemand eine Idee, wie man die Hatch-Texture, welche auf Seite 40 gezeigt wird, erzeugen könnte?
http://developer.amd.com/wordpress/media/2012/10/ShadingCourse_Mitchell.pdf
-
XMAMan schrieb:
Erhalte ich dadurch nicht ein Schachbrettmuster, wenn ich für jeden Texel die gleiche Detail-Textur nehme? Stell dir mal vor ich nehme das jetzt für mein Holzfußboden. Die Pixel ganz vorne bei der Kamera kann man ja deutlich sehen. Wenn nun jeder dieser Pixel über eine Detail-Textur aufgehellt/abgedunkelt wird, dann müsste man doch dieses Muster dann immer-wieder-kehrend erkennen oder?
das kommt auf die textur an.
wenn du soeine hast:
http://www.shawnhargreaves.com/detail_blur/gravel_orig.jpg
dann erkennst du das muster vermutlich, aber hast du soeine:
http://media.moddb.com/images/articles/1/103/102706/auto/dt_brick_cr.jpg
wird dein auge eventuel schwierigkeiten haben ueberhaupt ein muster zu erkennen.das war ebenfalls nur ein beispiel, wie du die detail texture skalierst, ist dir ueberlassen, ebenfalls ob du nicht mehrere oktaven davon nutzt. in echtzeit hat man meistens nur einen detail layer, z.B.:
https://developer.valvesoftware.com/wiki/$detail
https://udn.epicgames.com/Three/MaterialBasics.html#Detail Texture
in path tracern kannst du 10 oktaven haben.XMAMan schrieb:
Ich habe heute mal etwas mit prozeduralen Texturen rumgespielt.
http://s17.postimg.org/pa539gf3f/Procedural_Holz.pngschaut doch schonmal nett aus, sehe keine einzelnen pixel
Hat jemand eine Idee, wie man die Hatch-Texture, welche auf Seite 40 gezeigt wird, erzeugen könnte?
http://developer.amd.com/wordpress/media/2012/10/ShadingCourse_Mitchell.pdf
das zeichnen die leute wohl selbst oder generieren sie mit code (du zeichnest random lienien in eine textur.
beim erstellen der textur speicherst du dir die layer am. z.B. nach 10 strichen, nach 20, nach 30, 40,...160 und erstellst damit die volume texture.
-
Leute ich habe schon wieder ein Problem mit dem Photonmapping^^
Auf welche Weise wird der helle Lichtfleck bei der Glaskugel genau mittig drunter erzeugt? Es gibt zum einen die Kaustik, welche etwas neben der Mitte ist. Und dann halt den nicht ganz so hellen Fleck genau Mittig unter der Kugel.
http://s18.postimg.org/afbhrh89l/Gesamttest_16_2_16.jpg
Bei der progressiven Variante sieht man, dass die eigentliche Kaustik sich aufgrund der höherern Photonenzahl verbessert, aber auch dort fehlt der Fleck in der Mitte. Ich verstehe nicht woher der kommt. Hat jemand einen Rat?