Windows Developer Documentation

Textures in DirectX

Textures are a fundamental part of modern graphics rendering, allowing developers to add intricate detail, color, and surface properties to 3D models and 2D elements. In DirectX, textures are handled through various resource types and operations that enable efficient and flexible use of image data.

What are Textures?

A texture, in the context of computer graphics, is typically an image or a multi-dimensional array of data that is applied to the surface of a geometric primitive. This process is known as texture mapping. Textures can represent:

Example of texture mapping on a 3D model
Figure 1: Texture mapping applied to a teapot model.

Texture Resource Types

DirectX provides several resource types for handling textures:

Texture Creation and Usage

Creating a texture typically involves the following steps:

  1. Define Texture Description: Specify dimensions, format, mipmap levels, usage (e.g., shader resource, render target), and CPU access flags using a D3D11_TEXTURE2D_DESC or D3D11_TEXTURE3D_DESC structure.
  2. Create the Texture Resource: Use the device's CreateTexture2D or CreateTexture3D method.
  3. Populate Texture Data: For initial data, use UpdateSubresource or map/unmap operations with ID3D11DeviceContext::Map and Unmap. For textures generated dynamically, render into them using render target views.
  4. Create Shader Resource View (SRV): Create an ID3D11ShaderResourceView that tells the pipeline how to interpret the texture data for use in shaders.
  5. Bind to Pipeline: Bind the SRV to the shader stage (e.g., pixel shader) using ID3D11DeviceContext::PSSetShaderResources.

// Example: Creating a basic 2D texture
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = 512;
texDesc.Height = 512;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT; // Usable by GPU
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; // Bindable as SRV
texDesc.CPUAccessFlags = 0; // No CPU access needed

ID3D11Texture2D* pTexture = nullptr;
HRESULT hr = pDevice->CreateTexture2D(&texDesc, nullptr, &pTexture);

if (SUCCEEDED(hr)) {
    // Create Shader Resource View
    ID3D11ShaderResourceView* pSRV = nullptr;
    hr = pDevice->CreateShaderResourceView(pTexture, nullptr, &pSRV);

    if (SUCCEEDED(hr)) {
        // Bind SRV to pixel shader
        pImmediateContext->PSSetShaderResources(0, 1, &pSRV);
        // ... use pTexture ...
        pSRV->Release();
    }
    pTexture->Release();
}
            

Mipmaps

Mipmaps are pre-calculated, lower-resolution versions of a texture. They are crucial for reducing aliasing artifacts and improving performance when objects are viewed at a distance. DirectX supports automatic mipmap generation and manual creation.

When creating a texture for mipmap usage, set MipLevels in the description to 0 to allow DirectX to generate all necessary levels, or specify the desired number of levels.

Note: Using a texture with mipmaps requires a ID3D11SamplerState to control how the texture is sampled across mipmap levels (e.g., using D3D11_TEXTURE_ADDRESS_WRAP and D3D11_FILTER_ANISOTROPIC).

Texture Formats

DirectX supports a wide range of texture formats, including:

Choosing the appropriate format depends on the intended use, desired precision, memory constraints, and performance considerations.

Further Reading