Exportieren (0) Drucken
Alle erweitern
Informationen
Das angeforderte Thema wird unten angezeigt. Es ist jedoch nicht in dieser Bibliothek vorhanden.

Implementieren von Schattenpuffern für Direct3D Featureebene 9 (DirectX und C++)

Applies to Windows and Windows Phone

Wenn Sie eine Windows-Runtime-App mit DirectX und C++ entwickeln möchten, die Schatteneffekte rendert und Direct3D-Funktionsebene 9_1, 9_2 oder 9_3 verwendet, müssen Sie eine bestimmte Teilmenge der Schattenpufferfunktionen von Direct3D 10_0+ verwenden, um Schatteneffekte richtig zu implementieren. Hier befassen wir uns mit der Implementierung von Schattenpuffern für Direct3D-Funktionsebene 9.

Was ist ein Schattenpuffer?

Schatten sind ein wichtiges Element beim Erstellen von realistischen 3D-Szenen und beim Herstellen einer überzeugenden Tiefenillusion. Die Schattenpuffer-Technik ist ein häufig verwendeter Ansatz für das Rendern von Schatten mithilfe der Grafikhardware. Sie ist allerdings relativ rechenintensiv. Schattenpuffer werden mithilfe eines Tiefenpuffers implementiert, in dem die Tiefeninformationen der Szene aus der Perspektive der Lichtquelle gespeichert werden. Dann wird jeder gerenderte Punkt der Szene mit dem Tiefenpuffer verglichen, um festzustellen, ob er im Schatten liegt.

Implementieren von Schatten mit Direct3D Featureebene 9_1, 9_2 oder 9_3

Rufen Sie nach dem Start Ihrer App ID3D11Device::CheckFeatureSupport unter Verwendung des D3D11_FEATURE_D3D9_SHADOW_SUPPORT-Direct3D-Feature-Enumerationswerts auf, um festzustellen, ob der installierte Grafiktreiber Schattenpuffer unterstützt. Wenn in den Daten (die entsprechende D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT-Struktur), die über den pFeatureSupportData-Parameter von CheckFeatureSupport abgerufen wurden, das SupportsDepthAsTextureWithLessEqualComparisonFilter-Feld den Wert "false" enthält, funktionieren in der Windows-Runtime-App mit DirectX keine Schattenpuffer, wenn diese auf dem Computer des Benutzers ausgeführt wird. Der Benutzer muss den Treiber upgraden, um dieses Problem zu beheben.



D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT d3d9ShadowSupportResults;
ZeroMemory(&d3d9ShadowSupportResults, sizeof(D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT)); 

m_device->CheckFeatureSupport(
		D3D11_FEATURE_D3D9_SHADOW_SUPPORT, 
		&d3d9ShadowSupportResults,
		sizeof(D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT)
		);
	

Die Technik funktioniert mit Puffern mit einer Tiefe von 16 Bit und 24 Bit. Daher werden beide im Abschnitt "Anmerkungen" behandelt. Bedenken Sie, dass manche Treiberimplementierungen nur Puffer mit einer Tiefe von 16 Bit unterstützen.

Hinweis  Weitere Informationen finden Sie unter Häufig verwendete Methoden zur Verbesserung von Tiefenkarten für Schatten.

  1. Erstellen Sie eine Texture2D-Flächenressource (mit ID3D11Device::CreateTexture2D), bei der das Format-Feld von D3D11_TEXTURE2D_DESC auf DXGI_FORMAT_R24G8_TYPELESS festgelegt ist, wenn Puffer mit einer Tiefe von 24 Bit unterstützt werden, bzw. auf DXGI_FORMAT_R16_TYPELESS, wenn dies nicht der Fall ist. Geben Sie das BIND_SHADER_RESOURCE-Flag und das BIND_DEPTH_STENCIL-Flag im BindFlags-Feld ebenfalls an. Damit kann die Fläche in verschiedenen Renderingdurchläufen entweder als Tiefenpuffer oder als Textur verwendet werden.

    Hinweis  Verlassen Sie sich bei der Ermittlung, ob der Grafiktreibers diese spezifischen Formate unterstützt, nicht auf CheckFormatSupport. Wenn Sie die Direct3D 11-APIs CheckFeatureSupport und CheckFormatSupport zur Abfrage der DXGI_FORMAT-Unterstützung für Featureebene 9_* verwenden, meldet die DirectX-Runtime keine Unterstützung für Schattenpuffer-Features.

  2. Erstellen Sie bei Verwendung eines Tiefenformats wie DXGI_FORMAT_D24_UNORM_S8_UINT für Schattenpuffer mit einer Tiefe von 24 Bit bzw. DXGI_FORMAT_D16_UNORM für Schattenpuffer mit einer Tiefe von 24 Bit eine ID3D11DepthStencilView (using ID3D11Device::CreateDepthStencilView) über der in Schritt 1 zugeordneten Texture2D-Ressource.

  3. Füllen des Schattenpuffers mit Schatteninformationen. Richten Sie zuerst an der Position der Lichtquelle eine temporäre Kamera ein, die in Richtung der Lichtquelle ausgerichtet ist. Rendern Sie dann alle Objekte der Szene, die Schatten auf sich selbst oder auf andere Objekte werfen können. Legen Sie für diesen Durchlauf keinen Pixelshader fest und binden Sie nur ID3D11DepthStencilView an die Ausgabe.

  4. Wenn Objekte in der Szene mit Schatten gerendert werden sollen, erstellen Sie SamplerState-Objekte mit Vergleichsfiltern. Der Vergleichsmodus muss bei Geräten mit Featureebene 9_* auf LessEqual festgelegt werden. Das Behandeln von BorderColor ist bei diesem Tiefensampler ebenfalls zulässig, obwohl die meisten Grafiktreiber BorderColor auf Direct3D Featureebene 9_1 und 9_2 nicht unterstützen. Mithilfe der Rahmenfarbe (BorderColor) ist es möglich zu steuern, ob die Bereiche außerhalb der Schattenkarte immer oder nie im Schatten liegen, indem Sie den BorderColor-Wert auf 0.0 bzw. auf 1.0 festlegen.

    Die Qualität des Schattenfilters wird im Vergleichssampler durch die Filteroptionen Mag und Min gesteuert. Punktsamples produzieren Schatten mit treppenförmigen Kanten. Eine lineare Einstellung des Filtersamplers führt zu Schattenkanten besserer Qualität, sie kann aber bei Geräten mit optimiertem Energieverbrauch zu Leistungseinbußen führen.

    Hinweis   Einige beachtenswerte Punkte. Zuerst können unterschiedliche Einstellungen für die Filteroptionen Mag und Min zu undefiniertem Verhalten führen. Außerdem wird anisotropisches Filtern nicht unterstützt. Schließlich unterstützt Direct3D Featureebene 9_* keine Tiefenpuffer mit MIP-Maps (Bildpyramiden).

  5. Erstellen Sie eine ID3D11ShaderResourceView (mit ID3D11Device::CreateShaderResourceView) für die in Schritt 1 zugewiesene Texture2D-Ressource, und binden Sie sie an den oben beschriebenen Vergleichssampler. Wie in Schritt 1 müssen Sie das Pixelformat dieser Ansicht für eine Tiefe von 24 Bit auf DXGI_FORMAT_R24_UNORM_G8_TYPELESS und für eine Tiefe von 16 Bit auf DXGI_FORMAT_R16_UNORM festlegen.

  6. Erstellen Sie einen ps_4_0_level_9_*-Pixelshader, und richten Sie ihn für den Schattedurchlauf ein. Er sollte die Position jedes Pixels relativ zur Position der Lichtquelle berechnen und dann den Z-Wert des Pixels mit dem Wert im Schattenpuffer vergleichen, um festzustellen, ob sich das Pixel im Schatten befindet. Sie erreichen dies, indem Sie folgenden Code für den Shader schreiben (wobei die Hardware den Vergleich durchführt):

    • Zuerst werden die Texturkoordinaten und der Z-Wert durch eine Projektion der aktuellen Position in derselben Welt und Ansicht und in demselben Projektionsraum ermittelt, der zum Rendern des Schattens verwendet wird, und dann werden die XY-Koordinaten zum Sampeln der Schattenkarte vom [-1..1]-Raum in den [0..1]-Raum abgebildet.
    • Dann werden die Texturkoordinaten und der Z-Wert durch eine Projektion der aktuellen Position in derselben Welt und Ansicht und in demselben Projektionsraum ermittelt, der zum Rendern des Schattens verwendet wird, und dann werden die XY-Koordinaten zum Sampeln der Schattenkarte vom [-1..1]-Raum in den [0..1]-Raum abgebildet.
    • Sampeln Sie dann mit den Methoden SampleCmp und SampleCmpLevelZero Texture2D aus der im Schritt 5 erstellten ID3D11ShaderResourceView, genau wie Sie es mit Direct3D Featureebene 10_0 und höher täten, um den Schattenanteil für das aktuelle Pixel zu finden. Das Ergebnis ist der Anteil der Samples, der beim linearen Filtern nicht im Schatten liegt, in Form von Werten im Bereich [0..1]. Für Punktsamples wird ein Wert von 0.0 oder 1.0 zurückgegeben.

    Hinweis  Unter Direct3D Featureebenen 9_1, 9_2 und 9_3, führt ein Versuch, einen Shader mit den systeminternen SampleCmp*-Methoden mit einem älteren HLSL-Compiler (z. B. die Windows 7-Version der ID3D11Device::CreatePixelShader-Method) zu einem Fehler. Die systeminternen SampleCmp*-Funktionen werden nur für den fxc-Compiler und die zugehörige DLL-Datei unterstützt, die ab Windows 8 zur Verfügung steht. Diese systeminternen HLSL-Elemente sind auch in Shadermodellen für Direct3D Featureebenen höher als 9 vorhanden.

  7. Rendern Sie die Objekte der Szene, auf die Schatten geworfen werden.

Denken Sie daran, den API-Satus nach dem Rendern mit Schatten zu bereinigen. Auf einem Gerät, das über eine konfigurierte Featureebene 9_1 verfügt, führen unpassende API-Statusergebnisse dazu, dass der ID3D11DeviceContext::Draw-Aufruf übersprungen wird. Wenn der Renderer z. B. an eine Textur gebunden wird (Tiefe oder anderes), während der entsprechende Sampler für ein Vergleichssampling konfiguriert bleibt, wird ID3D11DeviceContext::Draw übersprungen. Wenn dies der Fall ist, haben Sie den API-Status falsch festgelegt.

Implementieren von Schatten unter Direct3D Featureebene 10_0 oder höher

Die obigen Schritte für das Abbilden von Schatten auf Geräten mit Featureebene 9 funktioniert auch ohne Änderung des Codes auf Geräten mit Featureebene 10 oder höher. Höhere Featureebenen unterstützen allerdings eine größere Anzahl von Optionen, z. B. erweiterte Vergleichsmodi und Flächenformate mit zusätzlicher Tiefe.

Verwandte Themen

Häufig verwendete Methoden zur Verbesserung von Tiefenkarten für Schatten
Featureebenen von Direct3D 11
Entwickeln für unterschiedliche Direct3D-Featureebenen

 

 

Anzeigen:
© 2015 Microsoft