Tipp 0503 Texturfilter (point, linear, anisotropic)
Autor/Einsender:
Datum:
  Alexander Csadek
20.07.2006
Entwicklungsumgebung:
DirectX-Version:
  VB 6
DirectX 8
Da Direct3D den 3D-Raum auf den zweidimensionalen Bildschirm rendert, kommt es bei den Texturen zu unschönen Effekten. Besonders dann, wenn die Textur verkleinert bzw. vergrößert wird. Dazu kommt noch, dass die Textur ja perspektivisch auf das Polygon gerendert werden muss.
Je näher man z.B. einer Wand kommt, desto größer werden die einzelnen Farbblöcke, und irgendwann reicht ein Pixel nicht mehr aus. Direct3D muss nun entscheiden, wie dieser Pixel-Block eingefärbt werden muss. Umgekehrt entsteht das gleiche Problem, je weiter wir von der Wand weggehen, desto kleiner wird die Textur, und Direct3D muss entscheiden, welche Pixel sind zu sehen und welche nicht. Die daraus entstehenden Ungenauigkeiten (visuelle Artefakte) können mit dem Einsatz von Textur-Filtern minimiert werden.
Nearest Point Sampling
Diese Technik, falls man hierbei überhaupt von Technik sprechen kann, ist sehr alt und funktioniert auf der Basis der Ganzzahlkoordinaten der Pixel am Bildschirm. So werden die Fliesskommawerte im 3D einfach aufgerundet und das entsprechende Farb-Pixel von der Textur genommen. Dieser Vorgang ist sehr schnell, aber die unschönen Artefakte können damit kaum verhindert werden. Im Direct3D ist dieser Texturfilter standardmäßig eingestellt, da so gut wie jede Grafikkarte diesen Filter unterstützt.
Linear Filter
Diese Technik ist auch als bilinearer Filter bekannt. Sie verbessert die Qualität deutlich, und wird von den Spiele-Herstellern meistens verwendet. Wenig detaillierte Texturen können bei dieser Technik verwaschen wirken, ein Effekt, der durch detailliertere Texturen kompensiert wird. Im Prinzip basiert diese Technik auf einem Weichzeichner. 
Die Farbwerte jedes Pixels werden zerlegt und mit den Farbwerten der Nachbarpixel vermischt. Die Hardware muss hierbei mehr berechnen als beim Nearest Point Filter und sollte eine Grafikkarte lineares Filtern nicht unterstützen, ist mit einem Performance-Verlust zu rechnen. Bei den modernen Grafikkarten ist dies eher unwahrscheinlich.
Ein optimales Ergebnis wird mit diesem Filter erreicht wenn ein Polygon senkrecht zum Betrachter im 3D-Raum steht, dies kommt wohl eher sehr selten vor, aber das Ergebnis ist trotzdem um einiges besser als das vom Nearest Point Filter.
Anisotropic Filter (uneinheitlicher Filter)
Da für diese Technik kein einheitlicher Algorithmus verwendet wird, ist das Ergebnis von der Grafikkarte abhängig und vom Algorithmus den der Hersteller bei diesem Filter verwendet. So kann es passieren, dass bei manchen Grafikkarten das Ergebnis schlechter als beim linearen Filter ist. In der Regel wird bei dieser Technik die Interpolation der neuen Pixel-Farbe an unregelmäßigen Formen durchgeführt, und nicht wie beim linearen Filter an viereckigen Pixel-Bereichen. Der anisotropische Filter berücksichtigt die perspektivischen Verzerrungen. Wie gesagt, das Ergebnis hängt von der verwendeten Grafikkarte ab.
Es gibt noch eine vierte Technik bei den Textur-Filtern, MipMap, diese wird in einem gesonderten Tipp veranschaulicht und erklärt.
Es folgt nun der für diesen Tipp relevante Code.
 
Private Sub Render3D()
  Dim i As Long

  On Error GoTo ErrOut
  If gD3DDevice8 Is Nothing Then Exit Sub
  gD3DDevice8.Clear 0, ByVal 0, D3DCLEAR_TARGET Or _
        D3DCLEAR_ZBUFFER, 0#, 1#, 0

  'Szene beginnen
  gD3DDevice8.BeginScene

  'VertexFormat setzen
  gD3DDevice8.SetVertexShader D3DFVF_CUSTOMVERTEX

  'Textur Filter einstellen
  gD3DDevice8.SetTextureStageState 0, D3DTSS_MAGFILTER, _
      TexturFilter
  If TexturFilter = D3DTEXF_ANISOTROPIC Then _
      gD3DDevice8.SetTextureStageState 0, D3DTSS_MAXANISOTROPY, 2
  gD3DDevice8.SetTextureStageState 0, D3DTSS_MINFILTER, _
      TexturFilter
  If TexturFilter = D3DTEXF_ANISOTROPIC Then _
      gD3DDevice8.SetTextureStageState 0, D3DTSS_MAXANISOTROPY, 2

  'Textur setzen
  gD3DDevice8.SetTexture 0, texTextur

  'TexturKoordinaten ausserhalb der Textur werden nicht gespiegelt
  gD3DDevice8.SetTextureStageState 0, D3DTSS_ADDRESSW, _
        D3DTADDRESS_WRAP

  'Die Box rendern
  gD3DDevice8.DrawPrimitiveUP D3DPT_TRIANGLELIST, 12, _
        vxBox(0), Len(vxBox(0))
  gD3DDevice8.SetTextureStageState 0, D3DTSS_ADDRESSW, 0

  'Mesh Objekte sind in Unterelemente unterteilt.
  'Eines pro Material. Daher muss über eine Schleife
  'gerendert werden.
  For i = 0 To gNumMaterials - 1
    'Pro Unterelement die Textur setzen
    gD3DDevice8.SetTexture 0, gMeshTextures(i)
    'Unterelement rendern
    gMesh.DrawSubset i
  Next
  'Mit der Draw-Methode des D3DX8Sprite-Objektes werden die
  'Bilder gezeichnet
  Call gD3DX8Sprite.Draw(texFadenkreuz, recFadenkreuz, _
        vecScalingDummy, vecRotationCenterDummy, 0, _
        vecFadenkreuz, lngColorDummy)
  'Text zeichnen
  myDXFont.DrawTextW strText, Len(strText), recText, _
        DT_WORDBREAK, D3DColorMake(1, 1, 1, 1)

  'Szene beenden
  gD3DDevice8.EndScene

  'Kompletten BackBuffer zum FrontBuffer kopieren
  gD3DDevice8.Present ByVal 0, ByVal 0, 0, ByVal 0
  Exit Sub

ErrOut:
  Debug.Print Err.Number & " - " & Err.Description
End Sub
 
Hinweis
Um dieses Beispiel ausführen zu können, wird die DirectX 8 for Visual Basic Type Library benötigt (siehe dazu die Erläuterungen in der DirectX-Rubrik).

Windows-Version
95
98
ME
NT
2000
XP
Vista
Win 7
VB-Version
VBA 5
VBA 6
VB 4/16
VB 4/32
VB 5
VB 6


Download  (252 kB) Downloads bisher: [ 359 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

Startseite | Projekte | Tutorials | API-Referenz | VB-/VBA-Tipps | Komponenten | Bücherecke | VB/VBA-Forum | VB.Net-Forum | DirectX-Forum | Foren-Archiv | DirectX | VB.Net-Tipps | Chat | Spielplatz | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report
Letzte Aktualisierung: Donnerstag, 25. August 2011