Antialiasing in in slice (MPR) views

Multi-sampling is the true antialiasing method, but that would mess with the Z buffer, and therefore with hardware-accelerated picking that is used for markup nodes label display and control point manipulation, compositing volume rendering and surface rendering, etc. Also as @pieper mentioned there seem to be some some issues with it in recent VTK and Qt versions (for example, I don’t think the MSAA setting has any effect right now on Windows).

Alternatively, you can do screen-space antialiasing using FXAA. It is very fast and simple, but it can alter any displayed content in the renderer (may makes boundary of line-like structures blurry), so it can be applied safely to renderers such as 2D overlays (markup interactors, labels, etc.), but need to be careful with applying to renderers that display images.

You can enable FXAA to all renderers of a slice or 3D views using this code snippet:

def enableFXAA(view, enable):
    renderWindow = view.renderWindow()
    renderers = renderWindow.GetRenderers()
    for renderer in renderers:
        renderer.SetUseFXAA(enable)
    slicer.util.forceRenderAllViews()

# For slice view:
enableFXAA(slicer.app.layoutManager().sliceWidget('Red').sliceView(), True)

# For 3D view:
# enableFXAA(slicer.app.layoutManager().threeDWidget(0).threeDView(), True)

FXAA has trouble with smoothing thin lines and may cause various artifacts. So, while it is extremely fast and simple, it would need some more experimentation to see how it could be utilized in Slicer.

Finally, there is also a computationally expensive but high-quality option: using an SSAAPass (render into higher-resolution image and sample down). You can try it with this code snippet:

def setupSSAA(view, enable):
    renderWindow = view.renderWindow()
    renderer = renderWindow.GetRenderers().GetFirstRenderer()
    # create the basic VTK render steps
    basicPasses = vtk.vtkRenderStepsPass()
    # finally blur the resulting image
    # The blur delegates rendering the unblured image
    # to the basicPasses
    ssaa = vtk.vtkSSAAPass()
    ssaa.SetDelegatePass(basicPasses)
    # tell the renderer to use our render pass pipeline
    if enable:
        renderer.SetPass(ssaa)
    else:
        renderer.SetPass(basicPasses)
    slicer.util.forceRenderAllViews()

#setupSSAA(slicer.app.layoutManager().sliceWidget('Red').sliceView(), True)
setupSSAA(slicer.app.layoutManager().threeDWidget(0).threeDView(), True)

This works quite nicely, but it tends to make thin lines much thinner, and it messes up Z buffer similarly to MSAA (volume rendering is not composited correctly with surfaces, depth peeling does not work, etc.). I haven’t experimented with it much, maybe these issues can be addressed.

I would also mention that I have a hi-dpi laptop and I can barely see aliasing artifacts. So, in some cases upgrading the hardware might be an option, too.