Transparent DisplayMaterial issue in C#

Hi all,

I am having issues with transparent material for a CustomBrepObject, hope anyone could point me a direction. So here is a screenshot for illustration:

  1. The original geometries (looks all fine with transparent objects).

  2. Copied from above original geometries (gumball + drag + Alt). The top brep is seeing through all objects below as if there’s nothing behind.

  3. Copied from above original geometries, and moved. The top brep is not showing correctly with the color of below objects.

Here is what I did for OnDraw in my CustomBrepObject:

        protected override void OnDraw(DrawEventArgs e)
        {
            if (e.Display.DrawingSurfaces)
            {
                var material = new DisplayMaterial(Color.FromArgb(120, 75, 190), 0.2);
                var mesh = RH.Mesh.CreateFromBrep(this.BrepGeometry, RH.MeshingParameters.Default);
                e.Display.DrawMeshShaded(mesh, material);
            }
            else
            {
                base.OnDraw(e);
            }
        }

(note: code above is simplified for illustrating the problem)

I tried to set the material IsTwoSided to true, or set mesh.VertexColors with the color with alpha value, but they doesn’t improve anything.

            material.IsTwoSided = true;
            material.BackDiffuse = material.Diffuse;
            material.BackTransparency = material.Transparency;

There are a several posts mentioned about EnableDepthTesting and EnableDepthWriting, etc, I couldn’t get them work.

I also tried to create custom DisplayConduit, it only works fine if I reorder the objects based on their distance from the camera. But this is very intensive, and Rhino’s view gets very slow when I have about 200 breps.

Hope this provides you enough information to understand this issue.
Thanks so much in advance.

cc @dale @jeff

Hi @mingo1214,

This looks like an ordering issue…but the concept of “transparency” is more complicated than it might seem…Let me try briefly explaining…

There is no such thing as “transparency” inside a computer. You can’t just say “I want something transparent” and voila!, it’s transparent. Transparency is a “special effect”, that is done through trickery and blending, that results in making your brain think it’s “seeing through” something on the screen. This can be done in several different ways, using several different techniques.

So how does Rhino’s display pipeline do it? It uses a somewhat modified “painter’s algorithm” for all transparent objects. That means, that all non-transparent objects MUST be drawn first, then all transparent objects are sorted from furthest to closest order, and then drawn on top everything else, applying a blending factor with its transparent color, and with whatever pixels it overlays.

It’s actually a lot more complicated than that due to hollow objects and opened, non-solid objects…certain things need to happen for back faces before front faces, etc… but I hope you get the general idea.

Therefore, if any of your “transparent” objects get drawn too soon, or before any non-transparent objects, then you lose the “effect”, and they will no longer appear to look transparent.

That being said, since this is more complicated than just drawing an object, and very specific internal steps must be made, there isn’t any good provision for this for third party objects. Given all of the different channels and phases within the pipeline, plugins can draw anything they want, anywhere they want, and it sounds like you’re objects are all getting drawn along with the other, non-transparent objects.

Sorry for the long winded reply, but I just wanted you to understand why the next suggestion is being made…

The only way to come close to getting third party objects to appear transparent, is to make sure they’re drawn last in the pipeline channels. That is done using the PostDrawObjects channel. If you draw all your transparent objects in that channel, there’s a much better chance they will look the way you want and expect them too, but even then, there’s no guarantee, since there might be other plugins in play.

So, the code you have above to setup a transparent material looks fine, you just need to draw the objects at the last possible moment within the pipeline.

If that still doesn’t work, then it’s probably something else that’s not working, and I’ve wasted your time…But I’ll probably need a working, compilable source code example that I can step through and see what you’re doing and why it’s not working.

Thanks,
-Jeff

Hi @jeff

Thanks so much for your explanation, yes, I have seen a several posts that you explained about how transparent objects work in theory and Rhino.

Currently I just override the OnDraw of each CustomBrepObject, so the drawing order is controlled by Rhino. Before doing this, I was using drawing all CustomBrepObject within DisplayPipeline.PostDrawObjects, But there are always a lot of pieces doesn’t look right here and there.

How does Rhino decide in which order an object to be drawn when I override the OnDraw method? If this is too late to let Rhino know an object is transparent in OnDraw, how do I tell Rhino that this is transparent before Rhino figuring out the drawing order?

I just put a sample repo so that you can use to recreate this issue. This is the test model that you can use, and use command “TransparentRhinoObjectCommand” to convert them to CustomBrepObject once you have the following test plugin compiled.

Please let me know if you need anything else. Thanks again.

TransparentTest.3dm (731.2 KB)