Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Opacity of streamlines interacting with visual ordering of visualization modules #491

Closed
Mallcock1 opened this issue Mar 6, 2017 · 10 comments

Comments

@Mallcock1
Copy link

Changing the opacity of streamlines to anything other than its default value (1.0) brings the streamlines to the front of the scene even when there are other objects that should obscure them.

For example, I refer you to the magnetic fieldline example given here: http://docs.enthought.com/mayavi/mayavi/auto/example_magnetic_field_lines.html.

Running the code as it is gives the following scene:
test_bug_1

However, if we change the opacity of the fieldlines so that it is different it its default value of 1.0 (either by adding field_lines.actor.property.opacity = 0.99 or by manually adjusting the opacity in the Mayavi pipeline) we get something like the following scene:
test_bug_2
The fieldlines are now at the front of the scene, however the isocontours should still obscure then like in the previous image.

@Mallcock1 Mallcock1 changed the title Opacity of streamlines interacting with visual ordering of visualization modules BUG: Opacity of streamlines interacting with visual ordering of visualization modules Mar 6, 2017
@Mallcock1
Copy link
Author

Is this an issue which will be fixable in the near future? If not, I would appreciate knowing so that I can find another way around my problem. Thank you

@luukko
Copy link

luukko commented May 10, 2017

This seems to apply to other objects as well. I'm using contour3d with points3d and setting the opacity of the points to anything other than 1.0 causes the surface not to obscure them anymore.

@jeswcollins
Copy link

jeswcollins commented Sep 24, 2017

I see what I think is the same issue with two points3d objects. Here are some examples showing how the appearance of 2 spheres rendered depends on rendering order if the opacity is set to .99, but not if opacity is set to 1.

mlab.figure()
mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100,opacity=.99)
mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100,opacity=.99)

2

mlab.figure()
mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100,opacity=.99)
mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100,opacity=.99)

4

mlab.figure()
mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100)
mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100)

1

mlab.figure()
mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100)
mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100)

3

The issue does not seem to depend on choice of lights or light_manager ('vtk' or 'raymond').

I suppose one workaround may be first sorting the objects to be rendered by their depth along an axis into or out of the screen.

@prabhuramachandran
Copy link
Member

You probably need to set the front-face culling option on. Try this:

mlab.figure()
g1 = mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100,opacity=.99)
g2 = mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100,opacity=.99)
g1.actor.property.frontface_culling = True
g2.actor.property.frontface_culling = True

@jeswcollins
Copy link

jeswcollins commented Sep 24, 2017

Thanks Prabhu---I think the frontface_culling improved the visuals, but the rendering order still was a factor only in the semi-transparent case.

I reproduced that observation in vtk alone (it's a lower level issue).

After more reading, I think there is a solution or two built into vtk, but another solution may be to sort the objects before rendering.

Here are a couple links about vtk that seemed relevant:
https://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/CorrectlyRenderingTranslucentGeometry
https://www.vtk.org/Wiki/VTK/Depth_Peeling

And a couple links I used for reproducing the sphere case:
https://lorensen.github.io/VTKExamples/site/Python/GeometricObjects/Sphere/
https://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/Opacity

@Mallcock1
Copy link
Author

Mallcock1 commented Sep 25, 2017

Thanks for adding to the discussion and for the helpful links. I am not very knowledgeable about VTK or depth peeling, but a simple solution that I found that worked for my original example and the project I am working on was to include this:

scene = mlab.gcf().scene
scene.renderer.set(use_depth_peeling=True)

which I adapted from this question about a similar issue..

@jeswcollins
Copy link

jeswcollins commented Sep 29, 2017

Thanks for the help Matt and Prabhu.

I tried depth_peeling, which for my actual use case is more helpful than it is for this 2 sphere example. But compared to reordering the spheres, the edges seem less...anti-aliased I think might be the term?

f=mlab.figure()
f.scene.renderer.use_depth_peeling=1
g0=mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100,opacity=.99)
g1=mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100,opacity=.99)  
g0.actor.property.frontface_culling = True
g1.actor.property.frontface_culling = True

image

For my 3d plotting, I have a list of points and a list of colors. So instead of depth peeling I used this function to reorder those lists together before plotting:

def orderTransparentRender(cl,c):
    '''Opacity < 1 rendering results in appearance of spheres incorrectly in front of or behind other spheres
    One solution is setting f.scene.renderer.use_depth_peeling=1, however this seemed to result in less anti-aliased edges?
    This function sorts the cluster list cl and color list c together.
    '''
    cz=zip(cl,c)
    cz=sorted(cz,key=lambda x:-1*x[0][2])
    cz=zip(*cz)
    return cz[0],cz[1]

Otherwise the sorted call could be all that's required. I learned that from the python docs: https://wiki.python.org/moin/HowTo/Sorting. I learned about python's zip here: https://stackoverflow.com/questions/1663807/how-can-i-iterate-through-two-lists-in-parallel

@prabhuramachandran
Copy link
Member

With recent VTK versions this works well for me:

from mayavi import mlab
f = mlab.figure()
mlab.points3d(0,0,1,color=(.8,.8,.8),resolution=100,opacity=.99)
mlab.points3d(0,0,0,color=(.8,.8,.8),resolution=100,opacity=.99)
f.scene.renderer.use_depth_peeling = True

Also, there is an f.scene.renderer.maximum_number_of_peels that you could potentially use. It is 4 by default but you could set it to zero for no limit although this will slow down rendering. You could tinker with this.

May I close this issue? I think this does seem to fix many problems I have seen before.

@Mallcock1
Copy link
Author

Mallcock1 commented Aug 26, 2018 via email

@prabhuramachandran
Copy link
Member

Great, thanks.

yoda-vid added a commit to sanderslab/magellanmapper that referenced this issue Feb 9, 2021
Reducing opacity by any amount causes front 3D objects in Mayavi to appear behind deeper surfaces from some angles. Turn on depth peeling after rendering 3D surfaces or points to fix this ordering as described in this issue: enthought/mayavi#491 .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants