Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

21.05.2009, 16:08

Schnittpunkt Lichtstrahl/ Ebene

Guten Tag,
habe wieder ein Problem bei dem ich nicht weiterkomme.

Ich habe eine senkrechte Ebene (TRIANGLESTRIP), ein Dreieck und eine Lichtquelle (DIRECTIONAL).
Wie kann ich den Schnittpunkt des Lichtstrahls mit der Ebene, der von einer Dreiecksspitze in Richtung der Ebene projiziert wird, feststellen ?

Ich hab dafür folgene Funktionen durchprobiert, die bei mir jedoch nicht den gewünschten Effekt erzielen.
tbLineHitsTriangle, D3DXIntersectTri, alternativ tbLineHitsPlane.
Muss ich irgendwelche Vektoren normalisieren ? Bzw. kann mir jemand ein kleines Beispiel zeigen wie ich das mit einer Funktion hinkriege ?

Für meine Ebenengleichung hab ich folgende Koordinaten verwendet.

g_aPlane[0].vPosition = tbVector3(-4.0f, -4.0f, 0.0f);
g_aPlane[1].vPosition = tbVector3(-4.0f, 4.0f, 0.0f);
g_aPlane[2].vPosition = tbVector3( 4.0f, -4.0f, 0.0f);
g_aPlane[3].vPosition = tbVector3( 4.0f, 4.0f, 0.0f);

Für die Translationsmatrix:
tbVector3 g_vPlanePosition = tbVector3(0.0f, 0.0f, 0.0f);

Das Dreieck:

g_aTriangle[0].vPosition = tbVector3(-1.0f, 0.0f, 0.0f); //A
g_aTriangle[1].vPosition = tbVector3( 0.0f, 2.0f, 0.0f); //B
g_aTriangle[2].vPosition = tbVector3( 1.0f, 0.0f, 0.0f); //C

und dessen Translationsmatrix:
tbVector3 g_vTrianglePosition = tbVector3(1.0f, 0.0f, -5.0f);

Und evtl. die Lichtrichtung:
vLightDirection = tbVector3(1.0f,-1.0f,-1.0f);


Und zum vll. noch einer meiner gescheiterten Versuche, von welchem ich ausgehe das der Ansatz stimmt.

bResult = tbLineHitsTriangle(g_aTriangle[1].vPosition, vLightDirection + g_aTriangle[1].vPosition, g_aPlane[0].vPosition, g_aPlane[1].vPosition,g_aPlane[2].vPosition, &vOut);


Bin hier echt schon am verzweifeln und über jeden Hinweis dankbar.

Grüße IncogNito

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

21.05.2009, 16:20

bei einem direktionalem licht fällt das licht auf jeden Vertex mit demgleichen winkel, es hat keine feste position, daher wirst du schwerlich den schnittpunkt auf die ebene berechnen können. weil der vektor, den du dort hast repräsentiert wenn man so will einen "lichtstrahl" des gesamten lichtes, der bei der lichberechnung einfach so genommen wird (ausser diverse koordinatentransformationen wie bei bumpmapping wegen den normalen).

3

21.05.2009, 16:27

Ich möchte ein "Schatten" Dreieck mit der Position des Lichtes auf die Ebene spiegeln.
D.h. ich möchte die 3 Schnittpunkte der Dreiecksspitzen, auf der Ebene ermitteln. Dabei möchte ich die gleiche Richtung verwenden, wie die des Directional-Lichtes.

Jemand eine Idee ? ^^

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

4

21.05.2009, 17:02

überlicherweise nutzt man bei diesem problem den stencilbuffer, auf eine und mehrere ebenen ist das ausreichend.

bin heut zu doof gescheite tuts zu finden vllt is einer ma so nett und kann aushelfen :?

5

21.05.2009, 17:10

Danke :D
Genau, um es richtig zu machen brauch ich den Stencil Buffer.
Hab vorhin mal im Buch nachgeschlagen und das ganze befindet sich irgendwo ab seite 650 ^^
Ich bin jedoch momentan auf seite 350 und ich denke die Aufgabe wird fürn Anfang vll. zu schwer für mich.
Gibts es eine Möglichkeit das ganze ohne Stencil Buffer zu realisieren ?
Also am besten nach einem Prinzip wie man Kolisionen erkennt, mithilfe der Funktionen: tbLineHitsTriangle, D3DXIntersectTri oder tbLineHitsPlane.

Gruß Inco

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

21.05.2009, 17:20

ja das sollte auch gehen. dann arbeite aber lieber mit "punktlicht". stell dir vor, du hast einen Punkt p, der das licht ist. und du hast die 3 eckpunkte des dreiecks in weltkoordinaten (also mit der weltmatrix multipliziert). dann bildest du einfach eine tbLine mit P und je einem eckpunkt, sodass du 3 tbLine objekte hast. dann berechnest du die 3 schnittpunkte mit der tbPlane dafür gibtes funktionen.
aus den 3 punkten bildest du wieder ein dreieck (dafür würde ein dynamischer vertexbuffer oder DrawPrimitiveUP reichen) und zeichnest es zuletzt ohne z-buffer. alternativ kannst du auch das dreieck ein wenig "anheben", indem du einen kleinen wert dazuaddierst je ecke an den projezierten eckpunkten des dreicks in richtung der ebenennormale (die muss natürlich richtung originaldreieck zeigen sonst siehste nüscht :D), dann geht es auch mit z-buffer.

hier nochma bildchen:

- gelb: deine tbplane
- rosa: dein lichtpunkt p
- grün: dein originaldreieck
- blau: deine tbLine's
- rot: dein projeziertes dreieck aus tbPlaneHitstbLine oder wie das heisst^^


(Link)

7

21.05.2009, 17:36

Vielen Dank erstmal,

Zitat von »"TrommlBomml"«

ja das sollte auch gehen. dann arbeite aber lieber mit "punktlicht". stell dir vor, du hast einen Punkt p, der das licht ist. und du hast die 3 eckpunkte des dreiecks in weltkoordinaten (also mit der weltmatrix multipliziert).

Hmm ich hab das noch nie gemacht, kannst du mir vll. ein kleines Beispiel zeigen ? ^^


Zitat von »"TrommlBomml"«

dann bildest du einfach eine tbLine mit P und je einem eckpunkt, sodass du 3 tbLine objekte hast. dann berechnest du die 3 schnittpunkte mit der tbPlane dafür gibtes funktionen.

Das ist mein Problem, ich weiß nicht wie ich die tbLine machen soll, da der Punkt A der Line eine meiner Dreiecksecken sein kann, aber wie kriege ich das Ende davon -> Punkt B ? Das einzigste was ich ja habe ist die Lichtrichtung + evtl. die Entfernung von Dreieck zur Ebene.

Zitat von »"TrommlBomml"«

aus den 3 punkten bildest du wieder ein dreieck (dafür würde ein dynamischer vertexbuffer oder DrawPrimitiveUP reichen) und zeichnest es zuletzt ohne z-buffer.

Genau das hab ich vor, doch wieso ohne z-buffer ?

Zitat von »"TrommlBomml"«

alternativ kannst du auch das dreieck ein wenig "anheben", indem du einen kleinen wert dazuaddierst je ecke an den projezierten eckpunkten des dreicks in richtung der ebenennormale (die muss natürlich richtung originaldreieck zeigen sonst siehste nüscht :D), dann geht es auch mit z-buffer.

Oha, woher soll ich jetzt wissen was die Richtung meiner Ebenennormalen ist ? ^^


Gruß Inco

Edit:
Danke für das Bild :D

8

21.05.2009, 20:41

Zitat von »"IncogNito"«

Oha, woher soll ich jetzt wissen was die Richtung meiner Ebenennormalen ist ? ^^

die wete a,b und c der tbPlane-Klasse sind der richtungsvektor der Ebene

9

21.05.2009, 21:27

Ok hab mich vorhin etwas intensiver damit auseinandergesetzt, krieg es aber immer noch nicht hin.

Mein aktueller Stand:

Ich habe eine Ebene auf der x-z-Achse angelegt.
Mein Code dafür:

C-/C++-Quelltext

1
2
3
4
5
6
7
    //Plane

    tbVector3 PlaneA = tbVector3(0.0f, 0.0f, 0.0f);
    tbVector3 PlaneB = tbVector3(0.0f, 0.0f, 1.0f);
    tbVector3 PlaneC = tbVector3(1.0f, 0.0f, 0.0f);

    tbPlane g_Plane(tbPlaneFromPoints(PlaneA, PlaneB, PlaneC));
    tbWritePlaneToLog(g_Plane);


Die Ebene ist soweit ich es aus der Logdatei entnehmen kann, normalisiert und zeigt nach oben
Ebene: a = 0.000, b = 1.000, c = 0.000, d = 0.000, Normalenvektorlänge = 1.000

Als nächstes habe ich die Koordinaten für mein Dreieck erstellt und mit DrawPrimitiveUp gezeichnet.


C-/C++-Quelltext

1
2
3
4
    //Dreieck

    g_aTriangle[0].vPosition = tbVector3( -4.0f, 0.0f,  0.0f); //A

    g_aTriangle[1].vPosition = tbVector3( -8.0f, 0.0f, -2.5f); //B

    g_aTriangle[2].vPosition = tbVector3( -4.0f, 0.0f,  5.0f); //C


Das Dreieck hatte ich auch Sicherheitshalber normalisiert, hatte aber nichts gebracht.

Meine für "Strahlengleichung" jede Dreiecksecke lautet:

C-/C++-Quelltext

1
2
3
    g_Ray[0] = g_aTriangle[0].vNormal + g_vLightDirection * 100.0f; //A

    g_Ray[1] = g_aTriangle[1].vNormal + g_vLightDirection * 100.0f; //B

    g_Ray[2] = g_aTriangle[2].vNormal + g_vLightDirection * 100.0f; //C


Sowie die entsprechende Schnittpunktabfrage, die leider mit als auch ohne normalisierte Vektoren scheiterte.

C-/C++-Quelltext

1
2
3
4
5
6
    tbVector3 vOut = 0.0f;
    bool bResult = false;
    //bResult = tbLineHitsTriangle(g_aTriangle[0].vPosition, g_Ray[0], g_aTriangle[0].vPosition, g_aTriangle[1].vPosition, g_aTriangle[2].vPosition, &vOut);

    bResult = tbLineHitsPlane(g_aTriangle[0].vPosition, g_Ray[0], g_Plane, &vOut); //(-4.0f, 0.0f,  0.0f)

    bResult = tbLineHitsPlane(g_aTriangle[1].vPosition, g_Ray[1], g_Plane, &vOut); //(-8.0f, 0.0f, -2.5f)

    bResult = tbLineHitsPlane(g_aTriangle[2].vPosition, g_Ray[2], g_Plane, &vOut); //(-4.0f, 0.0f,  5.0f)


Als Schnittpunkte der Strahlen vom Dreieck aus auf die x-z-Achse, bekam ich Komischerweise meine Dreieckkoordinaten wieder.
Bei der auskommentierten Funktion ebenfalls.
Beim Versuch eine Ebene aus meinen Dreieckskoordinaten zu erstellen, habe ich folgende Ausgabe erhalten: Ebene: a = 0.000, b = 0.000, c = 0.000, d = 0.000, Normalenvektorlänge = 0.000.
Die Ausgabe erscheint bei normalisierten, als auch nicht normalisierten Koordinaten.
Ich hoffe mir kann jemand weiterhelfen, weil ich bin momentan wirklich vollkommen ratlos.


Edit:
Muss ich vll. die Ebene mit SetTransform/ Matrix irgendwie einsetzen ?

Grüße Inco

10

22.05.2009, 14:55

Ok habs hinbekommen !! :D
Erstmal vielen dank an alle wo mir geholfen haben, vor allem TrommlBomml der sich voll die Mühe gemacht hat. :D

Das war echt ein komischer Fehler, vielleicht hat jemand eine Erklärung dafür. Unswar wenn ich die Plane vorher initialisiere und in ner globalen Var abspeicher, dann hat der Probleme mit den Schnittpunktberechnungen.
Wenn ich Sie aber ständig in der Renderfunktion neu initialisiere klappt alles.
Komischerweise krieg ich bei der Log-Datei bei beiden initialisierungen die gleichen Werte.
Jemand eine Erklärung wieso das so ist ? ^^

Gruß Inco

Werbeanzeige