Message Boards Message Boards

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}

enter image description here

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.

enter image description here

POSTED BY: Martijn Froeling
4 Replies

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.

POSTED BY: Henrik Schachner
Posted 1 month ago

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}

enter image description here

POSTED BY: Yuzhu Lu

Awesome!! I'm well aware I'm pushing the limits by finding the most expensive renders each time ;) 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

POSTED BY: Martijn Froeling

On my MacBook Pro M1 the render times are

{0.021712, 0.021005, 1.2053, 1.20494}
POSTED BY: Gianluca Gorni
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract