Skip to content

Hello Triangle MSAA

This example showcases the minimal changes needed to enable multisample anti-aliasing. Read the Hello Triangle example to see the differences.

The first place to look is createRenderTarget, where the MSAA texture and view are initialized. This function is called on initialization and on window resize.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void HelloTriangleMSAA::createRenderTarget()
{
    const TextureOptions options = {
        .type = TextureType::TextureType2D,
        .format = m_swapchainFormat,
        .extent = { .width = m_window->width(), .height = m_window->height(), .depth = 1 },
        .mipLevels = 1,
        .samples = m_samples,
        .usage = TextureUsageFlagBits::ColorAttachmentBit,
        .memoryUsage = MemoryUsage::GpuOnly,
        .initialLayout = TextureLayout::Undefined
    };
    m_msaaTexture = m_device.createTexture(options);
    m_msaaTextureView = m_msaaTexture.createView();
}

Filename: hello_triangle_msaa/hello_triangle_msaa.cpp

This creates a texture and a view with the correct multisampling configuration and new dimensions, which we will attach to the render pass option struct (KDGpu::RenderPassCommandRecorderOptions). This texture is able to hold more information (samples) per texel. Additionally, we need to configure the render pass option struct to multisample, passing in the same number of samples we did for the texture above.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    m_opaquePassOptions = {
        .colorAttachments = {
            {
                .view = m_msaaTextureView, // The multisampled view which will change on resize.
                .resolveView = {}, // Not setting the swapchain texture view just yet. That's handled at render.
                .clearValue = { 0.3f, 0.3f, 0.3f, 1.0f },
                .finalLayout = TextureLayout::PresentSrc
            }
        },
        .depthStencilAttachment = {
            .view = m_depthTextureView,
        },
        // configure for multisampling
        .samples = m_samples
    };

Filename: hello_triangle_msaa/hello_triangle_msaa.cpp

Notice that the render pass options contains two separate entries: one for view and one for resolveView. The view is set to the multisample texture, which has extra sampling information. During an MSAA pass, though, the multisampled texture needs to have its extra information "resolved" into a final, regular texture: the resolveView.

Also configure the graphics pipeline (KDGpu::GraphicsPipelineOptions) to multisample:

1
2
3
        .multisample = {
            .samples = m_samples
        }

Filename: hello_triangle_msaa/hello_triangle_msaa.cpp

Lastly, on each frame, update the resolveView with the swapchain view that we want to render to.

1
2
    // We now update the resolveView instead of the view
    m_opaquePassOptions.colorAttachments[0].resolveView = m_swapchainViews.at(m_currentSwapchainImageIndex);

Filename: hello_triangle_msaa/hello_triangle_msaa.cpp


Updated on 2023-12-22 at 00:05:36 +0000