Weil sich das Rekonstruieren in meinem Fall am entscheidender Bottleneck herausgestellt hat, bin ich am Ende bei einer wesentlich simpleren Höhe-Winkel-Repräsentation gelandet. Die Hälfte der Bits für Höhe [-1, 1], die andere Hälfte für Winkel [0, 2pi], dann reichen ein sincos, eine Wurzel und ein paar Mads für die Rekonstruktion. Jetzt wo ich eXiles Link zu Octahedron-Normal Vectors sehe, wäre das vielleicht nochmal eine Ecke flotter.
Die Spirale habe ich deshalb leider nicht mehr weiterverfolgt. Da die Oberfläche einer gekappten Kugel der Höhe h \($2\pi \ \int_0^{\cos^{-1} (1 - h)}{sin \theta \ d\theta} = 2 \pi h$\), also linear in der Höhe ist, ist die äquidistante Verteilung von Punkten auf die Höhe wie in diesem Thread eingangs skizziert wohl prinzipiell nicht verkehrt. Auch der lineare Zusammenhang des Kreiswinkels mit dem Arcuscosinus der Höhe erscheint mir nicht ganz verkehrt. Auf die Frage, inwieweit die Punkteverteilung mit den angegebenen Vorfaktoren uniform ist, habe ich leider immer noch keine Antwort. Mit der Einfachheit und damit der Effizienz von Octahedron Normals wird eine spiralbasierte Lösung jedoch ohnehin nicht mithalten können.
[Mathe] Spirale auf der Einheitskugel
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [Mathe] Spirale auf der Einheitskugel
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Chromanoid
- Moderator
- Beiträge: 4321
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: [Mathe] Spirale auf der Einheitskugel
Re: [Mathe] Spirale auf der Einheitskugel
Was bei meinem letzten Post nicht wirklich herausgekommen ist: Die Sphere-Map Transform ist nicht nur einen Tick genauer in meinen Experimenten; sie ist auch noch um einiges schneller. Nur das interessiert jetzt eher weniger; du willst das ja übers Netzwerk übertragen und nicht im Pixelshader Millionenfach berechnen.
Falls es überhaupt notwendig ist, die Normalen zu enkodieren (ist das wirklich so viel übers Netzwerk?), würde ich einfach mal ONVs vorschlagen, und die als uint16_ts (also UNORM) ins Paket reinschreiben.
Da ich, wie gesagt, das getestet habe,aber hier nur eine Vorgängerversion aus einer Nicht-HLSL-Sprache finde, hier Pseudocode Code gefunden:
Nachtrag: Ein wenig Disclaimer zum Code geschrieben, weil ja ZFX einen wahnsinnigen Page Rank hat.
Nachtrag: Bitte obigen Code nicht mehr nutzen, sondern den aus dem supplemental Material von hier verwenden.
Falls es überhaupt notwendig ist, die Normalen zu enkodieren (ist das wirklich so viel übers Netzwerk?), würde ich einfach mal ONVs vorschlagen, und die als uint16_ts (also UNORM) ins Paket reinschreiben.
Da ich, wie gesagt, das getestet habe,
Nachtrag: Bitte obigen Code nicht mehr nutzen, sondern den aus dem supplemental Material von hier verwenden.
Zuletzt geändert von eXile am 19.04.2014, 15:29, insgesamt 1-mal geändert.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [Mathe] Spirale auf der Einheitskugel
Danke, gleich mal eingebaut. Brachte leider "nur" 1-2 ms, im Moment hänge ich mehr bei den Atomics. Dennoch, wo wir schon bei Shader Code sind, gibt es noch einen intelligenteren (effizienteren) Weg als Multiplikation, Int-Casts und Bit-Shifts, um die Daten in uint-UAVs abzulegen?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [Mathe] Spirale auf der Einheitskugel
Kurze Ergänzung: Wenn man das von der Enkodierung berechnete 2-Tupel in einen 32-Bit-Integer presst (16 Bits pro Komponente), erleidet man mit der Fallunterscheidung nach tmp2 bei der Dekodierung leider desöfteren Schiffbruch, weil bisweilen Normalenprojektionen von außerhalb der Pyramidengrundfläche durch die Kompression die Seite wechseln.eXile hat geschrieben:Da ich, wie gesagt, das getestet habe,aber hier nur eine Vorgängerversion aus einer Nicht-HLSL-Sprache finde, hier PseudocodeCode gefunden: [...]
Encode:
float2 tmp3 = oneMinusUlgyZSignEps * float2(tmp2.x, tmp2.y);
Decode:
float2 tmp3 = tmp2 > 0.0f ? tmp1 : sign(tmp1) - tmp1;
tmp2 -= sign(tmp2) * ulgyZSignEps;
Besser wäre es wohl, die richtige Seite direkt auf Integer-Ebene zu enkodieren und zu dekodieren. Dies wird dem aufmerksamen Leser als Übung überlassen. ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: [Mathe] Spirale auf der Einheitskugel
Da Octahedron Normals gerade an mehreren Stellen "wiederentdeckt" werden (Wow, manchmal dauert es echt lange, bis sowas ankommt!), ein Nachtrag zum Nachtrag: Man braucht keine Epsilons, wenn man die Negierung mit einer Vertauschung der ersten beiden Komponenten UND DEREN VORZEICHEN kombiniert, weil dann auf beiden Seiten der inneren Raute / Pyramidengrundfläche benachbarte Richtungen nebeneinander landen. Damit ist der Ausgang der Fallunterscheidung bei der Dekodierung für die Richtungen auf der Unterscheidungsgrenze irrelevant: Sollte ein kodierter Vektor durch Präzisionsverlust die Seite wechseln, stellt er trotzdem noch eine im Rahmen der Diskretisierungsgenauigkeit korrekte Richtung da.CodingCat hat geschrieben:Kurze Ergänzung: Wenn man das von der Enkodierung berechnete 2-Tupel in einen 32-Bit-Integer presst (16 Bits pro Komponente), erleidet man mit der Fallunterscheidung nach tmp2 bei der Dekodierung leider desöfteren Schiffbruch, weil bisweilen Normalenprojektionen von außerhalb der Pyramidengrundfläche durch die Kompression die Seite wechseln.eXile hat geschrieben:Da ich, wie gesagt, das getestet habe,aber hier nur eine Vorgängerversion aus einer Nicht-HLSL-Sprache finde, hier PseudocodeCode gefunden: [...]
Encode:
float2 tmp4 = tmp2.z < 0 ? tmp3 : (1.0f - abs(tmp3.yx)) * signNotZero(tmp3.xy); // Beachte Vertauschung der Komponenten UND Vertauschung der Vorzeichen
Decode:
float2 tmp3 = tmp2 > 0 ? tmp1 : (1.0f - abs(tmp1.yx)) * signNotZero(tmp1.xy);
(Warum ist das so? Die Grenze liegt gerade bei z = 0, somit gilt dort |y| = 1 - |z| - |x| = 1 - |x|. Oberhalb der Grenze x' = x, unterhalb mit Vertauschung x' = s(x) * (1 - |y|) = s(x) * (1 - 1 + |x|) = s(x) * |x| = x.)
Ich möchte noch anmerken, dass im Netz noch mehr Implementierungen rumfliegen, die das Problem des hier eingangs geposteten Codes teilen. Insbesondere ist schon die Projektion im oben verlinkten Ursprungspaper problematisch - denn dort wird zwar die Komponentenvertauschung angegeben, nicht jedoch die anschließende Vertauschung der Vorzeichen, was wieder in 2 von 8 Fällen den falschen Quadrant wählt. Selbes gilt für die daraus abgeleitete Implementierung im gerade aufgetauchten Blog-Post hier. Es ist zu befürchten, dass uns derlei Implementierungen noch lange erhalten bleiben.
Das neue eingangs in diesem Post verlinkte JCGT-Paper macht es glücklicherweise richtig und kommt mit allerlei getestetem und optimiertem Shader-Code, also am besten darauf bauen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: [Mathe] Spirale auf der Einheitskugel
Ja, das habe ich auch gesehen. Ich habe meinen obigen Post nun auch editiert.
Eigentlich hätte ich mir das schon damals denken können, aber ich hatte in meinem Mathematica-Skript einen Fehler drin, den ich gerade gefunden habe (ansonsten hätte ich diese Unstetigkeit wohl hoffentlich unter Umständen vielleicht entdeckt).
Im supplemental material vom JCGT-Paper fehlen leider die qualitativen Bildvergleiche, die im Paper (z.B. bei Figure 8) versprochen wurden. Das wäre eigentlich sehr wichtig zu sehen. Ich habe Morgan McGuire mal eine Twitter-Nachricht deswegen geschrieben; wenn das nach Ostern nichts wird, kommt noch eine Mail hinterher.
Eigentlich hätte ich mir das schon damals denken können, aber ich hatte in meinem Mathematica-Skript einen Fehler drin, den ich gerade gefunden habe (ansonsten hätte ich diese Unstetigkeit wohl hoffentlich unter Umständen vielleicht entdeckt).
Im supplemental material vom JCGT-Paper fehlen leider die qualitativen Bildvergleiche, die im Paper (z.B. bei Figure 8) versprochen wurden. Das wäre eigentlich sehr wichtig zu sehen. Ich habe Morgan McGuire mal eine Twitter-Nachricht deswegen geschrieben; wenn das nach Ostern nichts wird, kommt noch eine Mail hinterher.