[D3D11] DepthStencilView mit TextureCube

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

[D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Servus,
für meine ShadowMap Generierung von Punktlichtquellen möchte ich eine Textur verwenden, die ich mit dem Flag D3D11_RESOURCE_MISC_TEXTURECUBE erstelle. Davon erstelle ich mir 6 DepthStencilView für jeden Face, 6 SRV für je ein Face sowie ein SRV für das binden als TextureCube. Die Erstellung funktioniert ohne Fehler, jedoch bleibt der Inhalt der Textur leer beim Zeichnen. Hat einer eine Idee ob bei der Erstellung semantisch etwas schief geht?

Code: Alles auswählen

// Create texture object
D3D11_TEXTURE2D_DESC tex2DDesc = {0};
tex2DDesc.Width				= width;
tex2DDesc.Height			= height;
tex2DDesc.Format			= DXGI_FORMAT_R32_TYPELESS;
tex2DDesc.BindFlags			= D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
tex2DDesc.MiscFlags			= D3D11_RESOURCE_MISC_TEXTURECUBE;
tex2DDesc.ArraySize			= 6;
tex2DDesc.MipLevels			= 1;
tex2DDesc.Usage				= D3D11_USAGE_DEFAULT;
tex2DDesc.SampleDesc.Count	= 1;

HRESULT hr = device->CreateTexture2D(&tex2DDesc, nullptr, cubeTexture.rebind());
assert(hr == S_OK);

// Create cube shader resource view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
srvDesc.TextureCube.MipLevels = 1;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;

hr = device->CreateShaderResourceView(cubeTexture, &srvDesc, srv[6].rebind());
assert(hr == S_OK);

// Create face shader resource views
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
srvDesc.Texture2DArray.MipLevels = 1;
srvDesc.Texture2DArray.ArraySize = 1;

for(unsigned i = 0; i < 6; ++i) {
	srvDesc.Texture2DArray.FirstArraySlice = i;
				
	hr = device->CreateShaderResourceView(cubeTexture, &srvDesc, srv[i].rebind());
	assert(hr == S_OK);
}

// Create depth stencil views
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
ZeroMemory(&dsvDesc, sizeof(D3D11_RENDER_TARGET_VIEW_DESC));
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
dsvDesc.Texture2DArray.ArraySize = 1;
			
for(unsigned i = 0; i < 6; ++i) {
	dsvDesc.Texture2DArray.FirstArraySlice = i;

	hr = device->CreateDepthStencilView(cubeTexture, &dsvDesc, dsvFace[i].rebind());
	assert(hr == S_OK);
}
Bin mir halt unsicher ob ein DepthStencilView auf eine solche Art von Textur zugreifen kann, wenn ihr die Erstellung semantisch verifizieren könnt muss ich wohl tiefer schürfen.

MfG
RazorX
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Nach weiterem forschen hab ich nun rausgefunden, dass in der Textur etwas drin steht und über die Face-SRV auch ausgelesen werden kann. Wenn ich jedoch den Cube-SRV nehme, wird mir immer 0 zurückgeliefert, obwohl der auf die selben Daten zugreifen sollte.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von dot »

Sagt die Debug Runtime vielleicht was?
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Leider nein
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von dot »

Nachdem ich mal etwas genauer drübergeschaut hab: Du hast srvDesc.TextureCube.MostDetailedMip nicht gesetzt. Ansonsten wär vielleicht mal interessant, wie genau du im Shader auf den Cube zugreifst...
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Da ich die SRV Desc Struktur nulle und es nur ein Mip-Level gibt, hat sich das Zuweisen erledigt (Most-Detailed ist ja eben die 0).

Der Zugriff im Shader erfolgt so:

Code: Alles auswählen

float3 l = input.lightPos - viewspacePosition;
...
l = normalize(l);
...
output = float4(computeLinearDepth(texShadowCube.Sample(pointClampSampler, l), g_zNear, g_zFar), 0, 0, 1.f);
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von dot »

Und l liefert auch sinnvolle Werte? Und das SRV wurde auch am richtigen Slot gebunden?
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

l liefert richtige Werte, da dies der Vektor ist den ich auch für Beleuchtung benutze. Der TextureCube ist auch auf dem richtigen Slot gebunden, eine weitere Texture2D hab ich auf dem selben und im Programm tausch ich dann schonmal Zeilen aus. So konnte ich auch sagen, dass definitiv etwas in der Textur drin steht.

Edit: Kein Plan was ich geändert habe, aber es funktioniert jetzt oO
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Leider hab ich noch immer Probleme mit dem TextureCube. Heute im Laufe des Tages habe ich mich die ganze Zeit damit rumgeschlagen, dass beim auslesen des TextureCubes mir seltsame Artefakte auftauchen. Der Vektor wird ganz normal berechnet und wird auch zur Beleuchtung verwendet. Die Projektionsmatrix für die einzelnen CubeFaces hat: FoV = PI / 2, Aspect = 1, Near = .1f, Far = Radius. Ich hätte angenommen, dass wenn ich nun mit einem Vektor auf dem Einheitskreis daraus sample das ich auch eine sphärische Verzerrung erhalte. Leider bekomme ich aber Samples, denen man deutlich ansehen kann das sie in einer Box liegen. (Auf dem Bild wird ein Point Clamp Filter benutzt und ich bin mit der Kamera sehr nah auf den Boden runter, da so der Effekt sehr stark sichtbar wird; Rot ist der Beleuchtungsanteil berechnet durch N dot L; Grün ist der Tiefenwert der Shadowmaps).
screenshot_2012-11-05_16-35-40.png
Wenn ich nun mit diesen Tiefeninformationen gegen die Entfernung des Pixels von der Punktlichtquelle einen Schattentest mache, erhalte ich folgende seltsame Strukturen.
screenshot_2012-11-05_14-04-56.png
Muss ich eine zusätzliche sphärische Verzerrung anwenden um keine Boxergebnisse zu bekommen?

MfG
RazorX
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von dot »

Beim Samplen aus einer Cubemap zählt nur die Richtung, ob der Vektor normalisiert ist (ich nehme mal an das meinst du mit "auf dem Einheitskreis") oder nicht, macht keinen Unterschied...

Wenn ich das richtig verstanden hab, enthalten deine Maps die nichtlineare Tiefe, aus der du die lineare Viewspace Tiefe aus Sicht der Lichtquelle rekonstruierst!? Ich nehme an, du verwendest für den Schattentest dann die euklidische Entfernung ("die Entfernung des Pixels von der Punktlichtquelle")!? Das ist natürlich falsch, du musst natürlich ebenso die lineare Viewspace Tiefe aus Sicht der Lichtquelle verwenden...
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Fängt langsam an Sinn zu ergeben. Also den Punkt aus meinem Viewspace in den Viewspace der Punktlichtquelle (dem Viewspace in dem der CubeFace gerendert wurde) transformieren und dann die z-Komponente gegen die gespeicherte Tiefe testen? Ich geh mal davon aus, dass es in HLSL keine Möglichkeit gibt zu erkennen aus welchem Face der Sample stammt!?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von Niki »

RazorX, hast du das Problem mittlerweile gelöst? Wenn nicht, dann will ich mal versuchen zu helfen. Auf grund der Benutzung von "computeLinearDepth" gehe im folgenden davon aus, dass du einen Renderer mit Deferred Lighting hast.

Was ich mache ist folgendes:

(1) Zuerst einmal bestimme ich welches pixel im GBuffer ich beleuchten will. Dieses transformiere ich zurück in den View Space des Spielers. Ich nenne diese position mal posVS.

(2) Als nächstes transformiere ich posVS in das Koordinatensystem des Point Lights. Nennen wir das mal posLS (LS für Light Space)

(3) Dann sample ich die shadow cube map mit Texturekoordinaten posLS.xyz. Normalisieren brauchst man da nichts. Den resultierenden nicht-linearen depth-Wert wandle ich in einen linearen depth-Wert um. Nennen wir den mal shadowLinearDepth.

(4) Nun musst du rausfinden ob der Punkt posLS von shadowLinearDepth verdeckt wird. Wie "dot" bereits erwähnte benutzt du anscheinend die Euklidische Distanz length(posLS) und vergleichst die mit shadowLinearDepth. Wie Du bereits gemerkt hast kommen daher diese komischen kurvigen Resultate in Deinen Screenshots. Damit Du das korrigieren kannst fragst Du, wie Du rausfinden kannst aus welchem Face das Sample stammt. Willst Du gar nicht wissen, denn das bedeutet jede Menge if/else im Pixel Shader. Stattdessen etwas Pseudo-Code (der Trick steckt in abs() und max()):

Code: Alles auswählen

float3 absPosLS = abs(posLS.xyz);
float pixelLinearDepth = max(absPosLS.x, max(absPosLS.y, absPosLS.z));

if (pixelLinearDepth > g_lightFarPlane)
    return float4(0, 0, 0, 0); // in shadow

if (shadowLinearDepth <= pixelLinearDepth * 0.96) // 0.96 = shadow bias
{
    return float4(0, 0, 0, 0); // in shadow
}
else
{
    return Lighting(...);
}
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von RazorX »

Dank dir für die ausführliche Antwort, hatte das aber selber schon vor geraumer Zeit gelöst. Habs letztlich auch über den max/abs Ansatz gemacht und funktionierte relativ gut. Was mich etwas gestört hatte war, dass man auf TextureCubes kein PCF anwenden kann und das Resultat nicht ganz so schön aussah. Muss das ganze mal zu einem Texturatlas umbauen.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D11] DepthStencilView mit TextureCube

Beitrag von Niki »

Ich bin mir auch noch nicht sicher ob ich die cube maps für diesen Zweck mag. Das war mir aber vorerst wurscht, da ich das shadow mapping nur testweise implementiert habe um für später zu wissen wie ich das ganze in meine deferred shading pipeline reinbaue. Wenn's dann soweit ist werde ich auch andere Methoden ausprobieren, wie zum Beispiel über 6 spot lights mit einer einzigen shadow map.
Antworten