# How to improve visibility of surfaces with opacity?

Consider this example

Graphics3D[{EdgeForm[None], Opacity[0.5],
Blue,  Cuboid[{0, 0, 0}, {1, 1, 1/3}],
Green, Cuboid[{0, 0, 1/3}, {1, 1, 2/3}],
Red,   Cuboid[{0, 0, 2/3}, {1, 1, 1}],
Gray, Opacity[1], Sphere[{1/2, 1/2, #/3 - 1/6}, 0.1] & /@ {1, 2, 3}},
Boxed -> False]


For the green box, the edges and the surfaces in the back are also quite visible. For blue and red boxes the contrast is much smaller. How to improve it such a way that the edges would be visible from the difference in colour and also make the balls inside visible?

One possible way can be using an extra layer with slightly different opacity

Graphics3D[{EdgeForm[None], Opacity[0.5],
Blue, Cuboid[{0, 0, 0}, {1, 1, 1/3}],
Green, Cuboid[{0, 0, 1/3}, {1, 1, 2/3}],
Red, Cuboid[{0, 0, 2/3}, {1, 1, 1}],
Opacity[0.6],
Blue, Polygon[{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0}}],
Red, Polygon[{{0, 0, 2/3}, {0, 1, 2/3}, {0, 1, 1}, {0, 0, 1}}],
Gray, Opacity[1], Sphere[{1/2, 1/2, #/3 - 1/6}, 0.1] & /@ {1, 2, 3}},
Boxed -> False]


For a lot of boxes, it does not seem to be a good option.

• Why not just adjust the opacity of each layer "by eye"? (Create a Manipulate to help you along.) My general principle in cases such as yours is to set the opacity high (0.9) for objects that obscure no others, and incrementally lower for other layers, and low (0.2) for objects that are not obscured by others. You might try EdgeForm[Orange] too. Commented Feb 7, 2018 at 17:13
• Thanks, @DavidG.Stork. I have to keep Opacity<=0.5, because I have to put some sticks and balls inside the boxes. I prefer the edges free from lines - it looks better. The problem is only with few specific colours. I was wondering if it can be fixed by adjusting the Lighting and shadow. Commented Feb 7, 2018 at 17:31
• I urge you to put the sticks into your figure here, so we know the TRUE problem you're solving. Commented Feb 7, 2018 at 18:21
• @DavidG.Stork. I modified my question. The objective is to make both the surfaces of the boxes and the object inside visible. Commented Feb 8, 2018 at 7:51
• (1) The Lighting -> "Neutral" option in Graphics3D can help equalize variations in shading between different colours. (2) You could use something like FaceForm[Opacity[0.3], Opacity[0.7]] to make the front faces more transparent than the back ones.
– user484
Commented Feb 8, 2018 at 9:17

One (tedious) way is to define a box with different Opacity for different surfaces.

opqbox[{x1_, y1_, z1_}, {x2_, y2_, z2_}, {d_, u_, l_, r_, b_, f_}] := {EdgeForm[None],
Opacity[b], Polygon[{{x1, y1, z1}, {x2, y1, z1}, {x2, y2, z1}, {x1, y2, z1}}],
Opacity[u], Polygon[{{x1, y1, z2}, {x2, y1, z2}, {x2, y2, z2}, {x1, y2, z2}}],
Opacity[r], Polygon[{{x1, y1, z1}, {x2, y1, z1}, {x2, y1, z2}, {x1, y1, z2}}],
Opacity[l], Polygon[{{x1, y2, z1}, {x2, y2, z1}, {x2, y2, z2}, {x1, y2, z2}}],
Opacity[o], Polygon[{{x1, y1, z1}, {x1, y2, z1}, {x1, y2, z2}, {x1, y1, z2}}],
Opacity[f], Polygon[{{x2, y1, z1}, {x2, y2, z1}, {x2, y2, z2}, {x2, y1, z2}}]}

opc={0.5,0.15,0.35,0.20,0.25,0.25};
Graphics3D[{EdgeForm[None],Opacity[0.5],
Blue,opqbox[{0,0,0},{1,1,1/3},opc],
Green,opqbox[{0,0,1/3},{1,1,2/3},opc],
Red,opqbox[{0,0,2/3},{1,1,1},opc],
Gray,Opacity[1],Sphere[{1/2,1/2,#/3-1/6},0.1]&/@{1,2,3}},
Boxed->False]


d, u, l, r, b, f are the Opacity for down, up, left, right, back and front face.

This cube is made by the method suggested by Michael E2 in this answer.