K3D-tools / K3D-jupyter

K3D lets you create 3D plots backed by WebGL with high-level API (surfaces, isosurfaces, voxels, mesh, cloud points, vtk objects, volume renderer, colormaps, etc). The primary aim of K3D-jupyter is to be easy for use as stand alone package like matplotlib, but also to allow interoperation with existing libraries as VTK.
MIT License
921 stars 123 forks source link

Surface mesh rendering with opacity #313

Open sina-mansour opened 2 years ago

sina-mansour commented 2 years ago

Hello,

I would like to first thank you for your amazing effort in implementing this package. I find it intuitive and much needed.

I've been using this package for a while and have run into a rendering issue when trying to render a surface mesh with opacity. This might be closely related to this other issue, but I just wanted to make sure.

So to give you an example this is the surface rendered with no opacity:

image

And this is the same surface after adding opacity:

image

I had run into the same problem a while ago when using mayavi, and back then, I was able to solve it by enabling backface_culling and frontface_culling for the rendered surfaces.

I just wanted to ask if this is a known issue and whether you are working on a solution.

Additionally, currently, the way opacity is handled, the whole surface mesh is going to have the same level of opacity.

However, in other tools, like mayavi there's a feature to assign RGBA values to every vertex, hence the opacity of different vertices can be different. Would it be possible to add in an array for opacity instead of a single value, to indicate the opacity of all vertices separately?

artur-trzesiok commented 2 years ago

@sina-mansour thanks for sharing. The problem with opacity is indeed very similar. I have on my development branch depth_peels implementation. Can you send me a code to produce those images artur.trzesiok@gmail.com? I will check if new version will fix your problem well and send screenshot back here.

In K3D we have k3d.mesh(colors=[...]) to pass per vertex color. It shouldn't be that hard to add opacities=[...] param. I will think about it.

sina-mansour commented 2 years ago

Hi Artur,

I've emailed you the files to regenerate this figure, I also wanted to include a reference image here, of what I think rendering with opacity should look like. This is basically what I get with mayavi:

image

In mayavi, the command that makes opacity work is adding depth_peeiling: scene.renderer.set(use_depth_peeling=True)

artur-trzesiok commented 2 years ago

Hi @sina-mansour

Thanks for your response. I used data from your email + developers version of k3d with depth_peels:

image

So I hope that depth peels in k3d are on good track.

sina-mansour commented 2 years ago

Hi @artur-trzesiok,

Many thanks for that. do you recommend that I switch to the developer version of k3d or is this going to be released soon?

I've also noticed that the depth peeling parameter in your screenshot seems to be an integer and not a boolean, what do different values mean? Does higher mean better but more computationally expensive?

I also look forward to the feature for variable opacities for vertices. (The picture below was generated with mayavi as an example, the vertices on top have an opacity of 1, but opacity is lower in the bottom.)

image

P.S. upon closer inspection, I think there seems to be some sort of artifact still present in the screenshot you've shared, I've tried to highlight these regions in the screenshot below, Do you know why that is happening?

image

I think this has something to do with the original order of vertices. The same artifacts were also present in my screenshot earlier:

image

artur-trzesiok commented 2 years ago

I've also noticed that the depth peeling parameter in your screenshot seems to be an integer and not a boolean, what do different values mean? Does higher mean better but more computationally expensive?

DepthPeels is always a integer value. Some libraries can hide some internal implementation. Number of depth peels is correlated with question "how many surafaces with opacity can be located under some camera positions in the same place of view?" So with depth peels = 7 it mean that we can handle 7 (single depth peels) or 14 (dual depth peels) surfaces

P.S. upon closer inspection, I think there seems to be some sort of artifact still present in the screenshot you've shared, I've tried to highlight these regions in the screenshot below, Do you know why that is happening?

Isn't it very similar to mayavi output?

sina-mansour commented 2 years ago

I can definitely assure you that while the difference is minimal, it definitely comes from an artifact that is somehow related to the order in which the surface vertices are defined.

Let me elaborate on that with a figure. The figure below renders the very same surface in mayavi and colors it with a jet colormap and according to the order of vertex indices:

image

As you can see the borders of the colors in this image are exactly where the artifacts show in the screenshots I've annotated with red lines above. In the figure below I've added the same annotations to the colored surface:

image

However, this is a similar figure rendered with mayavi, and as you can see those artifacts are not present:

image

Comparing this figure with the one you've shared, I agree that after adding the depth peeling option, the figure looks more like what it should look like, i.e, opacity is rendered properly. However, for some reason which is unclear for me, the brightness of the vertices seem to relate to its index and all vertices are not rendered alike.

I'm not sure if my explanation helped with regards to what I mean by the artifact or not. Do you see what I'm referring to?