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

lumpinus

Frischling

  • »lumpinus« ist der Autor dieses Themas

Beiträge: 27

Wohnort: Bad Münstereifel

  • Private Nachricht senden

1

07.11.2006, 15:48

Bone-Animation mit dem Vertex-Shader

Hallo zusammen!

Ich implementiere gerade eine Skinned-Mesh (also ein 3D-Modell mit Bones) in meiner Engine. Nun ist es ja am schnellsten wenn man das ganze Modell mit einem Draw-Call rendert. Das bedeutet ich weise jedem Vertex im Vertexformat eine BoneId zu, und im Vertexshader gelange ich dann über diese Id mit relativer Adressierung an die korrekte Matrix.

Dabei gibt es für jeden Joint zwei Matrizen:
-Transformationsmatrix für die Positionsvektoren
-Transformationsmatrix für die Normalenvektoren

D.h. acht Shader-Register pro Joint. Macht bei sagen wir 18 Joints 144 Register.

das ist natürlich eine ganze Menge und ich bin mir nicht mehr sicher ob dieser Ansatz wirklich der schnellste ist. Außerdem soll meine Engine mit dem ShaderModel 1 kompatibel sind, wo ja nur 96 Register da sind.

Wie regelt ihr das denn?

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

2

07.11.2006, 16:12

Hast Du Dir mal das DirectX SDK Beispiel zu dem Thema angeschaut? Das zeigt ja verschiedene Wege auf.

Ich habe gehört Skinning per Shader sei nicht soo viel schneller als per CPU.

Nimmst Du D3DX?
"Games are algorithmic entertainment."

lumpinus

Frischling

  • »lumpinus« ist der Autor dieses Themas

Beiträge: 27

Wohnort: Bad Münstereifel

  • Private Nachricht senden

3

07.11.2006, 16:26

Ja ich nehm D3DX.
Ich soll also für jeden Joint jeden einzelnen Vertex per Hand vor dem Rendern transformieren, den Vertexbuffer locken, kopieren und dann jeden Joint mit einem Draw-Call rendern??
Na wenn du meinst dass das schneller ist...

Aber auch jeden Joint einzeln mit Vertex Shader rendern muss lamer als mein Ansatz sein, weil ich erstens für jeden Joint einen Drawcall hab und für jeden Joint noch die zwei Matrizen übertragen muss.

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

4

07.11.2006, 16:36

btw: woher holst du dir die Joint- und Bone-Informationen? Ich mein, aus welchem 3D_Modell_format?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

lumpinus

Frischling

  • »lumpinus« ist der Autor dieses Themas

Beiträge: 27

Wohnort: Bad Münstereifel

  • Private Nachricht senden

5

07.11.2006, 16:44

Ich wandel das ms3d(Milkshape) Format mit einem Konverter in ein eigenes Format um
edit: Bone und Joint sind übrigens dasselbe

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

6

07.11.2006, 17:03

Zitat von »"Osram"«



Ich habe gehört Skinning per Shader sei nicht soo viel schneller als per CPU.


In andere Worten es ist schneller, aber nicht extrem viel schneller, d.h. andere Kriterien (Implementierungsaufwand, Debugbarkeit, freie Resourcen für anderes etc) können (!) für Dich wichtiger sein.

Habe gerade mal das MS Sample getestet:

fixed function non indexed 450 fps (fullscreen 500)
fixed function indexed 250
SW 350
Shader (asm oder HLSL macht keinen messbaren Unterschied, die angezeigten Werte schwanken sowieso extrem) 480 (fullscreen 650)

Also sind Shader auf meinem Rechner (nVidia 6800 go) ca 10-35% schneller, wenn ausser dem Rendern von Skinned Meshes nichts anderes gemacht wird. In BoB, dem Projekt an dem ich arbeite, sind "skinned meshes" die Ausnahme und nur Eye Candy, daher nehmen wir FFP.
"Games are algorithmic entertainment."

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

07.11.2006, 17:23

wenn du deine joints insofern limitierst, dass diese nur rotiert und verschoben werden können (was im allgemeinen reichen sollte, bei characteranimation sollte es sogar reichen nur zu rotieren).

damit kannst du zum transformieren der position ganz normal die matrix und für die normalen nur den 3x3 teil der matrix nehmen und brauchst nurmehr eine matrix (4 register).

ich hatte mal den gedanken, dass man mit quaternionen auf 2 register pro joint runterkommen könnte, habs aber bisher noch net getestet...

wegen performance...
das hängt vom konkreten fall ab denk ich.
zum einen hast du da einen Lock(), was schlecht ist.
zum andren brauchst du die transformierten daten evtl. selber (kollision etc.).
man könnte z.b. das rendern ganz auf der gpu machen und ein stark vereinfachtes (aber genug genaues) physikmodell für die kollision auf der CPU animieren.
das wird aber erst bei großen modellen was bringen, wenn der lock zu teuer wär etc...

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

8

07.11.2006, 19:30

Zitat von »"lumpinus"«

edit: Bone und Joint sind übrigens dasselbe


In der Praxis schon... In der Theorie aber nicht. Joints sind die Gelenkspunkte und Bones sind die Verbindungen zwischen zwei Gelenkspunkten. In der Praxis hat man dann lediglich einen Unterschied in der Handhabung, die Daten sind die selben!
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

lumpinus

Frischling

  • »lumpinus« ist der Autor dieses Themas

Beiträge: 27

Wohnort: Bad Münstereifel

  • Private Nachricht senden

9

07.11.2006, 20:25

Naja, ich brauch schon eine 4x4 Matrix weil ich ja jeden Vertex auch projezieren muss

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

07.11.2006, 20:30

du brauchst nur EINE viewprojectionmatrix für ALLE vertices...

Werbeanzeige