The Lord of Programming Living Legend
Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 20.06.2007, 20:18 Titel: [Direct3D9] Z-Buffer hat keine Wirkung |
|
|
Frage:
Ich habe den ZBuffer per SetRenderState(D3DRS_ZENABLE,TRUE); aktiviert.
Trotzdem zeigt er keine Wirkung oder spielt verrückt.
Was kann ich tun? Ich bin so verzweifelt.
Antwort:
Dabei gilt es, mehrere Dinge zu beachten:
- Leeren des Z-Buffers:
Wie normalerweise am Anfang des Rendervorgangs der gesamte Bildschirm(bzw. Backbuffer) geleert wird, so soll auch der Z-Buffer geleert werden. Dieses Leeren entspricht dem Zuweisen von einem festgesetzten Wert für jeden Pixel des Buffers.
Wird es weggelassen, so werden alte Werte nicht überschrieben. Im Fall des Backbuffers werden so bereits gezeichnete Objekte nicht gelöscht und sind u.U. immer noch sichtbar, sofern die betreffenden Pixel nicht überschrieben wurden. Beim Z-Buffer sieht dies ähnlich aus. Allerdings ist dieser als Fehlerquelle für manchen Einsteiger schwerer zu erkennen. Dennoch bleibt das Prinzip gleich: Die gespeicherten Tiefenwerte des Z-Buffers werden nicht zwangsweise überschrieben und können so zu unliebsamen Effekten führen.
Die Lösung ist ein ein einfaches Leeren dieses Buffers am Anfang des Rendervorgangs. Ein Aufruf der Clear()-Methode des D3D9-Devices sollte in etwa so aussehen:
CPP: | //Leert Backbuffer UND Z-Buffer
cDevice->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,Color,1.0f,0); |
Wichtig ist das hinzugekommene "D3DCLEAR_ZBUFFER" und der 5. Parameter, der den Initialisierungswert für den Z-Buffer darstellt. Idealerweise sollte er auf 1.0f stehen.
Das Leeren von Backbuffer und Z-Buffer kann so durch einen einzelnen Aufruf von Clear() durchgeführt werden.
Sicherstellen, dass Z-Buffer nicht ignoriert wird:
Über die DirectX-Schnittstelle muss dem Device mitgeteilt werden, dass ein Z-Buffer verwendet wird. Dies wird beim Aufruf von CreateDevice() getan.
Die D3DPRESENT_PARAMETERS-Struktur, von der bereits eine Instanz initialisiert sein sollte, besitzt zwei Member, die zwangsweise gesetzt werden müssen, damit ein Z-Buffer korrekt arbeiten kann.
CPP: | D3DPRESENT_PARAMETERS present_params;
//[...]
present_params.EnableAutoDepthStencil = TRUE;
present_params.AutoDepthStencilFormat = D3DFMT_D16; |
Der erste der beiden legt fest, dass ein Tiefenbuffer verwendet(=erstellt, benutzt und wieder zerstört) werden soll. Ums Erstellen, Benutzen und Zerstören kümmert sich das Device selbst (sofern alles beachtet wird, versteht sich ). Der zweite legt das Format des Buffers fest. Eine Alternative zu D3DFMT_D16 wäre z.B. das 32-Bit-starke Format D3DFMT_D32, was einen genaueren Z-Test gewährleistet. Allerdings ist hier Vorsicht geboten, da auf vielen Grafikkarten nur 16-Bit-Z-Buffer möglich sind. (Wer die best mögliche Alternative anbieten will, verwendet am besten die D3D-Caps.)
Near-Clippingplane & Far-Clippingplane:
Beim Erstellen einer Projektionsmatrix werden im Normalfall die beiden Ebenen (orthogonal zur Z-Achse = "in den Bildschirm hinein") angegeben, die den zu rendernden Sichtbereich festlegen.
Achtung: Hier für die Near-Clippingplane nicht den Abstand 0.0f zur Kamera angeben! Dies führt bei den ablaufenden Matrizenberechnungen zu Ungenauigkeiten, die dazu führen können, den gesamten Z-Buffer "lahmzulegen". Auch die Einschränkung des Sichtbereichs kann so nicht gewährleistet werden.
Sollten kleine Fehler beim Z-Testing auftreten, so ist dazu zu raten, den Abstand zwischen Near- und Far-Clippingplane zu verkleinern. Ein zu großer Abstand kann Ursache für Ungenauigkeiten sein.
Auch eine Anpassung des Z-Buffer-Formats(siehe vorheriger Punkt) kann die Genauigkeit verbessern.
Vorsicht bei Wechsel:
Ein Wechsel der Projektions- oder Sichtmatrix ist mit Vorsicht zu genießen. Ohne das Leeren des Z-Buffers stimmt die Zuordnung eines Tiefenwerts zu einem Pixel nicht mehr.
Das Weiterbenutzen eines beschriebenen Z-Buffers bei geänderter Matrix kann zu Chaos führen.
_________________ www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console
Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet... |
|