Seite 1 von 1

[Erledigt]Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 12.01.2016, 01:31
von zfxacc32
Hi,

ich habe ein Spiel (ohne Quellcode) von Direct3D 8 nach 9 "konvertiert", indem ich die Direct3D Interfaces gehookt und die Funktionen weitergeleitet habe (mit ein paar Anpassungen von zB. Strukturen/Parametern).
Das funktioniert auch ganz gut, doch mit der Beleuchtung der Charaktere stimmt etwas nicht.

Demonstration:

Normal (Direct3D 8):
licht1-1.jpg
Falsch (Direct3D 9):
licht1-2.jpg
Normal (Direct3D 8):
licht2-1.jpg
Falsch (Direct3D 9):
licht2-2.jpg
Als GIF, wenn ihr es in Bewegung sehen wollt (12 und 18 MB):
http://ecjgtkr5kjn7v92d.blob.core.windo ... licht1.gif
http://ecjgtkr5kjn7v92d.blob.core.windo ... licht2.gif

Ich habe leider nicht so viel Ahnung von Direct3D und frage mich, woran das liegen könnte.
Sind bei Direct3D 9 irgendwelche Standardeinstellungen/States anders? Ich hab in der Doku leider nichts gefunden, sieht alles ziemlich gleich aus.

Bin für jeden Hinweis dankbar.
MfG

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 12.01.2016, 11:31
von Schrompf
Hm. Sieht aus, als würden die Normalen im Skinning anders behandelt. Schau mal nach irgendwelchen States zum Thema "Inverse Transpose". Was auch sein könnte: bei DX8 hat man ja Skinning noch häufig auf der CPU gemacht. Könnte also auch sein, dass die da ein besonders komprimiertes Vertexdatenformat für die Normalen benutzen. Wobei ich glaube, dass das Licht dann nicht so falschrum mitrotieren würde, aber ausschließen würde ich es nicht.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 12.01.2016, 14:56
von Krishty
Das mit den GIFs ist eine riesen Hilfe, aber könntest du vielleicht nochmal eins machen, in dem sich ein Character um sich selber dreht? Ich tippe ebenfalls auf Schrompfs Vorschlag, dass die Lichtrichtung beim Bone Skinning nicht transformiert wird. Mit einem GIF von einem Charakter, der sich einmal um sich selber dreht, könnten wir erkennen, ob die Beleuchtung mitrotiert oder nicht oder in die falsche Richtung.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 12.01.2016, 17:30
von zfxacc32
Klaro, hier bitte, auch als mp4 Video (3.5MB, muss vielleicht manuell gespeichert werden).

Richtig:
http://ecjgtkr5kjn7v92d.blob.core.windo ... light1.gif
http://ecjgtkr5kjn7v92d.blob.core.windo ... light1.mp4

Falsch:
http://ecjgtkr5kjn7v92d.blob.core.windo ... light2.gif
http://ecjgtkr5kjn7v92d.blob.core.windo ... light2.mp4

Nur sagen, wenn ihr noch mehr input braucht :)

Ich gucke mal im assembler, ob ich da was finde...

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 12.01.2016, 18:41
von dot
Ja, da werden definitv die Normalen nicht richtig transformiert...

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 13.01.2016, 08:33
von zfxacc32
Danke erstmal.
Ich würde das Ganze gerne eingrenzen. Wonach müsste ich suchen? (Wie wird das Transformieren gemacht? Welche D3D Funktionen werden benötigt?)
Woran könnte es liegen, dass es mit Direct3D 9 plötzlich nicht mehr funktioniert? Es wurde ja am Code nichts verändert, bloß das D3D 8 Interface durch das 9er ersetzt.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 22.01.2016, 12:54
von zfxacc32
Was ich herausgefunden habe:
D3DRS_LIGHTING ist false und D3DFVF_NORMAL wird nicht gesetzt.
Es werden auch keine vertex shader benutzt (CreateVertexShader wird nie aufgerufen).

Aber wie funktioniert dann die Beleuchtung?

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 22.01.2016, 13:08
von Schrompf
Fixed Function? Welche FVFs sind denn gesetzt? Und wird der VertexBuffer jedes Frame aktualisiert oder ist der statisch?

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 22.01.2016, 14:40
von zfxacc32
Schrompf hat geschrieben:Fixed Function?
Heißt das, D3D berechnet die Normalen?
Es wird übrigens SetLight() aufgerufen.
Schrompf hat geschrieben:Welche FVFs sind denn gesetzt? Und wird der VertexBuffer jedes Frame aktualisiert oder ist der statisch?
Mit ziemlicher Sicherheit XYZ, DIFFUSE und TEX.
Die zweite Frage kann ich momentan nicht beantworten, warum ist das denn wichtig? Ich denke mal, dass der VB für die Person immer gleich ist.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 24.01.2016, 23:33
von Degenerated
zfxacc32 hat geschrieben:Die zweite Frage kann ich momentan nicht beantworten, warum ist das denn wichtig? Ich denke mal, dass der VB für die Person immer gleich ist.
Das muss nicht sein. Gerade damals wurden Animationen oft (immer?) auf der CPU ausgerechnet und dann eben der Buffer neu befüllt, mit den transformierten Vertices.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 25.01.2016, 00:38
von zfxacc32
Okay.
Was ich gerne gewusst hätte, wären alle Möglichkeiten, Beleuchtung zu implementieren.
DirectX 8.1 SDK
When you use Direct3D lighting and materials, you allow Direct3D to handle the details of illumination for you. Advanced users can perform lighting on their own, if desired.
Ich denke damit ist gemeint, dass entweder D3DRS_LIGHTING gesetzt ist und die Normalen mit im Vertexbuffer sein müssen (was scheinbar nicht der Fall ist) oder eben D3DRS_LIGHTING false ist und alle vertex colors manuell ausgerechnet werden müssen.
Stimmt das so?

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 25.01.2016, 10:10
von Schrompf
Richtig. Und falls das FVF keine Normalen enthält, geht das automatische Beleuchten nicht. Es kann aber durchaus eine Mischkalkulation sein, bei der das Lighting dann nur noch einen Ambient-Teil statisch aufaddiert und die Werte im VertexBuffer den dynamischen Teil enthalten. Die Leute damals waren kreativ im Erfinden exotischer Speziallösungen.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 26.01.2016, 00:44
von zfxacc32
// EDIT: Ups, Auslesen der FVF flags korrigiert

Ich habe mich geirrt. Nach einer etwas ausführlicheren Analyse ist nun klar: Es wird D3DFVF_NORMAL benutzt.
So sehen die Aufrufe während dem Zeichnen des Körpers aus:

Zu Beginn:

Code: Alles auswählen

Device::SetTransform: D3DTS_VIEW, 
Device::SetTransform: D3DTS_PROJECTION, 
Device::SetTransform: 256, 
Device::SetTransform: 256 bis 283 
Mehrmals hintereinander:

Code: Alles auswählen

Device::SetRenderState: D3DRS_VERTEXBLEND, D3DVBF_1WEIGHTS, 
Device::SetRenderState: D3DRS_INDEXEDVERTEXBLENDENABLE, true, 
Device::SetIndices: 0, 

// Abwandlung
Device::SetRenderState: D3DRS_VERTEXBLEND, D3DVBF_DISABLE, 
Device::SetRenderState: D3DRS_INDEXEDVERTEXBLENDENABLE, false, 
Device::SetTransform: 256, 
Device::SetIndices: 0, 

Device::SetStreamSource: 0, 327398776, 40, 
Device::SetVertexShader: D3DFVF_XYZB2, D3DFVF_NORMAL, D3DFVF_TEX1, D3DFVF_LASTBETA_UBYTE4 (Abwandlung:  D3DFVF_XYZ, D3DFVF_NORMAL, D3DFVF_TEX1)
Device::SetLight: 
Device::SetRenderState: D3DRS_FOGENABLE, true, 
Device::LightEnable: true, 
Device::SetLight: 
Device::SetLight: 
Device::SetLight: 
Device::SetLight: 
Device::SetRenderState: D3DRS_NORMALIZENORMALS, false, 
Device::SetRenderState: D3DRS_AMBIENT, 
Device::SetMaterial: 
Device::ApplyStateBlock: 25, 
Device::SetRenderState: D3DRS_ALPHATESTENABLE, false, 
Device::SetRenderState: D3DRS_ZWRITEENABLE, true, 
Device::SetRenderState: D3DRS_ZENABLE, D3DZB_TRUE, 
Device::SetRenderState: D3DRS_ZFUNC, D3DCMP_LESSEQUAL, 
Device::SetRenderState: D3DRS_ALPHABLENDENABLE, true, 
Device::SetRenderState: D3DRS_SRCBLEND, D3DBLEND_SRCALPHA, 
Device::SetRenderState: D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA, 
Device::SetTexture: 0, 
Device::SetTextureStageState: 0, D3DTSS_ADDRESSU, D3DTEXTUREADDRESS, 
Device::SetTextureStageState: 0, D3DTSS_ADDRESSV, D3DTEXTUREADDRESS, 
Device::SetTextureStageState: 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR, 
Device::SetTextureStageState: 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE, 
Device::DrawIndexedPrimitive: D3DPT_TRIANGLELIST, 0, 46, 0, 59, 
State Block 25:

Code: Alles auswählen

Device::SetTextureStageState: 0, D3DTSS_COLOROP, D3DTOP_MODULATE, 
Device::SetTextureStageState: 0, D3DTSS_COLORARG1, D3DTA_TEXTURE, 
Device::SetTextureStageState: 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE, 
Device::SetTextureStageState: 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE, 
Device::SetTextureStageState: 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE, 
Device::SetTextureStageState: 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE, 
Device::SetTextureStageState: 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 0, D3DTSS_TEXCOORDINDEX, 0, 
Device::SetTextureStageState: 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 1, D3DTSS_TEXCOORDINDEX, 1, 
Device::SetTextureStageState: 1, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 2, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 2, D3DTSS_TEXCOORDINDEX, 2, 
Device::SetTextureStageState: 2, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 3, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 3, D3DTSS_TEXCOORDINDEX, 3, 
Device::SetTextureStageState: 3, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 3, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 4, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 4, D3DTSS_TEXCOORDINDEX, 4, 
Device::SetTextureStageState: 4, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 4, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 5, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 5, D3DTSS_TEXCOORDINDEX, 5, 
Device::SetTextureStageState: 5, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 5, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 6, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 6, D3DTSS_TEXCOORDINDEX, 6, 
Device::SetTextureStageState: 6, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 6, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 7, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE, 
Device::SetTextureStageState: 7, D3DTSS_TEXCOORDINDEX, 7, 
Device::SetTextureStageState: 7, D3DTSS_COLOROP, D3DTOP_DISABLE, 
Device::SetTextureStageState: 7, D3DTSS_ALPHAOP, D3DTOP_DISABLE, 
Ja, stimmt, die Animationen werden wohl "manuell" gemacht. Es werden keine Shader verwendet. Der vertex buffer ist auch immer ein anderer..
Das Spiel hat ein eigenes Modellformat. Ich nehme an, dass die Normalen darin gespeichert sind. Doch was ist mit den Animationen? Ist es üblich/sinnvoll, die Normalen für jedes Animationsframe separat zu speichern?

Leider bleibt die Frage offen, wie es sein kann, dass die Normalen plötzlich nicht mehr korrekt sind.. die D3D Funktionen geben auch immer S_OK zurück.

Re: Direct3D 8 zu 9 Konvertierung: Falsche Beleuchtung

Verfasst: 26.01.2016, 19:47
von zfxacc32
Könnte es vielleicht an der Reihenfolge der Aufrufe liegen?
zB. das Setzen der vertex blending matrices zu Beginn (Device::SetTransform: 256 bis 283). Vielleicht muss das bei D3D 9 anderswo stehen? (Ich weiß, unwahrscheinlich).
Bin momentan ratlos :(

Ich hab auch mal versucht, die Normalen des characters zu zeichnen (bei jedem dazugehörigen DrawIndexedPrimitive() Aufruf die Vertices+Normalen aus dem gesetzten VB in einen eigenen kopieren und als D3DPT_LINELIST darstellen).
Mir werden jedoch nur die Normalen des Kopfes angezeigt, nicht aber die des restlichen Körpers (die Beleuchtung des Kopfes scheint in D3D9 übrigens korrekt, siehe das Gif/Video).
Habe die Koordinaten geloggt, sind bei D3D 8 und 9 dieselben. Ich vermute also, dass es am vertex blending liegt.

Code: Alles auswählen

vertex xyz, vertex+normal xyz

D3DFVF_XYZB3, D3DFVF_NORMAL, D3DFVF_TEX1, D3DFVF_LASTBETA_UBYTE4
-0.0616953 / -0.00293348 / 0.56213 / -0.0614068 / -0.224591 / 0.818684
-0.0456624 / 0.0174519 / 0.581081 / -0.25753 / -0.0290028 / 0.965946
-0.0481068 / 0.0288982 / 0.602599 / -0.188044 / 0.0916261 / 0.826825
...

D3DFVF_XYZ, D3DFVF_NORMAL, D3DFVF_TEX1
-581.704 / 911.786 / 94.8275 / -581.586 / 911.743 / 94.0481
-581.698 / 911.78 / 94.8297 / -581.394 / 911.751 / 94.1153
-581.705 / 911.784 / 94.8255 / -581.382 / 912.247 / 94.0737
...
Der character steht ingame übrigens ca. an Kameraposition 581/911.

Re: [Erledigt]Direct3D 8 zu 9 Konvertierung: Falsche Beleuch

Verfasst: 27.01.2016, 11:51
von zfxacc32
Geschafft!

Ich hatte ja mal versucht, für diese Engine hardware vertexprocessing zu aktivieren, was aber entweder zu Crashes oder Grafikfehlern führte.
Nun hab ich es endlich geschafft. Es war bloß eine fehlende Nullzeiger-Prüfung, die den Crash verursacht hat.

Netter Nebeneffekt: Die Beleuchtung ist nun auch korrekt!

(Vermutung: D3D9 kommt mit vertex blending und software vertexprocessing nicht so gut klar wie D3D8).