2D antialiasing: choose a method and verify support
Separate geometry edges, texture filtering and MSAA limits in Compatibility and Vulkan.
Identify the source of aliasing
| Visible problem | Investigate |
|---|---|
| Stair steps on a slanted triangle edge | 2D geometry antialiasing, including MSAA when the backend supports it |
| Pixelated or blurred detail inside a shape | TextureFilter, source resolution and scaling |
| Moiré or flickering fine shader patterns | Pattern frequencies and filtering inside the shader |
| Jagged individual lines/contours | The draw command or type antialiased option, where available |
MSAA is not a universal image enhancer. It cannot restore missing texture detail or repair every pattern inside a fragment. Nearest filtering can be intentional for pixel art; forced blur is not automatically correct antialiasing.
Verify 2D MSAA support
The verified Reckfell 1.0.0 build has this important distinction:
| Rendering path | Confirmed result |
|---|---|
| Compatibility/OpenGL | Warns that 2D MSAA is unsupported; requesting Msaa4X leaves the mesh edge unchanged |
| Forward+/Vulkan | Msaa4X adds partial pixel coverage along the same mesh edge |
Msaa2D may read Msaa4X even without the effect in Compatibility. It stores a setting rather than querying GPU capabilities. Msaa3D is separate: enabling it did not smooth the 2D triangle in this test.
These results come from the current local Windows build on one device. They do not measure FPS or verify every driver, Mobile, Web, D3D or Metal. Do not select a backend just for a checkbox: match required features to target platforms and measure their cost there.
Run the isolated example
Use Reckfell.NET.Sdk 1.0.0 and net10.0. Save both files below, run dotnet build, attach CanvasAaExample.cs to an Entity2D in a .rscene level and run it. The triangle is slightly rotated and placed at fractional coordinates to expose its slanted edge.
For an MSAA comparison, use Forward+ with Vulkan and set the exported Antialiasing=Msaa4X before running. Compare it with Disabled at the same Viewport dimensions, coordinates and scale. Keep Disabled in Compatibility; requesting Msaa4X in this build produces a warning rather than a positive result.
CanvasMeshes.cs
using System;
using Reckfell;
public static class CanvasMeshes
{
public static ArrayMesh Quad(Vector2 size)
{
if (!size.IsFinite() || size.X <= 0 || size.Y <= 0)
throw new ArgumentOutOfRangeException(nameof(size));
Vector2 half = size * 0.5f;
return Build(
new[] { new Vector2(-half.X, -half.Y), new Vector2(half.X, -half.Y), half, new Vector2(-half.X, half.Y) },
new[] { Vector2.Zero, Vector2.Right, Vector2.One, Vector2.Down },
new[] { 0, 1, 2, 0, 2, 3 });
}
public static ArrayMesh Triangle() => Build(
new[] { new Vector2(-45, -40), new Vector2(50, -17), new Vector2(-20, 45) },
new[] { Vector2.Zero, Vector2.Right, Vector2.Down },
new[] { 0, 1, 2 });
private static ArrayMesh Build(Vector2[] vertices, Vector2[] uv, int[] indices)
{
var arrays = new Reckfell.Collections.Array();
arrays.Resize((int)Mesh.ArrayType.Max);
arrays[(int)Mesh.ArrayType.Vertex] = vertices;
arrays[(int)Mesh.ArrayType.TexUV] = uv;
arrays[(int)Mesh.ArrayType.Index] = indices;
var mesh = new ArrayMesh();
mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
return mesh;
}
}CanvasAaExample.cs
using Reckfell;
public partial class CanvasAaExample : Entity2D
{
[Export] public Viewport.Msaa Antialiasing { get; set; } = Viewport.Msaa.Disabled;
public override void _Ready()
{
GetViewport().Msaa2D = Antialiasing;
AddChild(new MeshInstance2D
{
Mesh = CanvasMeshes.Triangle(),
Position = GetViewportRect().Size * 0.5f + new Vector2(0.3f, 0.2f),
Rotation = 0.17f,
Material = new CanvasItemMaterial { LightMode = CanvasItemMaterial.LightModeEnum.Unshaded }
});
}
}Configure the intended Viewport
GetViewport().Msaa2D changes the Viewport owning this entity. A SubViewport rendering its own image needs its own setting; do not assume the main window option is shared by every render surface. The project also has rendering/anti_aliasing/quality/msaa_2d, but runtime code can override the selected Viewport.
Compare images at the same output dimensions. Enlarged screenshots, browser zoom and later image stretching can hide or introduce stair steps. This test reads the original Viewport texture pixels rather than judging a thumbnail.
When MSAA does not solve it
- Compatibility edges stay unchanged: this is a confirmed backend limitation, not a reason to keep increasing sample count.
- Texture detail is blurred: check TextureFilter and scaling independently from MSAA.
- Aliasing occurs inside a shader pattern: change its sampling/calculation rather than only the geometry-edge setting.
- A type exposes Antialiased or a draw command accepts antialiased: use the appropriate local mechanism and check its restrictions. It is not a switch for whole-canvas MSAA.
- Rendering becomes more expensive: compare GPU time and memory on target hardware; 4× is not automatically free.