ZFX
ZFX Neu
Home
Community
Neueste Posts
Chat
FAQ
IOTW
Tutorials
Bücher
zfxCON
ZFXCE
Mathlib
ASSIMP
NES
Wir über uns
Impressum
Regeln
Suchen
Mitgliederliste
Membername:
Passwort:
Besucher:
4384260
Jetzt (Chat):
27 (0)
Mitglieder:
5239
Themen:
24223
Nachrichten:
234554
Neuestes Mitglied:
-insane-

ZFX
Coding-Foren
Algorithmen und Datenstrukturen
Re: Mal wieder SH
Normal
AutorThema
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Mal wieder SHNach oben.
Hi,

ich habe folgendes Problem ich versuche gerade beliebige Spherische Funktionen in verschieden Basen abzuspeichern.
Angefangen habe ich mit der SH Basis.
Wen ich jetzt versuche die Beispiel function aus dem Paper von Green zu tranformieren und sie dan wieder rekonstroiere bekomme ich sehr merkwürdige Ergebnisse.
Bis zur Ordnung von 3 (Bänder 0..3 16 funktionen) scheint alles ganz Ordendlich zu sein und das Ergebnis sieht etwa so wie in den Paper aus. Wen ich allerdings die Ordung 4,5 oder 6 verusche erhalte ich viel zu starke Spots. Bei 7 und 8 kommt nur noch Unfug raus und darüber bekomme ich als ergebniss für jeden theta,phi wert 0.
Hier mal der Code
Code:
VECTOR3 inline sphere_to_kart(VECTOR2 sp){return VECTOR3(sin(sp.x)*sin(sp.y),cos(sp.x),sin(sp.x)*cos(sp.y));};


VECTOR2 inline kart_to_sphere(VECTOR3 kart){VECTOR2 v = VECTOR2(acos(kart.y/sqrt(kart.x*kart.x+kart.y*kart.y+kart.z*kart.z)),atan2(kart.x,kart.z));
                                                if(v.y <0)
                                                    v.y += 2.0f*PI;
                                                return v;
                                                };


long inline factorial(int n)
{
    if(n<=1)
        return 1;

    int result=n;

    while(--n > 1)
        result*=n;

    return result;
}

float inline eval_legendre(int l,int m, float x)
{
    float pmm = 1.0f;
    if(m>0){
        float somx2 = sqrt(1.0f-x*x);
        float fact = 1.0f;
        for(int i=1; i<=m;++i){
            pmm *= (-fact)*somx2;
            fact += 2.0f;
        }
    }

    if(l==m)
        return pmm;

    float pmmp1 = x*(2.0f*m+1.0f)*pmm;
    
    if(l==m+1)
        return pmmp1;

    float pll = 0.0f;
    for(int i=m+2;i<=l;++i){
        pll = ((2.0f*i-1.0f)*x*pmmp1-(i+m-1.0f)*pmm)/(i-m);
        pmm = pmmp1;
        pmmp1 = pll;
    }
    return pll;

}

float inline k_fac(int l, int m)
{
    float tmp = ((2.0f*l+1.0f)*factorial(l-m))/(4.0f*PI*factorial(l+m));
    return sqrt(tmp);
}

float inline eval_sh(int l,int m, float theta, float phi)
{
    const float sqrt2 = sqrt(2.0f);
    if(m==0)
        return k_fac(l,0)*eval_legendre(l,m,cos(theta));
    else if(m>0)
        return sqrt2*k_fac(l,m)*cos(m*phi)*eval_legendre(l,m,cos(theta));
    else
        return sqrt2*k_fac(l,-m)*sin(-m*phi)*eval_legendre(l,-m,cos(theta));
}


Code:
float LIGHTSAVER::test_distribution1(float theta,float phi)
{
    return max(0,5.0*cos(theta)-4.0)+max(0.0,-4.0*sin(theta-PI)*cos(phi-2.4)-3.0);
}

void LIGHTSAVER::sh_calc_coeff()
{
    int samples;
    float n;
    float step=0.05;
    
    for(int l=0;l<=this->sh_order;l++){
        for(int m=-l;m<=l;m++){

            float c=0;
            n=0;

            for(int i=0;i<this->myMesh[0].vector_vertex.size();i++){
                VECTOR2 sp;
                sp = kart_to_sphere(this->myMesh[0].vector_vertex[i]->pos.GetNormalize());    
                n+=1;    
                c += this->test_distribution1(sp.x,sp.y)*eval_sh(l,m,sp.x,sp.y); 
            }
        
            c *= 4.0*PI/n;
            this->sh_coeff.push_back(c);  
        
        }
    }

}

float  LIGHTSAVER::sh_restore_function(float theta,float phi)
{
    int index=-1;
    float value=0;

    for(int l=0;l<=this->sh_order;l++){
        for(int m=-l;m<=l;m++){
            index +=1;
            value += this->sh_coeff[index]*eval_sh(l,m,theta,phi);  
        }
    }

    return value;
}


Zum Sampeln nehme ich die Vertexe einer Kugel die durch eine Subdivision eines Würfels entstanden ist. Ich leses die funktion also nachher an den Sampels aus.

Hat jemand eine Idee was da schief läuft?

LG+Danke
Manuel
01.02.2009, 01:05:37 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
hmm, die Koeffizienten werden ab der siebten oder achten Ordnung so klein, dass man auf doubles zurückgreifen muss. alle Ordnungen darunter sollten aber auch noch mit single precision float problemlos laufen.

der code sieht im groben überblick erstmal in ordnung aus. vielleicht gleichst du ihn mit der ZFXMath library ab um den fehler zu finden.
01.02.2009, 09:39:20 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Hmm habe es gerade komplett durch geschaut und es ist exact das selbe wie in der ZFX lib. Hmm ich verstehe das net so wirklich.
01.02.2009, 12:28:59 Uhr
x
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Ich habe es jetzt mal ein bischen genauer debugt und ich bekomme bei zu großen fakultäten Problem das die Werte über den Bereich von long hinausgehen. Das führ dan zu negativen Ergebnissen was kann man da machen?
01.02.2009, 12:49:15 Uhr
x
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
So habe jetz alle floats und ints durch double ersetzt jetzt verschwinden auch die Fehler mit dem float überläufen aber das ergebniss sieht alles andere als berauschend aus. Bis zur 4 Ordnung sieht es wirklich gut aus aber danach bekomme ich sehr helle Spots in der Mitte der beiden "Lichtkegel"

http://www.bilder-hochladen.net/files/thumbs/13dt-2.jpg

1 Mal gendert, zuletzt am 01.02.2009, 13:03:26 Uhr von MadMax.
01.02.2009, 12:56:45 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
hmm, sehr große fakultäten sollten eigentlich nicht auftreten in den ersten paar ordnungen. kann mich aber auch irren, ist schon ne weile her.
die mathlib die du da hast ist auch schon sehr alt, die die online steht ist leider nicht die letzte version, könnte auch noch fehler entthalten. Könnte dir die letzte version zuschicken wenn du magst.

ich würde dann versuchen die zfx lib mit deiner funkion zu füttern und zu schauen ob das gleiche problem besteht. SHs haben immer kleine macken, von daher kann es schon sein, dass das ergebnis nicht unbedingt falsch ist auch wenn es so aussieht.
01.02.2009, 14:48:06 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Au ja das wäre net wen du sie mal füttern könntest

Hier die funktion

Code:
float LIGHTSAVER::test_distribution1(float theta,float phi) {     return max(0,5.0*cos(theta)-4.0)+max(0.0,-4.0*sin(theta-PI)*cos(phi-2.4)-3.0); }
02.02.2009, 01:20:50 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
habs einfach mal im basic SH sample der zfx mathlib eingesetzt und sieht gut aus. erst ab der 4. Ordnung ist die rekonstruktion wirklich brauchbar, alles davor ist einfach zu niederfrequent um solch eine funktion zu rekonstruieren.

die ursprüngliche methode im basicSH sample ist sogar fast die gleiche gewesen, hatte die wohl auch ausm robin green paper kopiert.

probier mal auf deiner seite das basicSH sample und schau mal die unterschiede.
02.02.2009, 09:50:04 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Bekomme das basic SH sample nicht zum laufen ich benutze Vista und VS2008. Da hagelts nur so fehlermeldungen.
02.02.2009, 22:32:55 Uhr
x
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Habe jetzt mal andere Testfunktionen versucht (z.b. einfach nur den theta winkel /pi). Und festgestellt je höher die Ordnung der verwendeten SHs desto schlecht das Ergebnis ich bin nun ziemlich verwirt den es sollte in jedem Fall ja genau anders rum sein.
02.02.2009, 23:39:18 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
hab das gerade eben mal getestet und läuft auch unter VS2008 ohne probleme. Die pfade zum DXSDK und zur ZFXMathlib müssen natürlich für VS bekannt sein, sonst werden die notwendigen dateien natürlich nicht gefunden.

und das mit der ungenauigkeit in höheren ordnung kann schon sein. ich hab für die ZFX Mathlib extra den konstanten teil in Mathlab zu einer Look-up-table errechnen lassen, damit keine probleme zur laufzeit auftreten. das ist allerdings nicht in der Version der Mathlib zu sehen die du hast. schicke mir mal deine email adresse, dann schicke ich dir die aktuelle version.


1 Mal gendert, zuletzt am 03.02.2009, 09:32:46 Uhr von Richard Schubert.
03.02.2009, 09:30:52 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Das mit den Pfaden ist mir schon klar nur fehlen an einien stellen die variablen declarationen. Das ist nicht weiter schlim. Das größere Problem ist das im Dx10 sdk kein Dxmusic mehr dabei ist und so die ganzen header nicht funktionieren.
03.02.2009, 12:18:22 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
achso das kann natürlich sein, hab auch noch ältere SDKs drauf. das würde es erklären.

an deiner stelle würde ich nicht versuchen das Rad neu zu erfinden es gibt diverse Sh sourcen im Netz die funktionieren. Die ZFX Mathlib ist auch nur eine aufgebohrte variante von Don Williamson. Leider ist seine Website nicht mehr online.

03.02.2009, 12:26:51 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Nunja das ganze ist bestanteil meiner Diplomatbeit und soll auch wie gesagt nichts weiter können als eine beliebige sphärische Funktion zu transformieren. Sprich ich brauche weder Lightning noch Rotation noch sonst irgendwas sondern einfach nur die Transformation und die Rücktransformation.
03.02.2009, 13:31:21 Uhr
x
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
und was spricht dagegen den codeteil zu löschen den du nicht brauchst? ob du die gleichungen korrekt aus einem paper abschreibst oder sie einfach irgendwoher kopierst, macht die diplomarbeit nicht weniger wissenschaftlich.

04.02.2009, 10:14:39 Uhr
DirectX 10
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
So ich habe jetzt endlich den Fehler gefunden. Die SH funktionen waren absolut korrekt implementiert. Das einzige problem war die erstellung der sampels mit denen ich die Sphere abgetaste habe. Ich habe als sampels einfach einen Würfel genommen und durch mehrmaliges Unterteilen so einen Kugel erstellt --> die Eckpunkte der kugel haben dan meine Sampel Richtugen dargestellt.
Wen ich wie im Paper einfach Random Punkte mache funktioniert alles sonst nicht.
Ich denke das der Monte Carlo algo Probleme mach da die sampels nicht mehr uniform verteilt sind und so die Annahme einer konstanten Gewichtsfunktion nicht mehr gegeben ist.
Hat jemand eine Idee wie man das verbessern könnte ?
05.02.2009, 15:48:27 Uhr
x
Krishty Offline
ZFX'ler


Registriert seit:
01.02.2004

Nordrhein-Westfalen
342173470
Re: Mal wieder SHNach oben.
Für konstant verteilte Punkte darfst du keinen Würfel benutzen und unterteilen, sondern solltest dir einen Platonischen Körper aussuchen. Falls du noch mehr Punkte brauchst als die bieten, fang mit dem Ikosaeder an und unterteile das weiter, wobei die neuen Punkte immer wieder normalisiert werden müssen. Dann ist der Fehler in der Gleichverteilung erheblich geringer als bei einem tesselierten Würfel.

Aramis hatte mal in einem meiner Threads ein Paper mit den Koordinaten gepostet, ich suche es schnell und trage es nach.

Edit:
Zitat von Aramis:
Dave Eberly hat dazu mal ein nettes Paperchen gemacht, sind gleich alle platonischen Primitivkörper drin: Hier klicken.


Gruß, Ky

2 Mal gendert, zuletzt am 05.02.2009, 16:03:01 Uhr von Krishty.
05.02.2009, 16:01:00 Uhr
Richard Schubert Offline
DX-Berater


Registriert seit:
05.12.2002

Berlin
85557876 rs@directx9.de
Re: Mal wieder SHNach oben.
oh ja, da hätten wir früher drauf kommen können.
man kann aber auch einfach den würfel so nehmen wie er ist, wenn darin die zu komprimierenden daten gespeichert sind. zur abtastung musst du lediglich beliebige punkte nehmen wie in der ZFX Mathlib und interpolierst einen gültigen funktionswert durch die nächstliegenden punkte zu dem zufälligen punkt auf der kugel. für genau dieses beispiel gibts in der ZFX mathlib auch code, da dort sowas ähnliches in dem einen beispiel gemacht wird.
05.02.2009, 17:34:24 Uhr
DirectX 10
Aramis Offline
ZFX'ler


Registriert seit:
14.03.2007

Baden-Württemberg
406712329
Re: Mal wieder SHNach oben.
Zitat von Krishty:
keinen Würfel [...] sondern einen Platonischen Körper aussuchen

Ich such mir einen Hexaeder aus

05.02.2009, 18:38:28 Uhr
Krishty Offline
ZFX'ler


Registriert seit:
01.02.2004

Nordrhein-Westfalen
342173470
Re: Mal wieder SHNach oben.
Der Knackpunkt war genau das, was du wegzitiert hast Sobald man es unterteilt, ist es nicht mehr platonisch, das wollte ich damit sagen.
05.02.2009, 18:50:56 Uhr
MadMax Offline
ZFX'ler


Registriert seit:
24.01.2003

Baden-Württemberg
159856355 x x x
Re: Mal wieder SHNach oben.
Vielen Dank für eure Hilfe werde das am WE mal ausprobieren.

LG
Manuel
06.02.2009, 01:29:59 Uhr
x
Normal


ZFX Community Software, Version 0.9.1
Copyright 2002-2003 by Steffen Engel