DXGI_FORMAT_D24_UNORM_S8_UINT Depth-Buffer lesen
-
Ich versuche die Werte eine DXGI_FORMAT_D24_UNORM_S8_UINT Textur zu lasen (D3D11, DepthStencilBuffer)
Also 24 Bit für die Tiefe und 8 Bit für den Stencil. Aber wie werden die 24 bit interpretiert?
ich versuche es so:
// create a temporary texture D3D11_TEXTURE2D_DESC desc; depthStencilTexture->GetDesc(&desc); desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.MiscFlags = 0; ID3D11Texture2D* tmpTexture = nullptr; HRESULT hr = getDevice()->CreateTexture2D(&desc, nullptr, &tmpTexture); getImmediateContextD3D()->CopyResource(tmpTexture, depthStencilTexture); D3D11_MAPPED_SUBRESOURCE mappedRes; getImmediateContextD3D()->Map(tmpTexture, 0, D3D11_MAP_READ, 0, &mappedRes); color4b* data = (color4b*)mappedRes.pData;
ich würde gerne die Tiefenwerte als Bild rausspeichern (mir ist klar das ich auch die Tiefe "rausrendern" kann - aber ich will es über den direkten Zugriff in die Echte Tiefentextur lösen)
-
Ich habe es so versucht:
unsigned int depth = color[0] << 16 | color[1] << 8 | color[2]; // 24 Bit genauigkeit 2^24 = 16.777.216 float fDepth = depth / 1677721; outimage.setPixelColor(x,y, buw::color3b( fDepth * 255, fDepth * 255, fDepth * 255 );
Liefer aber leider falsche Ergebnisse
-
Ich bin nicht sicher, ob überhaupt definiert ist, welche 24 Bit die Tiefe ausmachen und wie die Byteorder ist. Auf die Schnelle konnte ich jedenfalls nix finden...
Davon abgesehen, würd ich einfach mal von Machine Byte Order ausgehen, also wohl Little Endian und nicht Big Endian, wie dein Code. Und 2^24 ist eben 16777216, wie im Kommentar drüber schon richtig steht, im Code aber nicht. Du solltest aber sowieso durch 16777215 dividieren. Und vor allem willst du keine Integerdivision, weil die immer 0 ergeben wird...
Ich würde jedenfalls empfehlen, sowas nur zu Debugzwecken zu verwenden. Und die bessere Lösung wär wohl, die Tiefe einfach zu rendern...
-
Also basierend auf diesem link würde ich folgendes tun.
// color ist hier ein unsigned int und enthält die vollen Daten. float depth = static_cast<float>(color & 0x00FFFFFF); depth /= 16.777.215.0f; unsigned char colorValue = static_cast<unsigned char>(depth * 255.0f);
Das wäre für mich jetzt der logischste Weg das ganze mal zu probieren, obs so funktioniert weiß ich allerdings nicht.
-
Xebov schrieb:
Also basierend auf diesem link würde ich folgendes tun.
// color ist hier ein unsigned int und enthält die vollen Daten. float depth = static_cast<float>(color & 0x00FFFFFF); depth /= 16.777.215.0f; unsigned char colorValue = static_cast<unsigned char>(depth * 255.0f);
Das wäre für mich jetzt der logischste Weg das ganze mal zu probieren, obs so funktioniert weiß ich allerdings nicht.
Genau so funktioniert es bei mir - super danke!
BTW: Ich verwende das natürlich nur für Debug Zwecke