# How to get shadows in Graphics3D?

It was a shock to me when I found that in Graphics3D a surface is always transparent to the light sources:

lightSources = {{"Directional", Red, Scaled[{1/2, 1, 1}]},
{"Directional", Green, Scaled[{1, 1/2, 1}]},
{"Directional", Blue, Scaled[{0, 0, 0}]}};
Show[Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi},
Lighting -> lightSources],
Graphics3D[{PointSize[Large],
Point[lightSources[[All, 3]],
VertexColors -> lightSources[[All, 2]]]}]]


One can see the surface on the right is blue-illumunated although this surface is completely shaded from the blue light source located at the point {0,0,-1}.

I feel such rendering is unacceptable. Is it possible to produce shadows in Mathematica?

## UPDATE

To clear up: by "shadows" I mean that the surfaces on the scene must not be transparent to the light sources (or, better, their transparency could be defined by a user). I need not drop shadows shown in the linked threads: (1), (2).

-
If it does have to be in Mathematica, you might try exporting to POV-Ray: Export["file.pov", plot] (Untested: POV-Ray has issues with Intel Macs) –  Michael E2 Jan 14 '13 at 13:55
@Alexey I think you'll have to spend some time learning about POV-Ray and add the light sources and surface characteristics (material) yourself. Or perhaps you can try to export to some other 3D format and try and easier to use renderer. Maybe try kerkythea.net I used it once but not with Mathematica. –  Szabolcs Jan 14 '13 at 15:52
@AlexeyPopkov That's certainly disappointing. I was just typing something like what Szaboics said, when his comment showed up. Mathematica apparently does not export the lighting and surface characteristics. –  Michael E2 Jan 14 '13 at 15:55
@Sjoerd I need surface rendering but with non-transparent surfaces for the light sources. I neen not drop shadows shown in the questions you referenced. –  Alexey Popkov Jan 15 '13 at 5:39

Try changing "Directional" to "Point" in your definition of the lightSources. If I understand your question that solves the problem.

-
That puts the lights in the right positions, but the problem that "the surface on the right is blue-illuminated although this surface is completely shaded from the blue light source" remains. –  Rahul May 25 at 19:35
It sure is. What a pain. –  N.J.Evans May 25 at 19:58

Im sorry i have a bit limited time at the moment so the answer will need to be revisited later.

While its true that the hardware of your computer could do this, and it could be included in by wolfram making shadows is usually considered a next step in rendering. I am not dwelling on why this doesn't work, as you can use any of the existing free raytracers out there. There are plenty heres a (really) partial list (by preference and suitability in this case, path of least resistance):

Highend stuff

Midend

• pixie R free
• Aqsis R free
• yafaray free
• ... lots and lots of other software and hardware renderers out there that can easily do the job

There are a lot more. The ones marked with R conform to the RI spec making it easy to swap between the systems. On top of that Mathematica supports RIB export. It also brings your pipeline quite a bit o future proof that no other solution would give.

Note, I think POV ray is not a suitable tool by todays standard.

Exporting the geometry to rib should be as simple as:

Export["s:\\temp\\test.rib", Plot3D[Sin[x y], {x, 0, Pi}, {y, 0, Pi}]]


over this you need to append the lights and shaders. Now the RIB file at this point is unrenderable. Because its missing

• Camera
• Materials
• Lights
• World

Lets add those. A suitable camera environment would be ( Im using 3Delight so the notation may differ very slightly for auto shadows feature)

#this is rib
PixelSamples 3 3
PixelFilter "sinc" 2 2

Display "output.tif" "tiff" "rgb"

Format 400 400 1
Projection "perspective" "fov" 20

Rotate 180 0 1 0

Translate 2.5 -0.5 -20
Rotate -50 1 0 0
Rotate 118 0 0 1


After this we need the world where the object resides:

 #still rib
WorldBegin
... items in world...
WorldEnd


inside this world each light needs something like this:

#rib also beween World
AttributeBegin
Translate 0 0 -1
Color   0 0 1
Surface "constant"
Sphere 0.1 -0.1  0.1 360.0
LightSource "pointlight" "l1"
"intensity" 5
"lightcolor" [0 0 1]
AttributeEnd
Illuminate "l1" 1


and finally the object which we can include test.rib:

#still rib
Attribute "visibility" "int transmission" [1]
Surface "matte"

I was not able to reproduce the image: it still gives a lot of identical errors: 3DL WARNING P1037: camera to screen matrix too general, reverting to identity, 3DL ERROR P1051: [d:/Desktop/test.rib:7]: invalid context for 'RiPointsPolygons'. It would help if you post somewhere a complete working .rib file with comments (for example, on PasteBin). –  Alexey Popkov Jun 29 at 16:13
It is not clear how to change the view angle and the distance from the object consistently. Probably I should multiply numbers in the Translate 2.5 -0.5 -12 line by a constant when I lower the view angle (the line Projection "perspective" "fov" 20)? –  Alexey Popkov Jun 29 at 19:55