3
$\begingroup$

I am using the Graphics3D command in Mathematica to plot multiple 3 dimensional parallelotopes and two of them have overlapping faces. These two shapes have different colored faces, so the textures of the two seems to jump between the two colors. Is there any way to remove one or both of the textures in the overlapped area? Picture relatedIn the red circle is an example of the two colors mixing and switching from one to the other

$\endgroup$
4
  • 3
    $\begingroup$ Please provide example code so we can easily reproduce the issue. $\endgroup$
    – kirma
    Commented Jun 10, 2020 at 14:43
  • 3
    $\begingroup$ This looks like z-fighting, see here: en.wikipedia.org/wiki/Z-fighting The effect is hard to avoid and is very pronounced in this example: Graphics3D[{Green, Cuboid[{0, 0, 0}, {1, 1, 1}], Red, Cuboid[{1/2, 1/2, 1/2}, {1, 1, 1}]}] $\endgroup$
    – flinty
    Commented Jun 10, 2020 at 15:14
  • 1
    $\begingroup$ You have probably specified the surfaces so that they are exactly the same distance away from the camera. In that case it's impossible for Mathematica to know what it is you want. To resolve that, you only have to add a negligible offset to one of the surfaces to indicate to Mathematica which surface is supposed to be perceived as being closer to the camera. For example, in flinty's example you may change the second parameter of the red cube to {1, 1, 1} + 0.0001 to fix the issue. $\endgroup$
    – C. E.
    Commented Jun 10, 2020 at 15:19
  • $\begingroup$ Related? (111945) $\endgroup$
    – MarcoB
    Commented Jun 10, 2020 at 15:59

1 Answer 1

7
$\begingroup$

As I mentioned in the comments, this is called z-fighting. It's hard to avoid and it produces ugly artifacts like in this example:

Graphics3D[{Green, Cuboid[{0, 0, 0}, {1, 1, 1}], Red, Cuboid[{1/2, 1/2, 1/2}, {1, 1, 1}]}]`

zfight

Your graphics card determines whether a triangle is occluded by another triangle using a z-buffer. If the z-buffer has too low of a precision this means the outcome will be subject to floating point rounding error and as you rotate the object you'll experience flickering and one surface popping out over another like this.

You can eliminate the z-fighting by making one face very slightly offset in a way that is visually unnoticeable but distinct enough that the depth buffer will consistently produce the occlusion of one triangle by another as you move the object:

tiny = 2^-16;
Graphics3D[{Green, Cuboid[{0, 0, 0}, {1, 1, 1}], Red, 
  Cuboid[{1/2, 1/2, 1/2}, {1 - tiny, 1 - tiny, 1 - tiny}]}]

zfight2

$\endgroup$
4
  • $\begingroup$ Very well explained. +1 $\endgroup$ Commented Jun 10, 2020 at 16:07
  • 2
    $\begingroup$ I was also wondering about this and Method -> {"RelieveDPZFighting" -> True} doesn't fix the problem at least for sheared cubes. A slight offset of coplanar surfaces does it. $\endgroup$
    – kirma
    Commented Jun 10, 2020 at 18:51
  • $\begingroup$ Thanks @kirma . I hadn't heard of that option. Maybe using BSP trees instead of z-buffering works? $\endgroup$
    – flinty
    Commented Jun 10, 2020 at 20:05
  • $\begingroup$ As @flinty points out, this is easily solved (so that the visible surface is the latter given to Graphics3D) by giving additional option BaseStyle -> RenderingOptions -> {"Graphics3DRenderingEngine" -> "BSPTree"} $\endgroup$
    – Anti Earth
    Commented Mar 6 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.