Text in front of objects in Graphics3D

In Graphics3D, Text objects are rendered in front of other objects. Does anyone have a workaround for turning off that feature? I need to render several hundred spheres, each with a bit of Text floating on top, and I would like to allow spheres in front to obscure those in back, including the text. I could render the spheres with ParamtricPlot3D, and use Texture to add a label to each. I’m hoping there’s a simpler way.

Text expressions don’t really seem to inhabit the same space as graphics 3d expressions. See this example from the documentation:

Graphics3D[{Text[4 Pi r^2, {0, .5, .5}], Sphere[]}, Axes -> True]

The best way to get the text to actually be part of the 3D graphics is to make the text a texture on top of some sort of 3D graphic element. I don’t know of any examples of this off the the top of my head, but basically, you want to Rasterize the text and use it as Texture expression on a polygon or on the surface of your Sphere. This often requires some nontrivial tweaking to get something that you would want to present.

That’s what I did. Much slower, but it works like a charm. Look for the result on the cover of the Sept. 2013 issue of Math Horizons!

Bruce, We are glad it worked out for you. If there is any chance of posting cover image or at least linking to it after it comes out - please do! We will very much enjoy having it here and looking at your paper.

The Sept. 2013 issue of Math Horizons just went to press this afternoon. Here’s the cover -- it relates to a story by Jordan Ellenberg on Tom Zhang’s bounded-gap theorem from last spring. The image is an Ulam spiral showing the first few twin primes. It was made with Mathematica using spheres & tubes, and texture wrapping each sphere with a wrapper showing its number. The spiral is really a pyramid viewed from above, which allows more numbers to be crammed in around the edges. I’m happy to share the code if anyone is interested.

Please do share the code you used! We’d love to see it.

This is great, Bruce! Congratulations on the beautiful cover and, I am totally with Dan here, - yes, please share the code :wink:

Here’s the code. The cover image used m=20, and the final ImageSize was set to 5200 (the highest value I could get without risking a crash). I exported the image as a PNG, and used Photoshop’s shift-tilt filter to introduce the blurred edges. I could have done that in mma, of course, but it’s hard to argue with the simplicity of the photoshop filter. If you run this with something small, like m=4, you can easily grab and rotate the resulting image to see the pyramid structure.

Clear[s, e, n, w, dir, tab, m, \[Delta], positions, allPrimes, 
  twinPrimes, sph, ulam];
m = 4; (* m is the no. of spiral "laps", so (2m)^2 numbers will be \
displayed *)
\[Delta] = .1; (* \[Delta] = vertical depth added to \
pyramid for each number *)
dir = {s, e, n, 
  w}; (* directions: south, east, north, west *)
tab = {};
Do[dir = RotateLeft[dir]; AppendTo[tab, Table[First[dir], {k}]];
  dir = RotateLeft[dir]; 
  AppendTo[tab, Table[First[dir], {k}]], {k, 1, 2 m}];
positions = 
  FoldList[Plus, {0, 0, 0}, 
   Take[Flatten[tab], 4 m^2 - 1] /. {e -> {\[Delta], -1, 0}, 
     n -> {\[Delta], 0, 1}, w -> {\[Delta], 1, 0}, 
     s -> {\[Delta], 0, -1}}];
allPrimes = PrimeQ[Range[4 m^2]];
twinPrimes = 
  MapThread[
   Or, {MapThread[
     And, {allPrimes, Join[{False, False}, Drop[allPrimes, -2]]}], 
    MapThread[
     And, {allPrimes, Join[Drop[allPrimes, 2], {False, False}]}]}];
sph[k_, pos_, highlight_] := 
  Translate[
   SphericalPlot3D[.3, {\[Theta], 0, Pi}, {\[Phi], 0, 2 Pi}, 
     Mesh -> None, 
     PlotStyle -> 
      Texture[Graphics[
        Style[Text[k, {0, 0}, {0, 0}, {0, 1}], 128, 
         FontFamily -> "Optima"], AspectRatio -> 2, 
        Background -> 
         If[highlight, RGBColor[1.`, 1.`, 0.`], RGBColor[.5`, .5`, .5`]], 
        ImageSize -> 400]], 
     TextureCoordinateFunction -> ({#4, #5} &)][[1]], pos];
ulam = Graphics3D[{
   {Gray, Tube[positions, .05]},
   MapThread[sph, {Range[4 m^2], positions, twinPrimes}]
   }, ViewPoint -> {-1.8, 0, 0}, PlotRangePadding -> None, 
  Boxed -> False, Lighting -> "Neutral", ImageSize -> 600, 
  Background -> Black]