Render order issue with with materials with lower opacity not being transparent when animating

-----------
Update:

I seem to have found some more information about my problem.

I made a video to summarize my issues: three render order issue - YouTube

Basically, depending on the order at which I load in my instances, it will cause either the red or the blue slices to render correctly. If I load all of the blue instances on the screen, set the opacity to zero, then do the same with the red, the blue will work while the red will not (vice versa).

-----------

Original Post:

Hello,

I am working on a three JS animation where multiple instances will be changing opacity as the render in to create slicing affect.

I created a video to showcase this: Rendering Issue 1 - YouTube

In this video, you can see how I have two separate animations going on: one to slice in the red boxes and one to slice in the blue. Each of these animations are composed of multiple instance meshes, one for each slice, that have different opacity timings. This creates a interlocking animation between the two colors with no overlaps.

Each work on their own, but when I attempt to combine both together, I end up getting a issue with the opacity not working.

If I attempt to make the blue slices transparent with zero opacity: rendering issue 2 - YouTube

Now they just turn up black and are not.

Each slice has the following material:

In this case, the opacity is zero (useCustom is true), and later animates to one.

 new three.MeshPhongMaterial({
   transparent: true,
   receiveShadow: true,
   opacity: useCustom ? this._threeModelAnimationOptions.animationMesh.custom[groupItem].opacity : this._threeModelOptions[groupItem].opacity,
   color: new three.Color(useCustom ? this._threeModelAnimationOptions.animationMesh.custom[groupItem].color : this._threeModelOptions[groupItem].color)
 })

Material property of the instance mesh. Each slice is added to the scene and has the opacity set to zero. When it animates it, it is set to one.

The code: maze3d-world/maze3d-es.js at 9ab1e50befa03fea3b7bd929a9b423970d9f54c6 · michaelnicol/maze3d-world · GitHub

Line 103 starts the settings. min and max opacity is what it starts at to the opacity it animates to.

var renderer = new three.WebGLRenderer({
            transparent:true,
            shadowMap: {
                enabled: true
            }
        });

Thank you for the response,

Using the code you provided does not fix on the problem from testing I have done.

@Chaser_Code The code snippet you have shared is wrong. The renderer has no context parameters transparent and shadowMap.

1 Like

Then that code from another github example

Hello Mungen87,

Thank you for the clarification,

I seem to have found some more information about my problem and have been able to narrow it down to the render order.

I made a video to summarize my issues: three render order issue - YouTube

Basically, depending on the order at which I load in my instances, it will cause either the red or the blue slices to render correctly. If I load all of the blue instances on the screen, set the opacity to zero, then do the same with the red, the blue will work while the red will not (vice versa).

Can you please create you transparent objects with the depthWrite option setting to false? Does this mitigate the issue?

The sorting in context of transparency is tricky and sometimes you need a completely different rendering technique to get transparency right (more or less). However, disabling depth writing is normally something you want to do when setting transparent to true.

1 Like

I edited the depthWrite of each of the Mesh Phong Materials. It seems to get close to looking correct as I can see both red and blue, but I am still having issues.

Video outlining this: depth false issue - YouTube

The way my program loads these objects is:

  1. Load all the instances on the screen. Either load the red or the blue first depending on the users settings. Each instance material has a opacity of 1.0 to start.
  2. Play all 48 animation mixers at once. Sets all of the materials to 0, and then at the right time set the opacity to 1 in order to create the slice in effect.

Does the order at which they are loaded onto the screen initially - scene.add(slice_instance) - correspond with the render order?

What rendering techniques can I use to mitigate this problem? I can write a function to accept the users renderer and apply the required properties if needed to get future renders to work properly. I am not knowledgeable in these settings however.

Edit:

I ended up just setting the alpha test to 0.5 and it solved it, but it isn’t a good solution. This is because now the animation doesn’t work if the user wants to animate start the animation from below 0.5 opacity for that slice. It also has odd affects where the opacity is either 0 or 1, it can’t be 0.6.

The render order depends on many factory. The depth order is one of the most important. However, since objects are ordered based on their position in world space, rendering transparency is often not as expected. For best quality, you have to sort on fragment level. Order-Independent-Transparency tries to solve this issue but this approach is not trivial and not yet supported in three.js.

The issue you are facing is complex and sometimes it’s best to avoid transparency at all if possible.

1 Like

Maybe without transparent. Use alphaTest and pixelated texture to see boxes through holes
image

Fat wireframe three.js examples

Thank you for the clarification.

I’ll just avoid this issue altogether by not using fade-in as a animation option for my program. It will just instantly appear or slide in.

Update me if you ever implement Order-Independent-Transparency. It does sound like a complex issue.