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

11

10.05.2004, 00:23

Zitat

Meine Frage ist nun aber wie ich diese Transformationsmatrix berechnen muss ?
Du hast zwei Möglichkeiten
1) Du errechnest die Matrizen manuell zusammen. Also im Code selbst
2) Du setzt alle Matrizen (Projection, View und World) als Konstanten und multiplizierst sie im Shader Code.

Such dir eine aus :) Für größere Shader programme ist Variante 1 besser, da man dann mehr Platz für die eigentlichen Daten hat ;)
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

MannyDasMammut

Treue Seele

  • »MannyDasMammut« ist der Autor dieses Themas

Beiträge: 76

Wohnort: Baden - Würtemberg / Achern

Beruf: Schüler

  • Private Nachricht senden

12

10.05.2004, 12:45

Wie meinst du das

Wie meinst du das alle 3 Matrizten selbs im C++ Code setzen und dann mit SetVertexShaderConstant(0,&mat,4); setzen. Soweit ist das Klar ich mach das auch so aber ich sehe in meiner Anwendung absolut nichts.

Ich benutze um die Projektionsmatrix zu erhalten:

GetTransform

von meinen Direct3D Device. Dann berechne ich das ganze so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
D3DXMATRIX mat,matView,matProj;

// View- und Projektionsmatrix hohlen
g_pD3DD->GetTransform(D3DTS_VIEW,&matView);
g_pD3DD->GetTransform(D3DTS_PROJECTION,&matProj);

// Die Weltmatrix wurde vorher aus den Rotationsmatrizen , Scalematrizen und Positionsmatrizen berechnet
// WorldViewProj Matriz berechnen
D3DXMatrixMultiply(&mat,&matView,&matWorld);
D3DXMatrixMultiply(&mat,&mat,&matProj);

// Nun als Shaderkonstante setzen
g_pD3DD->SetVertexShaderConstant(0,&mat,4); // Konstante benötigt größe von 4 (4* float) registern


Das Objekt wird über die FFP korekt dargestell ( Zu beginn meines Rendervorgangs wird die Viewmatrix immer neu gesetzt also sie ist sicher gesetzt auch die Projektion ist gesetz ich setze in der FFP also nur noch die Weltmatrix und mit Shader frag ich eben die beiden View und Proj ab).
Bei der Shaderkompillierung treten keine Fehler auf. Die Shaderversion wird unterstützt aber das Objekt ist nicht sichtbar ?????? Wieso ???
Werde ich hier eigentlich noch gebrauch ansonsten würd ich gerne nach Hause gehen und meine graue Wand anstarren.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

13

10.05.2004, 14:13

Quellcode

1
2
3
4
5
6
7
8
9
10
vs_1_1                       // version instruction
dcl_position v0              // declare register data
dcl_normal v4                // v0 is position, v4 is normal
dcl_color0 v7                // v7 is diffuse color
dcl_texcoord0 v8             // v8 is texture coordinates
m4x4 oPos, v0, c4            // transform vertices using view projection transform
dp3  r0, v4, c12             // perform lighting N dot L calculation in world
mul  oD0, r0.x , v7          // calculate final pixel color from light intensity and
                             // interpolated diffuse vertex color 
mov  oT0.xy , v8             // copy texture coordinates to output

Also so wie ich das sehe musst du vorher ein dcl_ Befehl aufrufen um v0 zu setzen. Vielleicht kann man postion auch direkt in den m4x4 Befehl setzen.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

10.05.2004, 21:03

damit du deine matrix richtig verwenden kannst, musst du sie transponieren, da das m4x4 nur ein makro is und sowas macht ( DX doku ):

Quellcode

1
2
3
4
dp4   r0.x, r1, c0
dp4   r0.y, r1, c1
dp4   r0.z, r1, c2
dp4   r0.w, r1, c3


eine matrix multiplikation geht zeile mal spalte.
da sich sowas aber schlecht machen lässt, transponiert ( spalten und zeilen vertauschen ) man die matrix und kann dann zeile * zeile rechnen mit dem gleichen ergebnis

ein typischer vertex shader der nix macht außer transformieren würde so aussehen:

Quellcode

1
2
3
4
5
6
7
;c0 - c3    ....Transponierte World x View x Projection Matrix

vs_1_1

dcl_position v0

m4x4 oPos, v0, c0


wobei das vertex format nur D3DFVF_XYZ

damits funzt müsste dein code also so aussehen:

vorausgesetzt dein vertex shader is richtig gesetzt

Quellcode

1
2
3
4
5
6
7
8
9
10
D3DXMATRIX mat,matWorld,matView,matProj; 

g_pD3DD->GetTransform(D3DTS_WORLD,&matWorld); 
g_pD3DD->GetTransform(D3DTS_VIEW,&matView); 
g_pD3DD->GetTransform(D3DTS_PROJECTION,&matProj); 

D3DXMatrixMultiply(&mat,&matWorld,&matView); 
D3DXMatrixMultiplyTranspose(&mat,&mat,&matProj); 

g_pD3DD->SetVertexShaderConstant(0,&mat,4);

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

15

10.05.2004, 21:34

naja diarötisch könnte man ja das ganze mit mul machen und dann addieren, das spart den trans schritt.
[edit]Wenn man die Kamera und die Projektion nicht ändert könnte man doch diese nur einmal setzen und dadurch auch wieder Leistung sparen, dann braucht man nur noch das m4x4 durch muls und add ersetzen und wieder hat man Arbeit vom der cpu genommen.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

16

10.05.2004, 21:43

?

MannyDasMammut

Treue Seele

  • »MannyDasMammut« ist der Autor dieses Themas

Beiträge: 76

Wohnort: Baden - Würtemberg / Achern

Beruf: Schüler

  • Private Nachricht senden

17

10.05.2004, 22:42

Ja richtig da habt ihr wohl recht.

Aber das Problem ist eigentlich das die GetTransform Methoden nur dreck liefern da ich ein pures 3D Device verwenden und da funktionieren diese GetXXX Funktionen scheinbar nicht.

Ich erweitere die Engine nur durch externe Plugins momentan schreibe ich an einem Plugin für shader. Das Problem ist das ich die View und Projektionsmatrix nicht selbst berechne ich brauche also eine andere möglichkeit an diese Matrizen zu kommen kennt ihr eine möglichkeit. Selbst speichern kann ich sie nicht ? Da ich sie nicht selbst erzeuge
Werde ich hier eigentlich noch gebrauch ansonsten würd ich gerne nach Hause gehen und meine graue Wand anstarren.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

18

10.05.2004, 23:17

Ihrgendwo muss ja Settransform aufgerufen werden, dann müsste auch Getransform gehen.
@dot also statt trans die 3 Matices multipizieren und setzen. Dann diesen code nutzen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vs_1_1 

dcl_position v0 
//zuerst die w
mul r0.w v0.w c0.w
mad r0.w v0.w c1.w r0.w
mad r0.w v0.w c2.w r0.w
mad r0.w v0.w c3.w r0.w
move oPos.w r0.w
// jetzt hab ich mir nen bein gestellt da ich nicht weis wie teilen geht
rcp r0.w r0.w

//x
mul r0.x v0.x c0.x
mad r0.x v0.x c1.x r0.x
mad r0.x v0.x c2.x r0.x
mad r0.x v0.x c3.x r0.x
mul oPos.x r0.x r0.w
//usw

Scheind zwar länger aber dann übernimmt die GPU das ganze. Man könnte jetzt noch sagen, wenn man die view und Projelktion nur einmal am start des spiels setzt: c0-c3 Projektion und view c4-c7 welt. Dann spart man sich wieder etwas arbeit, wenn man die View und Pro nur einmal multipliziert. Dann muss man nur noch 2 Matrices mal nehmen und auch das kann der Shader übernehmen-> noch mehr luft für die CPU.

[edit] also der code war komptlett falsch, aber ich habe ihn nach einiger Zeit hingemurkst. Also das Shader test prog von dem Sample Browser ist mit m4x4 und trans 850 fps schnell und meine version 990.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

19

11.05.2004, 13:53

evtl. gibts in deiner engine ja bereits methoden um die matrizen herauszubekommen.
oder du berechnest sie einfach selber
oder die engine is bereits so schlau die matizen in die vertex shader constanten zu schreiben -> mal nachsehen

20

11.05.2004, 14:10

Was für eine Engine nutzt du denn?

Zitat

Ihrgendwo muss ja Settransform aufgerufen werden, dann müsste auch Getransform gehen.
Stimmt. Irgendwo muss ich doch einstellen können wie die Projektionsmatrix aussehen soll und irgendwo muss ich ja auch die Worldmatrix setzen können. Dies kann die Engine nicht wircklich selber berechnen. Eine Get-Methode sollte es eigentlich dann auch geben. Ansonsten must du deinem PlugIn ebenfalls ein paar Set-Methode für die Matrizen verpassen. Zwar nicht unbedingt die beste Lösung aber eine ;)

Wenn die Engine ein Pure 3D-Device erzeugt gehen alle Get-Methode des Direct3D Devices nicht. Vieleicht kannst du ja hier einlenken und verhindern das die Engine ein Pure Device ereugt? Dann gehen auch wieder die Get-Methoden.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Werbeanzeige