Combining Graphics3D with MaterialShading and Opacity

Im trying to render two objects together, one with MaterialShading and one with Opacity.
However, when combining these objects my computer becomes very slow and for large objects the frontend even crashes.

I managed to get a toy example running that shows the issue.
By combining these two objects the graphics rendering time goes from a fraction of a second to over 4s.
does anyone know what is going on here or has any solutions?

dat = Table[
   x^2 + y^2 - z^2 + RandomReal[0.1], {x, -2, 2, 0.2}, {y, -2, 2, 
    0.2}, {z, -2, 2, 0.2}];
g1 = First@
   ListContourPlot3D[dat, Contours -> {0}, Mesh -> None, 
    ContourStyle -> Directive[{Blue, Opacity[0.5]}]];
g2 = {MaterialShading["Gold"], Tube[RandomReal[20, {10, 10, 3}]]};

gr1 = Graphics3D[{g1}];
gr2 = Graphics3D[{g2}];
gr3 = Graphics3D[{g1, g2}];
gr4 = Show[gr1, gr2];

{gr1, gr2, gr3, gr4}
Graphics`RenderTiming /@ {gr1, gr2, gr3, gr4}

I’m on Mathematica 14.1 with Windows 10.

As a indication what needs to be rendered see below, the left does not has surface volumes rendered, the right does. The render times are already quite large so the times 100 as in the example wont work.

On my MacBook Pro M1 the render times are

{0.021712, 0.021005, 1.2053, 1.20494}

Yes, This is the most expensive combination. But there is an option for performance goal, (you need to list opaque objects before all transparent objects) to get a more rendering accurate result:

dat = Table[
   x^2 + y^2 - z^2 + RandomReal[0.1], {x, -2, 2, 0.2}, {y, -2, 2, 
    0.2}, {z, -2, 2, 0.2}];
g1 = First@
   ListContourPlot3D[dat, Contours -> {0}, Mesh -> None, 
    ContourStyle -> Directive[{Blue, Opacity[0.5]}]];
g2 = {MaterialShading["Gold"], Tube[RandomReal[20, {10, 10, 3}]]};

gr1 = Graphics3D[{g1}];
gr2 = Graphics3D[{g2}];
gr3 = Graphics3D[{g2, g1}, 
   BaseStyle -> 
    RenderingOptions -> {"3DRenderingMethod" -> "HardwareDepthBuffer"}];
gr4 = Show[gr2, gr1, 
   BaseStyle -> 
    RenderingOptions -> {"3DRenderingMethod" -> "HardwareDepthBuffer"}];

{gr1, gr2, gr3, gr4}
Graphics`RenderTiming /@ {gr1, gr2, gr3, gr4}

Awesome!!
I’m well aware I’m pushing the limits by finding the most expensive renders each time :wink: and are very happy that each time you are providing me with solutions.

Exactly what i needed, this trick is speeding up my other renders as well.

Thanks again

Yes - just awesome, many thanks! I should have known this option much sooner - quite often I simply did not use Opacity[] because it was greatly slowing down everything.

(you need to list opaque objects before all transparent objects)

Interestingly, when you do it just the other way, the respective object becomes transparent from one side only, e.g. compare:

goldSticks = {MaterialShading["Gold"], Tube[RandomReal[20, {10, 10, 3}]]};
glassPlate = {Opacity[.5], InfinitePlane[{{1, 10, 0}, {0, 10, 0}, {0, 10, 1}}]};

Graphics3D[{goldSticks, glassPlate}, BaseStyle -> RenderingOptions -> {"3DRenderingMethod" -> "HardwareDepthBuffer"}]

with

Graphics3D[{glassPlate, goldSticks}, BaseStyle -> RenderingOptions -> {"3DRenderingMethod" -> "HardwareDepthBuffer"}]

One might think of situations in which this effect is wanted.