如何使用 ID3D11Device::CreateTexture2D 方法使用 mipmap 创建纹理数组

How to use ID3D11Device::CreateTexture2D method to create texture array with mipmaps

提问人:Tenebre 提问时间:10/28/2023 更新时间:10/28/2023 访问量:24

问:

我本来打算使用贴图纹理将大量纹理传递到我的着色器,但由于 mip 映射导致的纹理渗色是不可接受的。在做了一些研究之后,我认为纹理数组将是完美的。

下面的代码片段采用全分辨率 (mip 0) 的图像缓冲区数组,以及每个缓冲区的预生成的 mipmap 数组。该代码可以完美地处理一组 mip 0 图像(ArraySize = n;MipLevels = 1) 或单个 mip 0 映像及其关联的 mipmap (ArraySize = 1;MipLevels = n),但如果同时给定数组和 mip 级别 (ArraySize = n;MipLevels = m),返回代码 0x80070057(参数无效)。

我已经阅读并重新阅读了文档,并阅读了网络上我能找到的所有相关帖子,并尝试了我能想到的一切。DirectX 11 文档说它可以完成,所以我一定遗漏了什么。任何帮助将不胜感激。

这是我用来生成纹理的代码。从我读过的所有内容来看,它应该是正确的。

// Setup the description of the texture.
    textureDesc.Height = height;
    textureDesc.Width = width;
    textureDesc.MipLevels = mipLevels;
    textureDesc.ArraySize = count;
    textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    textureDesc.SampleDesc.Count = 1;
    textureDesc.SampleDesc.Quality = 0;
    textureDesc.Usage = D3D11_USAGE_IMMUTABLE;
    textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    textureDesc.CPUAccessFlags = 0;
    textureDesc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA* subData = new D3D11_SUBRESOURCE_DATA[count*mipLevels];

    for( int i = 0; i < count; i++ ) {

        subData[i*mipLevels].pSysMem = imageDataArray[i*mipLevels];
        subData[i*mipLevels].SysMemPitch = (UINT)(width*4);
        subData[i*mipLevels].SysMemSlicePitch = 0;
        int w = width;
        for( int m = 0; m < mipLevels-1; m++ ) {
            w >>= 1;
            subData[i*mipLevels+m+1].pSysMem = mipsPtr[i][m];
            subData[i*mipLevels+m+1].SysMemPitch = (UINT)(w*4);
            subData[i*mipLevels+m+1].SysMemSlicePitch = 0;
        }
    }

    // Create the empty texture.
    hResult = device->CreateTexture2D(&textureDesc, (D3D11_SUBRESOURCE_DATA*)subData, &texture);
    if( FAILED(hResult) ) {

        return false;
    }
DirectX-11 纹理2D MIPMasp

评论


答:

0赞 Tenebre 10/28/2023 #1

我花了几天时间试图追踪这段代码的问题,并知道它应该可以工作......我知道它有效,因为它可以与一组纹理或单个 mipmap 链一起使用。它归结为一行:

subData[i mipLevels].pSysMem = imageDataArray[i mipLevels]; 应该是: subData[i*mipLevels].pSysMem = imageDataArray[i];

现在它工作了!哈哈。

评论

0赞 Chuck Walbourn 11/2/2023
您可能会发现 DirectXTex 中的代码是一个有用的参考。