Problem mit Kameradrehung: Lichtrichtung soll erhalten werden
-
Uhm, also natürlicher erscheint es aber doch gerade dann, WENN sich etwas an der Beleuchtung ändert. Beispielsweise trifft dich das Licht einer reflektierenden Fensterscheibe nur in einem bestimmten Winkel und auch Oberflächen sehen unter anderem Winkel anders aus. So wie du es beschreibst, stell ich mir vor, dass du wie ein Bergarbeiter mit einer Helmlampe durch deine 3d-Welt springst

-
Vielleicht sollte ich genauer erklären, was ursprünglich passierte und was ich eigentlich will, "Bergarbeiter mit Helmlampe" ist nämlich kein passendes Bild:
Das will ich:
Man stelle sich z.B. einen von der Sonne (directional) beleuchteten Tisch vor.
Ich will diesen Tisch von allen Seiten betrachten können (Genau genommen von einer Sphäre konstanten Radius aus - es handelt sich hier nicht um ein Spiel mit 1st Person Perspektive!). In diesem Sinne soll sich nichts am Verhälnis Lichtquelle - beleuchtetes Objekt ändern. Die Sonne geht ja auch nicht unter, nur weil ich um einen Tisch wandere! (Es sei denn, ich lass mir dafür seeeeehhhr viel Zeit....;))Das passierte in der Situation meines ersten Beitrags:
Ich konnte meinen Tisch von allen Seiten betrachten, aber es sah aus, als würde ich den Tisch drehen, statt mich darum zu bewegen!bzw. nochmal als Code:
Der im Sonnenlicht gedrehte Tisch (unerwünscht)://rotation um z-Achse: FLOAT fAngle = dieses->m_rotz * (2.0f * D3DX_PI) / 360.0f; //"dieses" ist ein Ersatz für den "this" Zeiger in statischen Funktionen. D3DXMatrixRotationZ( &matWorld, fAngle ); //Roatation um x-Achse FLOAT fAnglex = dieses->m_rotx * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationX( &matWorld2, fAnglex ); matWorld2 = matWorld * matWorld2; m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld2 ); //Lichtrichtung; D3DXVECTOR3 vecDir; D3DLIGHT9 light; ZeroMemory( &light, sizeof(D3DLIGHT9) ); light.Type = D3DLIGHT_DIRECTIONAL; vecDir = D3DXVECTOR3(0,0,-1); D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );Und jetzt:
Von allen Seiten betrachtbarer Tisch: (nur eine Zeile verändert)//rotation um z-Achse: FLOAT fAngle = dieses->m_rotz * (2.0f * D3DX_PI) / 360.0f; //"dieses" ist ein Ersatz für den "this" Zeiger in statischen Funktionen. D3DXMatrixRotationZ( &matWorld, fAngle ); //Roatation um x-Achse FLOAT fAnglex = dieses->m_rotx * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationX( &matWorld2, fAnglex ); matWorld2 = matWorld * matWorld2; m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld2 ); //Lichtrichtung; D3DXVECTOR3 vecDir; D3DLIGHT9 light; ZeroMemory( &light, sizeof(D3DLIGHT9) ); light.Type = D3DLIGHT_DIRECTIONAL; //EINZIGE ÄNDERUNG ZU OBEN: vecDir = D3DXVECTOR3(0,sinf(dieses->m_rotx * D3DX_PI / 180.0f),-1 * cosf(dieses->m_rotx * D3DX_PI / 180.0f)); D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );Und die Frage ist:
Gibt es zum Erreichen dieses Effektes (Betrachten des Tischs in der Sonne von verschiedenen Seiten) eine einfachere Alternative?
-
Ich konnte meinen Tisch von allen Seiten betrachten, aber es sah aus, als würde ich den Tisch drehen, statt mich darum zu bewegen!
Das ist doch das gleiche

Lichtquellen bewegen sich normal nicht, bzw werden nicht gedreht oder skaliert. Das einzige wo sie bewegt werden, ist wenn du eine Straßenlampe darstellst und der Beobachter sich rel. zu der Lampe bewegt.
Vor allem sowas wie die Sonne bewegt sich doch nicht.
-
DEvent schrieb:
Ich konnte meinen Tisch von allen Seiten betrachten, aber es sah aus, als würde ich den Tisch drehen, statt mich darum zu bewegen!
Das ist doch das gleiche

Habe ich mich wohl schon wieder missverständlich ausgedrückt...
Unter "von allen Seiten betrachten" verstehe ich (wie ein anderes Mal auch so formuliert) sowas wie: Drumherumgehen, aber immer auf den Tisch gucken.
Das heißt:
Die Tischplattenoberseite ist immer beleuchtet, egal von wo aus ich den Tisch betrachte.
Wenn man den Tisch dagegen dreht (was ich ja nicht will...), dann kann die Tischplattenobersite auch der Sonne abgewandt sein, z.B. wenn der Tisch auf den Kopf steht.In diesem Sinne also nochmal:
Ich will den "Tisch" nicht im Raum drehen, sondern ich will um ihn herumschweben und ihn dabei immer betrachten.DEvent schrieb:
Lichtquellen bewegen sich normal nicht, bzw werden nicht gedreht oder skaliert. Das einzige wo sie bewegt werden, ist wenn du eine Straßenlampe darstellst und der Beobachter sich rel. zu der Lampe bewegt.
Vor allem sowas wie die Sonne bewegt sich doch nicht.Ich will ja außer der Kamera auch gar nichts bewegen/drehen/skalieren.
Gruß,
Dong
-
Ich will ja außer der Kamera auch gar nichts bewegen/drehen/skalieren.
Dann machst doch nicht. Kamera ist doch ein extra Koordinatensystem, da wird das Licht mitberechnet.
Also als ich programmier habe, da wird das Licht mitberechnet wenn ich die Kamera drehe. Also unter OpenGL und DirectX.
Du musst das Licht auch vor der Welt-Transformation (die Kamera) setzen.
Normal ist es doch so:1. Licht setzen
2. Objekt rendern
3. Kamera setzenMan muss immer beachten das die Grafik-API eine State-Machine ist, das heist die Reihenfolge der Befehle ist wichtig.
Wenn du so machst, wird das Licht auch nicht mitberechnet
1. Objekt rendern
2. Kamera setzen
3. Licht setzenEs seih den ich erzähl grade totalen Schwachsinn, weil ich vom joggen erschöpft bin...
-
Setzt man nich zuerst die Kamera und dann rendert man? (in OGL)
-
Jo klar, sonst weiß die Grafikkarte ja garnicht was sie rendern muß.
-
DEvent schrieb:
Ich will ja außer der Kamera auch gar nichts bewegen/drehen/skalieren.
Dann machst doch nicht. Kamera ist doch ein extra Koordinatensystem, da wird das Licht mitberechnet.
Womit wir wieder bei meiner Frage aus dem ersten Beitrag dieses Threads sind, denn genau das versuchte ich doch!
Erste Frage zur Sicherheit:
Die Kameraperspektive stelle ich mit der view Matrix ein, oder?Dann noch mal zur Frage von oben:
Warum funktioniert dann folgendes nicht:D3DXVECTOR3 vEyePt(dieses->m_kamera_dist * dieses->m_kamera_x, dieses->m_kamera_dist * dieses->m_kamera_y, dieses->m_kamera_dist * dieses->m_kamera_z); D3DXVECTOR3 vLookatPt( dieses->m_lookat_x, dieses->m_lookat_y, dieses->m_lookat_z ); D3DXVECTOR3 vUpVec( 0.0f, 0.0f, 1.0f ); D3DXMATRIXA16 matView, matView2; fAngle = dieses->m_rotz * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationZ( &matView, fAngle ); fAnglex = dieses->m_rotx * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationX( &matView2, fAnglex ); matView2 = matView * matView2; D3DXMatrixLookAtLH( &matView2, &vEyePt, &vLookatPt, &vUpVec ); m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView2 );obwohl doch nahezu dasselbe zuvor mi der World Matrix klappte?:
D3DXMATRIXA16 matWorld, matWorld2; FLOAT fAngle = dieses->m_rotz * (2.0f * D3DX_PI) / 360.0f; // fAngle = 0; //ist auskommentiert bei Versuchen die View Matrix zu drehen D3DXMatrixRotationZ( &matWorld, fAngle ); FLOAT fAnglex = dieses->m_rotx * (2.0f * D3DX_PI) / 360.0f; // fAnglex = 0; //ist auskommentiert bei Versuchen die View Matrix zu drehen D3DXMatrixRotationX( &matWorld2, fAnglex ); matWorld2 = matWorld * matWorld2; m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld2 );DEvent schrieb:
Also als ich programmier habe, da wird das Licht mitberechnet wenn ich die Kamera drehe. Also unter OpenGL und DirectX.
Du musst das Licht auch vor der Welt-Transformation (die Kamera) setzen.
Normal ist es doch so:1. Licht setzen
2. Objekt rendern
3. Kamera setzenMan muss immer beachten das die Grafik-API eine State-Machine ist, das heist die Reihenfolge der Befehle ist wichtig.
Wenn du so machst, wird das Licht auch nicht mitberechnet
1. Objekt rendern
2. Kamera setzen
3. Licht setzenIch mahce es wie in den Tutorials des DirectX SDK:
Die Renderfunktion ruft erst eine SetupLights() Funktion auf, dann eine SetupMatrices() Funktion und dann wird gerendert.Gruß,
DongP.S.:
Ist jetzt aber echt nicht mehr so furchbar wichtig, da ich das Problem ja mittlerweile auch anders (gemeinsame Drehung der Worl Matrix und der Lichtrichtung) in den Griff bekommen habe...
-
dong schrieb:
D3DXVECTOR3 vEyePt(dieses->m_kamera_dist * dieses->m_kamera_x, dieses->m_kamera_dist * dieses->m_kamera_y, dieses->m_kamera_dist * dieses->m_kamera_z); D3DXVECTOR3 vLookatPt( dieses->m_lookat_x, dieses->m_lookat_y, dieses->m_lookat_z ); D3DXVECTOR3 vUpVec( 0.0f, 0.0f, 1.0f ); D3DXMATRIXA16 matView, matView2; fAngle = dieses->m_rotz * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationZ( &matView, fAngle ); fAnglex = dieses->m_rotx * (2.0f * D3DX_PI) / 360.0f; D3DXMatrixRotationX( &matView2, fAnglex ); matView2 = matView * matView2; D3DXMatrixLookAtLH( &matView2, &vEyePt, &vLookatPt, &vUpVec ); m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView2 );Was zur Hölle tust Du denn da? Du berechnest erst mit viel Aufwand dieses matView2 und danach rufste LookAt auf und überschreibst das wieder.
-
@Jester:
Ah, so ist das!
Das ist aber nicht nett, dass beim Aufruf einer Funktion ein Argument variiert wird.
(Ja, ich weiß:
1. Mit einer Referenz als argument ist das möglich.
2. Das hätte ich irgendwo selber nachlesen können.)Danke, die Umkehrung der Reihenfolge werde ich gleich mal ausprobieren!

Nachtrag:
Ja, jetzt klappt natürlich auch die Beeinflussung der View-Matrix.