簡體   English   中英

如何將壓縮的 DDS 格式紋理與 mip 映射一起使用?

[英]How can I use compressed DDS format textures with mip mapping?

到目前為止,我將D3D11_TEXTURE2D_DESC::MipLevels設置為 1,但為了提高地形紋理的性能和質量,我嘗試將其交換為帶有 mipmap 的紋理。 所以這是我用來創建帶有 mipmap 的紋理的代碼:

 D3D11_TEXTURE2D_DESC t2d;
ZeroMemory(&t2d, sizeof(D3D11_TEXTURE2D_DESC));

UINT BindFlags = (D3D11_BIND_SHADER_RESOURCE | (m_Header.dwMipMapCount ? D3D11_BIND_RENDER_TARGET : 0)); // if the texture has mipmaps then bind it to render target.

t2d.Format = GetDXGIFormat(m_Header.ddspf); // BC2_UNORM
t2d.Width = m_Header.dwWidth;
t2d.Height = m_Header.dwHeight;
t2d.MipLevels = !m_Header.dwMipMapCount ? 1 : 0; // if the texture has mip maps then set it to 0 in order to use them all.
t2d.ArraySize = 1;
t2d.SampleDesc.Count = 1;
t2d.Usage = D3D11_USAGE_DEFAULT;
t2d.BindFlags = BindFlags;
if(!t2d.MipLevels) // only set if the texture has mip maps.
    t2d.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

D3D11_SUBRESOURCE_DATA sd;
ZeroMemory(&sd, sizeof(D3D11_SUBRESOURCE_DATA));

sd.pSysMem = m_DDSData;

switch (t2d.Format) {
case DXGI_FORMAT_BC1_UNORM:
    sd.SysMemPitch = 8 * (m_Header.dwWidth / 4);
    break;
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC3_UNORM:
    sd.SysMemPitch = 16 * (m_Header.dwWidth / 4);
    break;
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
    sd.SysMemPitch = m_Header.dwWidth * 4;
    break;
default:
    return Log("Unsupported texture format.");
}

hr = pDevice->CreateTexture2D(&t2d, &sd, &m_pTexture2D);
if (FAILED(hr))
    return Log("Failed to create texture.");

當我的代碼運行並找到帶有 mip 貼圖的紋理時,它最終失敗了,這是我在調試時收到的錯誤消息:

D3D11 錯誤:ID3D11Device::CreateTexture2D:格式 (0x4a, BC2_UNORM) 不能綁定為 RenderTarget,或轉換為可以綁定為 RenderTarget 的格式。 因此這種格式不支持 D3D11_BIND_RENDER_TARGET。 [ STATE_CREATION 錯誤 #92:CREATETEXTURE2D_UNSUPPORTEDFORMAT]

但是,如果它找到沒有 mip 貼圖的紋理,或者甚至是帶有 mip 貼圖的紋理,但我將紋理描述上的 mip 貼圖設置為 1,則不會收到錯誤消息。 正如錯誤消息中所說,我無法將紋理綁定到渲染目標,但是如果我嘗試使用D3D11_RESOURCE_MISC_GENERATE_MIPS我會收到一條錯誤消息,指出紋理需要綁定到D3D11_BIND_RENDER_TARGET

mipmap 的自動生成不支持塊壓縮格式。 您可以使用CheckFormatSupport確認這一點。

bool autogen = false;
UINT fmtSupport = 0;
hr = d3dDevice->CheckFormatSupport(format, &fmtSupport);
if (SUCCEEDED(hr) && (fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN))
{
    // 10level9 feature levels do not support auto-gen mipgen for volume textures
    if ((resDim != D3D11_RESOURCE_DIMENSION_TEXTURE3D)
        || (d3dDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0))
    {
        autogen = true;
    }
}

通常,您需要離線壓縮紋理並生成 mipmap 作為該處理的一部分。 這些可以存儲在 DDS 文件中,然后在運行時與 mips 一起加載。

有關支持 mipmap 生成、塊壓縮和 DDS 編解碼器的 C++ 庫,請參閱DirectXTex 它還包括DDSTextureLoader模塊,這是一個輕量級的 DDS 文件加載器。

對於非常大的數據集,已經使用了替代方案,其中使用在運行時加載的某種有損格式(如 JPEG)壓縮高分辨率圖像,然后軟件或基於 GPU 的盒式過濾器生成 mips。 然后使用快速塊壓縮方案壓縮該紋理的所有級別。 它的質量與離線壓縮不同,但對於某些場景,值得進行權衡。

請記住,塊壓縮格式具有固定的 2:1 或 4:1 壓縮比,但優點是您無需解壓縮它們,因為硬件可以直接使用它進行渲染。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM