Yes it's realtime... you can change the light direction on the fly (last line of code above).

It works like this: to produce shadows, all the objects that must receive and cast shadows in your coin scene must be placed inside a SoShadowGroup, and there must be one ShadowDirectionalLight in that same SoShadowGroup (there re other types of shadow-casting lights available too). You can also add a SoShadowStyle inside, which allows to turn shadows on/off:

That's basically what the OfflineRenderingUtils.embedLight does: You give it a coin node/graph, and it embeds it inside a SoShadowGroup.

Only, the FreeCAD viewport doesn't have tools to replace the scenegraph. This would probably cause some problems too, as some tools likely wouldn't find their children anymore. But it would be cool to allow to add a SoShadowGroup to the main view. Need to look at how to do that correctly..

So what the above script does is 1) create a blank viewer (which has no connection with FreeCAD tools and view providers), 2) build a coin scenegraph from the visible objects (so far I couldn't make it work to simply copy the main scenegraph, not sure why) 3) embed that scenegraph in a SoShadowGroup, 4) set the viewr's scenegraph with that scenegraph.

Only, the FreeCAD viewport doesn't have tools to replace the scenegraph. This would probably cause some problems too, as some tools likely wouldn't find their children anymore. But it would be cool to allow to add a SoShadowGroup to the main view. Need to look at how to do that correctly..

This actually shouldn't cause problems because view providers usually search underneath their root separator. And if any function needs to search for nodes of other objects (like the body feature) it shouldn't assume any fix order of how the nodes are organized but is supposed to use an SoSearchAction.

Btw the clipping plane or axis cross functions also change the graph structure at runtime and I have never seen a problem.