+- +-

Benutzer

Welcome, Guest.
Please login or register.
 
 
 
Forgot your password?

Autor Thema: Frage zu DirectX 9.0c und Z-Buffer  (Gelesen 2075 mal)

kokunze

  • Abteilungstrident
  • Buchstabenmillionär
  • Beiträge: 1.167
    • Profil anzeigen
Frage zu DirectX 9.0c und Z-Buffer
« am: 20. November 2006, 19:33:54 »
Diese Frage geht an Leute, die bereits ein wenig mit C++ und Direct X programmiert haben:

Ich hab eine kleine 3D Engine geproggt, allerdings ein Problem dabei. Viele Polygone liegen exakt an der gleichen Stelle, was bei Rotation dieser zu Darstellungsfehlern führt. Das ganze nennt sich "Z-Fighting" weil 2 Polygone an der gleichen Stelle sind und der Z-Buffer nicth weiß, welches er eintragen soll.

Die Frage ist wie ich das Problem lösen kann. Hab jetz Ewigkeiten im Netz gesucht und bin immer wieder auf Depth-Bios gestoßen. Das ganze klingt zwar ganz nett, aber ich versteh net ganz die Berechnung des Bias und des Slope Wertes, damit das ganze Problemlos funktioniert.

Also die relevanten Daten meiner Engine:
Near Clip: 1.0f
Far Clip: 1000.0f
DepthStencilFormat: D3DFMT_D16

Die darstellbaren Objekte liegen irgendwo zwischen 20 und 100 vom Ursprung entfernt.

Ich wollte nun jedem Objekt (Quader) einen eigenen Bias Wert geben, so das wenn 2 Polygone übereinander sind das neuere gezeichnet wird. Leider funktionierte das mit diversem rumprobieren nicht. Ich brauch also eine genaue Berechnungsgrundlage, wie der Slope sein muss und um wieviel ich den Bias pro Durchlauf erhöhen muss, so das keine Artefakte mehr beim rendern entstehen.

Der eigentliche Renderdurchlauf:

for (int i=0; i < g_iMaxCubes; i++)
{
 g_App.GetDevice()->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, g_fSlopeBias);
 g_App.GetDevice()->SetRenderState(D3DRS_DEPTHBIAS, g_fBias*i);
 g_App.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,i*8,0,8,0,12);      
}   

g_App.GetDevice()->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0.0f);
g_App.GetDevice()->SetRenderState(D3DRS_DEPTHBIAS, 0.0f);

kokunze

  • Abteilungstrident
  • Buchstabenmillionär
  • Beiträge: 1.167
    • Profil anzeigen
Re: Frage zu DirectX 9.0c und Z-Buffer
« Antwort #1 am: 21. November 2006, 12:31:48 »
Also mehrstufiges Rendern, erhöhen der Bitzahl oder verschieben der Planes würde da nich wirklich was bringen. Die Polygone liegen ja nicht zu nah beieinander sondern real aufeinander. Also haben identische Koordinaten.

Wie kommst du auf die 999 Stufen in die man es unterteilen soll? Hab bisher immer gehört, das die Abstufung immer gröber wird, je weiter man sich von der Near Plane entfernt.


Microsoft sagt zu der Berechnung im übrigen folgendes:
Zitat von: microsoft
An application can help ensure that coplanar polygons are rendered properly by adding a bias to the z-values that the system uses when rendering the sets of coplanar polygons. To add a z-bias to a set of polygons, call the IDirect3DDevice9::SetRenderState method just before rendering them, setting the State parameter to D3DRS_DEPTHBIAS, and the Value parameter to a value between 0-16 inclusive. A higher z-bias value increases the likelihood that the polygons you render will be visible when displayed with other coplanar polygons.

Offset = m * D3DRS_SLOPESCALEDEPTHBIAS + D3DRS_DEPTHBIAS

where m is the maximum depth slope of the triangle being rendered.

m = max(abs(delta z / delta x), abs(delta z / delta y))

The units for the D3DRS_DEPTHBIAS and D3DRS_SLOPESCALEDEPTHBIAS render states depend on whether z-buffering or w-buffering is enabled. The application must provide suitable values.

The bias is not applied to any line and point primitive. However, this bias

allerdings ist es für mich ein Rätsel, was delta x, y und z sind. Abstände von Polygonen? Ausmaße von Objekten? Keine Ahnung...


Am besten wäre wenn ich ne Art Indizes oder Prioritäten verteilen könnte. So das er wenn er 2 gleiche Anwärter für einen Eintrag im Z-Buffer hat, den mit der höheren Priorität nimmt. Gibts da ne Möglichkeit das zu realisieren?

kokunze

  • Abteilungstrident
  • Buchstabenmillionär
  • Beiträge: 1.167
    • Profil anzeigen
Re: Frage zu DirectX 9.0c und Z-Buffer
« Antwort #2 am: 21. November 2006, 18:45:06 »
habs hinbekommen...
musste noch den float in double umwandeln (sonst hat er nur mist gemacht) und dann bisse rumfriemeln mit den Feineinstellungen, aber nun gehts

kokunze

  • Abteilungstrident
  • Buchstabenmillionär
  • Beiträge: 1.167
    • Profil anzeigen
Re: Frage zu DirectX 9.0c und Z-Buffer
« Antwort #3 am: 22. November 2006, 12:56:48 »
Also slope und bias sind beides globale Floats, die man per Tastatureingaben feintunen kann. (oder per Ini Datei)
Damit konnt ich während der laufzeit rumprobieren bis es gut klappte.

Die Inline-Methode zum umwandeln:

Zitat von: Mein Quelltext
inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }

und hier der Ausschnitt aus der Renderfunktion:
Zitat von: Mein Quelltext
for (int i=0; i < g_iMaxCubes; i++)
{
 g_App.GetDevice()->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(g_fSlopeBias));
 g_App.GetDevice()->SetRenderState(D3DRS_DEPTHBIAS, F2DW(g_fBias*(float)i));
 g_App.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,i*8,0,8,0,12);      
}

Hier werden viele Index-Buffer gestützte Quader gerendert. Bei jedem einzelnen erhöht er den Bias um den ausgetüftelten Faktor.


Hauptproblem war am Anfang auch das ich dummerweise vergessen hab, den int i, mit einem Typecast (float) auszustatten. Dadurch berechnete er nur ganzzahlige Ergebnisse, was dann natürlich totalen Unsinn als Ergebniss hatte.

 

Benutzer Online

23 Gäste, 0 Mitglieder
Powered by EzPortal