Makie - drawing lines through transparent surface

Hi, I’ve been using Julia and the Plots package for a while, but only recently have tried using Makie for some visualizations, and ran into some problems. No matter what I try, I can’t get line segments to play nicely with transparent surfaces or with volumes.

As an MWE, if I make a simple surface and put line segments above and below it, I get what I would expect

using Makie
scene = Scene()

y = collect(-10:0.1:10)
x = y
z = zeros(length(x), length(y))

height = 5.0
x0 = 0.0
y0 = 0.0
z0 = 0.0
origin = Point3f0(x0, y0, height)
crosspt = Point3f0(x0, y0, z0)
finalpt = Point3f0(x0-2 ,y0+2, -height)
line1 = [origin, crosspt]
line2 = [crosspt, finalpt]
linesegments!(scene, line1,  linewidth=5, color=:red,)
linesegments!(scene, line2,  linewidth=5, color=:red,)
surface!(scene, x, y, z,  shading=false)

But if I change the last line to make the surface partially transparent as

surface!(scene, x, y, z, alpha=0.95, transparency=true, shading=false)

it draws the line as if the surface was completely transparent.

I have tried several variations of this (including changing the plotting order). Searching the forums I saw it suggested that alpha didn’t work correctly, so I attempted replacing the surface with meshes using explicit colors,

mesh!(scene, [-10,-10,10], [-10, 10, -10], [0,0,0], color=(:purple, 0.95), transparency=true, shading=false)
mesh!(scene, [-10,10, 10], [10, -10, 10], [0,0,0], color=(:purple, 0.95), transparency=true, shading=false)

but I get the same result.

Looking closely it seems the lines from the axis/grid also get drawn over the surface. Am I missing something about how transparency is supposed to work, or does it fundamentally not work with lines in Makie?

I am hoping someone in the community has some idea whats going on here. Thanks in advance.

This is an annoying problem…As if transparency isn’t hard enough already, I have two render targets for drawing primitives that need anti-aliasing (aa) and one that doesn’t…Lines don’t need aa, a.k.a fxaa (which is the algorithm i implemented), but a surface has fxaa enabled.
You can try this, to get better results:

using Makie
scene = Scene(camera = cam3d!)

y = collect(-10:0.1:10)
x = y
z = zeros(length(x), length(y))

height = 5.0
x0 = 0.0
y0 = 0.0
z0 = 0.0
origin = Point3f0(x0, y0, height)
crosspt = Point3f0(x0, y0, z0)
finalpt = Point3f0(x0-2 ,y0+2, -height)
line1 = [origin, crosspt]
line2 = [crosspt, finalpt]
linesegments!(scene, line1,  linewidth=5, color = :red, fxaa = true)
linesegments!(scene, line2,  linewidth=5, color = :red, fxaa = true)
surface!(scene, x, y, z, shading = false, colormap = [(:blue, 0.5), (:green, 0.5)], fxaa = true, transparency = true)

Thanks for the quick reply, this fixed the issue. There are some artifacts when a few bunched lines overlap, but it is minor. This also fixed a related issue I had where lines wouldn’t go through volumes.

If you don’t mind a related question, I am trying to figure out how to changes colors on volumes with absorption. In the example at

https://simondanisch.github.io/ReferenceImages/gallery//3d_cube_with_sphere_cutout,_outside/index.html

it seems the matrix adjusts the amount of red (first element in rgba). Because it uses algorithm = :absorptionrgba I am inferring that you could change all of the rgba channels, but I can’t figure out how. I’ve tried making the matrix elements tuples, RGBA objects, and passing one array for each channel, but not luck. Any suggestion is appreciated, thanks!

absorptionrgba will look up the color value from a colormap…
So you’ll need to supply colormap = vector_of_colors/symbol/... :wink:

First, thanks for all of the work on Makie, it is great to have this in Julia.

Even specifying a colormap I haven’t been able to get the volume to change color using absorptionrgba. However, this did work for indexedabsorption, so I think I am good to go. Thanks again for all of the help.

1 Like