enthought / mayavi

3D visualization of scientific data in Python
http://docs.enthought.com/mayavi/mayavi/
Other
1.3k stars 285 forks source link

Add anti aliasing #183

Open dmsurti opened 9 years ago

dmsurti commented 9 years ago

Add anti aliasing to renderer.

itziakos commented 9 years ago

is this related to #102?

dmsurti commented 9 years ago

Yes, though only partly. #102 is only a work around for using anti aliasing in VTK < 6.2. With OpenGL2 backend, anti aliasing must be enabled by default. This is the overall intended solution.

dmsurti commented 9 years ago

After adding MSAA support with 8 samples, the performance degrades. As VTK is moving towards OpenGL2 backend, the best option is to add FXAA (Fast Approximate Anti Aliasing) which provides the best balance of performance and quality. The online benchmarked number for FXAA is 1.3 ms/frame.

FXAA needs to be added to the post processing pipeline here: https://gitlab.kitware.com/vtk/vtk/tree/master/Rendering/OpenGL2/glsl

JohnLunzer commented 9 years ago

I'll comment here because it seems relevation. I had been using mayavi for a few days and it felt like AA was enabled (I'm guessing MSAA?). Over the past couple days I can't get AA to engage anymore. Setting fig.scene.anti_aliasing_frames makes no difference (but is by default set to 8). The aa_frames setting is not acceptable because it causes severe slowdown. I've even dug down and set vtk_window.polygon_smoothing to True but this causes an artifact (very slight spacing between the polygons).

Am I missing something with getting MSAA to work?

dmsurti commented 9 years ago

@JohnLunzer AA frames is an option when your OpenGL does not support antialiasing and it is a slow implementation. AA frames = 5 or 6 is suggested value for reasonable performance, as per VTK docs. http://www.vtk.org/doc/nightly/html/classvtkRenderWindow.html#ab65de98e425838230cbd5760bcda4457

In order to get MSAA working (assuming your OpenGL supports it), in mayavi doing this should get you anti aliasing: On scene's render window do this:

self.scene.render_window.point_smoothing = True
self.scene.render_window.line_smoothing = True
self.scene.render_window.polygon_smoothing = True
self.scene.render_window.multi_samples = 8 # Try with 4 if you think this is slow

Also you can choose which ever primitive (point, line, polygon) you want to smooth. HTH.

JohnLunzer commented 9 years ago

Somehow magically MSAA turned back on without artifacts (so my OpenGL must support it). I'm on windows 7 with mayavi 4.4.0 running scripts in IPython with Spyder.

Now, with MSAA always on, when I adjust these settings by referencing fig.scene.render_window nothing happens, I can't turn it off. The smoothing settings worked when MSAA wasn't working, but like I said they created weird artifacts (spaces between polygon faces).

In my research I found that those settings are only supposed to work if set before the first render, which I wasn't able to figure out how to do given mayavi's architecture. However I found that calling fig.scene.render_window.open_gl_init() could turn on/off the smoothing settings even after the first render.

Still very confused about what is happening. Are there no other places where MSAA is affected? Config files? tvtk settings?

dmsurti commented 9 years ago

fig.scene.render_window.multi_samples = n, where n > 0 turns on multi sampling. n = 4 or 8 are suggested values. If n = 0, it turns off multi sampling.

You are right that the settings should be applied before the first render. In mayavi, before show() call when using mlab, applying these settings should work. If you can post a working code snippet, that will help.

JohnLunzer commented 9 years ago

The code below creates simple setup for plotting vectors and by default automatically labeling them.

I've commented out the bit where I would turn on/off hardware antialiasing (MSAA).

From my understanding just calling mlab.figure() does a first render (maybe I'm wrong) which is why I was having trouble turning on/off MSAA before it got stuck on (but I figured out that open_gl_init() can overcome this).

With my setup in it's current state MSAA is always on and I can not turn it off. If the commented section in uncommented the MSAA is not affected. I've tried from within Spyder, from command line IPython, and simply by running python test.py.

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 24 09:02:47 2015
@author: Lunzer
"""

from mayavi import mlab

fig1 = mlab.figure(bgcolor=(0.1,0.1,0.1),size=(1024,768))
fig1.scene.parallel_projection = True

#fig1.scene.render_window.point_smoothing = False
#fig1.scene.render_window.line_smoothing = False
#fig1.scene.render_window.polygon_smoothing = False
#fig1.scene.render_window.multi_samples = 0
#fig1.scene.render_window.open_gl_init()

fig1.scene.show_axes = True

axColor = (0.45,0.45,0.45)
centerAxis = mlab.points3d(0.0, 0.0, 0.0, 4, mode='axes',color=axColor,
                      line_width=1.0, scale_factor=1.,opacity=1.0)
centerAxis.actor.property.lighting = False

axes = mlab.axes(centerAxis, color = axColor, nb_labels=9)
axes.property.display_location = 'background'
axes.title_text_property.opacity = 0
axes.label_text_property.bold = 0
axax = axes.axes
axax.label_format = '%-#6.2g'
axax.fly_mode = 'none'
axax.font_factor = 1.0

def quiv3dlabels(vectors=(0,0,0,1,1,1),mode='arrow', scale_factor=1, 
                 colormap='gist_rainbow', scale_mode = 'vector', resolution = 12,
                 labels = None):
    x,y,z,u,v,w = vectors
    numVectors = len(x)    
    quivs = mlab.quiver3d(x,y,z,u,v,w,mode=mode, scale_factor=scale_factor,
                          scale_mode = scale_mode,colormap=colormap,
                          resolution = resolution)
    quivs.glyph.color_mode = 'color_by_vector'
    quivsProperties = quivs.glyph.glyph_source.glyph_source
    quivsProperties.shaft_radius = 0.006
    quivsProperties.tip_length = 0.08
    quivsProperties.tip_radius = 0.02

    retLabels = list()
    indexes = range(numVectors)
    if labels and len(labels) == numVectors:    
        pass
    else:
        labels = ['v'+str(ind) for ind in indexes]
    for ind,label in zip(indexes,labels):
        x,y,z,u,v,w = vectors[0][ind], vectors[1][ind], vectors[2][ind],\
                      vectors[3][ind], vectors[4][ind], vectors[5][ind]
        text = mlab.text(x=x+u/2.,y=y+v/2.,z=z+w/2.,
                         text=str(label), width=0.01*len(label))
        retLabels.append(text)
    return quivs, retLabels

v1 = ( 0, 0, 0, 4, 4, 4)
v2 = ( 1, 0, 1,-2,-4, 5)
v3 = (-1, 2,-4, 5, 0,-1)
v4 = ( 0, 0, 0,-3,-3,-4)
v5 = (-3,-3,-4, 4, 5,-8)
vectors = zip(v1,v2,v3,v4,v5)

quivs, _ = quiv3dlabels(vectors)
dmsurti commented 9 years ago

Opened Issue #234 related to anti aliasing in mlab.

About OpenGL_init, this function is meant only to be called by concrete implementations of the abstract class vtkOpenGLRenderWindow. So if you do call this as in your example, your OpenGL context could be unreliable. https://gitlab.kitware.com/vtk/vtk/blob/master/Rendering/OpenGL/vtkCocoaRenderWindow.mm#L352

raultron commented 4 years ago

If someone has this problem in Linux and you have a Nvidia Card you can use the Nvidia X Server Settings to override the application antialiasing settings. This will force antialiasing in all OpenGL windows including Mayavi renders.