In den letzten Tagen hatte ich wieder Zeit, an der 3D-Engine SeeingSharp 2 weiterzuarbeiten. Diesmal ging es darum, allgemein das Arbeiten mit Texturen zu verbessern. Genauer geht es um das Texture sampling. Texture sampling bezeichnet den Prozess, wie Farbinformationen aus Texturen gelesen werden. Direct3D bietet hierbei eine lange Liste von Einstellungen. So kann etwa beeinflusst werden, nach welcher Logik Texturen auf einer Fläche gekachelt werden sollen. Auch die Art, wie die Farben zweier benachbarter Pixel auf einer Textur vermischt werden, kann konfiguriert werden. Letzteres ist dann relevant, wenn eine Textur am Monitor mehr oder weniger Pixel beansprucht, als in der Textur selbst zur Verfügung stehen. Insgesamt hat SeeingSharp 2 bis jetzt nur ein Standard-Set an Einstellungen mit Anisotroper Filterung [1] unterstützt. Passt dieses Standard-Set nicht, so hatte man bis dato keine Möglichkeit, das Texture sampling zu beeinflussen.
Inhaltsverzeichnis
Einstellungsmöglichkeiten für Texture sampling
Direct3D 11 bietet zur Konfiguration des Texture sampling die Struktur D3D11_SAMPLER_DESC [2]. Die vielen Felder würde ich auf folgende Konfigurationsmöglichkeiten zusammenfassen
- Logik zur mehrfachen Darstellung einer Textur auf einer Fläche (Siehe D3D11_TEXTURE_ADDRESS_MODE [3])
- Logik zur Ermittlung des Farbwerts, falls man sich zwischen mehreren Texeln einer Textur befindet. In Direct3D wird das als Filter bezeichnet (Siehe D3D11_FILTER [4]). BTW: Als Texel bezeichnet man Farbpunkte in einer Textur, sie sind also i. d. R. mit Pixel in Bitmaps vergleichbar.
- Div. Detaileinstellungen zu den zuletzt genannten Themen
Die Standardeinstellung in SeeingSharp war bis dato wie im nachfolgenden Codeausschnitt. Die Namen der Enumerationen und Strukturen weichen hierbei leicht von den obigen ab, da SeeingSharp 2 einen Wrapper für den Zugriff auf Direct3D 11 verwendet (aktuell Vortice.Windows [5]).
var samplerDesk = D3D11.SamplerDescription.Default; samplerDesk.AddressU = D3D11.TextureAddressMode.Wrap; samplerDesk.AddressV = D3D11.TextureAddressMode.Wrap; samplerDesk.Filter = D3D11.Filter.Anisotropic; samplerDesk.MaxAnisotropy = 8;
Beispiele für verschiedene Einstellungsvarianten
Was bedeuten obige Einstellungen konkret? Die Eigenschaften AddressU und AddressV beziehen sich auf die mehrfache Darstellung einer Textur auf einer Fläche. TextureAddressMode.Wrap bedeutet hier, dass gekachelt wird. Eine vergleichbare Einstellung wäre TextureAddressMode.Mirror. Diese kachelt ebenso, spiegelt aber benachbarte Blöcke. TextureAddressMode.Clamp und TextureAddressMode.Border dagegen kacheln die Textur nicht und unterscheiden sich dadurch, mit welcher Farbinformation der Rest der Fläche ausgefüllt wird. Im nachfolgenden Screenshot hätte ich zur Veranschaulichung drei der Modi gegenübergestellt. Beachte bitte, dass hier nur AddressU geändert wurde und nicht AddressV. U und V sind dabei die beiden möglichen Achsen auf einer Textur. Man kann sich diese wie die X- und Y-Achsen auf einem Bitmap vorstellen.
Die Eigenschaft Filter bezieht sich auf die Ermittlung des Farbwerts, wenn ein Wert zwischen zwei Texeln abgefragt wird. Hierbei gibt es eine lange Liste an Einstellungsmöglichkeiten. Das liegt daran, da bei den meisten Varianten nach minification (verkleinern), magnification (vergrößern) und mip-level unterschieden wird. Darin kann anschließend je Variante zwischen Linear und Point ausgewählt werden. Linear bedeutet dabei, dass mehrere Farbwerte vermischt werden. Point dagegen heißt, dass nur einer der betroffenen Farbewerte gezogen wird. Zusammen ergibt das Werte wie D3D11.Filter.MinMagMipPoint oder D3D11.Filter.MinLinearMagPointMipLinear. Die verschiedenen Kombinationen werden also als Member einer Enumeration zur Verfügung gestellt. Anisotropic ist dabei ein Sonderfall, da hierbei alles eingeschlossen wird. Nachfolgender Screenshot vergleicht die beiden Varianten D3D11.Filter.Anisotropic und D3D11.Filter.MinMagMipPoint. Letztere Variante sorgt dabei für eine verpixelte Optik.
Die restlichen Einstellungen wie das MaxAnisotropy oben sind Detaileinstellungen, auf die ich in diesem Artikel nicht weiter eingehen möchte. An diesem Punkt kann ich gut auf die Dokumentation von Direct3D 11 oder die Xml-Dokumentation von SeeingSharp verweisen.
Einstellen des Texture sampling an der TextureResource von SeeingSharp 2
Ab Version 0.9.2 bietet SeeingSharp 2 alle Einstellungen zum Texture sampling an der Klasse TextureResource an. TextureResource ist eine Basisklasse für alle Arten von Texturen in SeeingSharp 2, so etwa RenderTargetTextureResource oder Direct2DTextureResource. Nachfolgend ein Code-Ausschnitt, welcher das Konfigurieren einer TextureResource beim Erzeugen der Textur zeigt. In diesem Fall wird ein Filter verwendet, der eine verpixelte Darstellung erzeugt, sobald die Kamera nah am Objekt ist. Über eine größere Fläche wird die Texture gekachelt.
// ... await mainRenderLoop.Scene.ManipulateSceneAsync(manipulator => { // ... // Create texture and material var resTexture = manipulator.AddResource(_ => { var textureFileLink = new AssemblyResourceLink( typeof(TextureSamplingSample), "PrimitiveTexture.png"); var textureResource = new StandardTextureResource(textureFileLink); textureResource.Filter = SeeingSharpFilter.MinLinearMagPointMipLinear; textureResource.AddressU = SeeingSharpTextureAddressMode.Wrap; textureResource.AddressV = SeeingSharpTextureAddressMode.Wrap; return textureResource; }); // ... }
Neues Sample im SampleContainer
SeeingSharp 2 hat ebenso ein neues TextureSampling Beispiel, bei dem man mit den verschiedenen Einstellungen experimentieren kann. Eine Textur wird hierbei auf einer Fläche dargestellt, auf die sie nach einem 4×4 Raster gemappt wird. Nachfolgender Screenshot zeigt das Beispiel.
Downloads
- Aktuelle Releases von SeeingSharp 2 inkl. SampleContainer und ModelViewer
https://github.com/RolandKoenig/SeeingSharp2/releases
Verweise
- Informationen zu Anisotroper Filterung von Intel
https://www.intel.de/content/www/de/de/gaming/resources/what-is-anisotropic-filtering.html - Dokumentation zur Struktur D3D11_SAMPLER_DESC
https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ns-d3d11-d3d11_sampler_desc - Dokumentation zur Enumeration D3D11_TEXTURE_ADDRESS_MODE
https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_texture_address_mode - Dokumentation zur Enumeration D3D11_FILTER
https://learn.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_filter - Der aktuell von SeeingSharp 2 verwendete Direct3D Wrapper Vortice.Windows
https://github.com/amerkoleci/Vortice.Windows
Ebenfalls interessant
- Worklog SeeingSharp 2: Getting Started für WinUI 3
https://www.rolandk.de/wp-posts/2022/06/worklog-seeingsharp-2-getting-started-fuer-winui-3/ - Worklog SeeingSharp 2: Neuer Anstrich mit WinUI
https://www.rolandk.de/wp-posts/2020/09/worklog-seeing-2-winui/