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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 | void HelloTriangleMSAA::createRenderTarget()
{
const TextureOptions options = {
.type = TextureType::TextureType2D,
.format = m_swapchainFormat,
.extent = { .width = m_swapchainExtent.width, .height = m_swapchainExtent.height, .depth = 1 },
.mipLevels = 1,
.samples = m_samples.get(),
.usage = TextureUsageFlagBits::ColorAttachmentBit,
.memoryUsage = MemoryUsage::GpuOnly,
.initialLayout = TextureLayout::Undefined
};
m_msaaTexture = m_device.createTexture(options);
m_msaaTextureView = m_msaaTexture.createView();
}
bool HelloTriangleMSAA::isMsaaEnabled() const
{
return m_samples.get() != SampleCountFlagBits::Samples1Bit;
}
void HelloTriangleMSAA::setMsaaSampleCount(SampleCountFlagBits samples)
{
if (samples == m_samples.get())
return;
// get new pipeline
for (size_t i = 0; i < m_supportedSampleCounts.size(); ++i) {
if (m_supportedSampleCounts[i] == samples) {
m_currentPipelineIndex = i;
break;
}
}
// the ExampleEngineLayer will recreate the depth view when we do this
m_samples = samples;
// we must also refresh the view(s) we handle, and reattach them
createRenderTarget();
}
void HelloTriangleMSAA::drawMsaaSettings(ImGuiContext *ctx)
{
constexpr ImVec2 winOffset(200, 150);
constexpr ImVec2 buttonSize(120, 40);
constexpr size_t maxMessageLen = 40;
ImGui::SetCurrentContext(ctx);
ImGui::SetNextWindowPos(ImVec2((float)m_window->width() - winOffset.x, winOffset.y));
ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiCond_FirstUseEver);
ImGui::Begin(
"Controls",
nullptr,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
auto getButtonLabel = [](SampleCountFlagBits samples) -> const char * {
switch (samples) {
case SampleCountFlagBits::Samples1Bit:
return "No MSAA";
case SampleCountFlagBits::Samples2Bit:
return "2x MSAA";
case SampleCountFlagBits::Samples4Bit:
return "4x MSAA";
case SampleCountFlagBits::Samples8Bit:
return "8x MSAA";
case SampleCountFlagBits::Samples16Bit:
return "16x MSAA";
case SampleCountFlagBits::Samples32Bit:
return "32x MSAA";
case SampleCountFlagBits::Samples64Bit:
return "64x MSAA";
default:
return "Unknown";
}
};
int selectedIndex = m_requestedSampleCountIndex;
for (int i = 0; i < m_supportedSampleCounts.size(); ++i) {
ImGui::RadioButton(getButtonLabel(m_supportedSampleCounts[i]), &selectedIndex, i);
}
// so we can deal with it in updateScene
m_requestedSampleCountIndex = selectedIndex;
ImGui::End();
}
|
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.
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:
| .multisample = {
.samples = 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.
Filename: hello_triangle_msaa/hello_triangle_msaa.cpp
Updated on 2026-02-28 at 00:01:08 +0000