5
$\begingroup$

I am using a shadow function, planarShadow, as shared by Prof. Jens Nöckel on Shadows of 3D plots and objects This function works perfectly while making sharp shadows. However, I want to make blurry shadows just like if one is using DropShadowing[1] in $2D$. In the above-shared link, he talked about how a blur effect in 3D can in principle be created by using another method he described here, which is very complicated for me.

planarShadow[x_, direction_, normal_, darkShadow_ : True] := Module[{d, n}, d = Normalize[direction]; n = Normalize[normal]; x /. Graphics3D[gr_, opts___] :> Graphics3D[{If[darkShadow, Black], GeometricTransformation[ If[darkShadow, gr /. {Glow[_] -> Glow[], r_?(MemberQ[{RGBColor, Hue, CMYKColor, GrayLevel}, Head[#]] &) -> Black}, gr], Composition[TranslationTransform[direction], Quiet[RotationTransform[{d, n}], {RotationMatrix::degen, RotationTransform::spln}], ScalingTransform[10^-3, d], Quiet@Check[ScalingTransform[1./(n . d), n - (n . d) d], Identity]]]}, opts]] With[{a = ParametricPlot3D[{(2 + Cos[\[Phi]])* Cos[\[Theta]], (2 + Cos[\[Phi]]) *Sin[\[Theta]], Sin[\[Phi]]}, {\[Theta], 0, 2 \[Pi]}, {\[Phi], 0, 2 \[Pi]}, Mesh -> None, Axes -> False, Boxed -> False]}, Show[a, planarShadow[a, {0, -0.5, -2}, {0, 0, 1}, True], PlotRange -> All]] 

enter image description here

How to edit the above function to get a blurry shadow? or is there any other way to achieve this?

Thank you

$\endgroup$

2 Answers 2

4
$\begingroup$
torus = {(2 + Cos[v]) * Cos[u], (2 + Cos[v]) * Sin[u], Sin[v]}; plot = ParametricPlot3D[torus, {u, 0, 2 Pi}, {v, 0, 2 Pi}, Axes -> False, Boxed -> False, Mesh -> None, PlotPoints -> 64]; 

Using DropShadow by Michael Sollami

DropShadow = ResourceFunction["DropShadow"]; DropShadow[plot, "Blur" -> 20, "Color" -> Gray, "Opacity" -> .8, "Offset" -> {-50, 90}] 

enter image description here

$\endgroup$
2
  • $\begingroup$ Thank you @eldo. It looks simply amazing and it run on 13.0 $\endgroup$ Commented Jun 24, 2024 at 3:24
  • $\begingroup$ Thanks for the accept :) $\endgroup$ Commented Jun 24, 2024 at 7:56
8
$\begingroup$

I've tried adding multiple semi-transparent shadows at different angles:

planarShadow[x_,direction_,normal_,darkShadow_:True]:=Module[{d,n,o=0.1}, d=Normalize[direction]; n=Normalize[normal]; x/. Graphics3D[gr_,opts___]:>Graphics3D[{If[darkShadow,{Opacity[o],Black}],GeometricTransformation[If[darkShadow,gr/. {Glow[_]->Glow[],r_?(MemberQ[{RGBColor,Hue,CMYKColor,GrayLevel},Head[#]]&)->RGBColor[0,0,0,o]},gr],Composition[TranslationTransform[direction/.{f_,g_,_}:>{f,g,-2+RandomReal[{-0.1,0.1}]}],Quiet[RotationTransform[{d,n}],{RotationMatrix::degen,RotationTransform::spln}],ScalingTransform[10^-2,d],Quiet@Check[ScalingTransform[1/(n.d),n-(n.d) d],Identity]]]},opts]] a=ParametricPlot3D[{(2+Cos[\[Phi]])*Cos[\[Theta]],(2+Cos[\[Phi]])*Sin[\[Theta]],Sin[\[Phi]]},{\[Theta],0,2 \[Pi]},{\[Phi],0,2 \[Pi]},Mesh->None,Axes->False,Boxed->False,PlotPoints->60]; b=Show[a,planarShadow[a,{0,-0.5,-1}+0.6Append[#,0],{0,0,1},True]&/@CirclePoints[20],PlotRange->All]; Style[b,RenderingOptions->{"3DRenderingEngine"->#}]&/@{"Metal","OpenGL","Mesa","OpenGL","BSPTree"} 

Which gives some more-or-less nice results depending on your version of Mathematica, graphics card, and operating system:

enter image description here

Not very good yet, but maybe give ideas to others…

Another way of doing this, is by using ray tracing, but this is not available on all platforms I think. I can only test on Mac:

a=ParametricPlot3D[{(2+Cos[\[Phi]])*Cos[\[Theta]],(2+Cos[\[Phi]])*Sin[\[Theta]],Sin[\[Phi]]},{\[Theta],0,2 \[Pi]},{\[Phi],0,2 \[Pi]},Mesh->None,Axes->False,Boxed->False,PlotPoints->60]; Style[Graphics3D[{First[a],White,Polygon[6{{-1,-1,0},{-1,1,0},{1,1,0},{1,-1,0}}+Threaded[{0,0,-3}]]}, Lighting->{AmbientLight[RGBColor[0.2,0.2,0.2]],{"Area",RGBColor[0.65,0.65,0.65],{0,0,18},{{4,0,0},{0,4,0}}}}, Boxed->False, ViewPoint->{0.2,-2,1.6}, ViewVertical->{0, 0, 1}, Method->{"RayTracing"->{"ImageSamples"->150,"RayBounce"->2}} ], RenderingOptions->{"3DRenderingMethod"->"RayTracing"} ] 

resulting in:

enter image description here

Which looks like a golden donut… You can change the ambient light and the 'Area' light to get more contrast and so on…

Note that raytracing is an experimental, undocumented function since version 13.x (?). Support might drop any moment.

$\endgroup$
8
  • 1
    $\begingroup$ thank you. this is really a nice attempt. I just have one question, do I need to have internet access to use the 3DRenderingEngine options? because with my Mathematica-13.0 on a Ubuntu 22.4LTS, I'm unable to render the beautiful shadows that you've shared. All of my shadows are coming out to be the same. $\endgroup$ Commented Jun 6, 2024 at 12:44
  • 2
    $\begingroup$ @user444, please look at the third bullet point in the documentation for "3DRenderingOptions", explaining which methods are available for a given operating system. $\endgroup$ Commented Jun 6, 2024 at 13:03
  • 1
    $\begingroup$ I've added an alternate way of solving this by using ray-tracing. The shadow then gets a bit colored because the reflected light has the color of the surface. Moreover, the feature is experimental and undocumented… $\endgroup$ Commented Jun 7, 2024 at 14:26
  • 1
    $\begingroup$ @SHuisman, It is not working in ubuntu, mathematica 13.0 ... Do you have any suggestion? $\endgroup$ Commented Jun 8, 2024 at 4:34
  • 1
    $\begingroup$ @SHuisman the ray tracing method was very useful to me, this works great on my MacBook but unfortunately not on my Windows system. Any alternative option that would give a similar result for a Windows or Linux based system? $\endgroup$ Commented Jun 9, 2024 at 4:38

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.