Force terrain shadow (from 3d object) regardless of time of day

301 views
Skip to first unread message

niklas...@enplore.com

unread,
Nov 29, 2018, 5:16:01 AM11/29/18
to cesium-dev
1. A concise explanation of the problem you're experiencing.

I have a case where I always want to cast a shadow from a 3d model, regardless of time of day. I've searched quite extensively (and probably spent about 4-5 hours trying to debug/find a workaround. The closest I've come is https://groups.google.com/forum/#!topic/cesium-dev/q5G3jBLqtJQ suggesting to hack the Cesium JS source code, but that is from 2016 and the source code has changed significantly since.

I've tried:
- All shadow configurations I could think of
- Setting the camera in any way I could think of

Unfortunately I rely on the date and time for the timeline, so I can't hard code the time to when the sun is up at that point.

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

Specifically, I want this to cast a shadow:
https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=bVPbbtswDP0VIXuwCySyHaNd5qbB0jQPLboLlmADBgODYjGJUFkyJNlZVvTfR1/irRfBDxQPeXh4bFfMkErAAQy5IgoOZAFWlDn93uR8L2uuC60cEwqMNySPqSJ4hNrqa/07IVsmLQzbpAUJmRNa3SouMua0eYHvGdcHmxBnylPOgTHIvTpBnYD2/klzoMvP8+v75U3PoUvJ50rkzMFbTF+NrgQH01NlBrD0hzaSr9sS/yxVT2eXqUpVhQa0S85F7UFrBgXlhBNgKePc71ZWLAeSEK+lJVjvdZP3IHZ7h9g4pGGXy1G6xFTXXJ/SiLqf0qB/5kVhgxXLCwk3zLGg6bLB4qSoi35hSHdy47VkT8/kN1qPqL3fo4HaNC20FfUrQbzzY8GMw4ipmG6Nzr8xjrH1IzqJzsN4SHCHcXx+MYzDekZnSCZ19kCz0hjkXQt0oue7KyUSoHxo+G6tnlyEke+Nw2gyiqLROFxH75M4TsYffnqvKPNSOlFI0XyBEQ3/4c6w7AH48q31BsPB1LqjhFnryEeRF9o4tFj6aKsDdBQF2WBTIoejmbX15Lr0ndNabtA32hKONqVz6M8j4cJi1zEhm1rZZW3zNDhNmXJREcGv0sGLfyIdkEwyaxHZllKuxB9IB7NpgPXP2qRGo9XuSwUGh9Ql+2h23yYppdMAr6+7OrH/Mf4F

<code>
var viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
selectionIndicator: false,
shadows: true,
terrainShadows: Cesium.ShadowMode.ENABLED,
shouldAnimate: true,
terrainProvider: Cesium.createWorldTerrain()
});

var cesiumAir = viewer.entities.add({
name : 'Cesium Air',
height : 20.0,
model : {
uri : '../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb'
}
});

var entity = cesiumAir;

entity.position = Cesium.Cartesian3.fromRadians(1.81503, 0.02356,30);
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601('2018-11-20T17:33:29Z');
viewer.clock.multiplier = 1.0;
viewer.trackedEntity = cesiumAir;
</code>


3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

Shadow is a good way of intuitively indicating how far away an object is from the ground (and at what point in time the object touches the ground). My backup solution is to change color of the model or something like that, but it's quite an ugly hack :)

Unfortunately I rely on the date and time for the timeline, so I can't hard code the time to when the sun is up at that point.

Any help would be greatly appreciated. Thank you so much for Cesium!


4. The Cesium version you're using, your operating system and browser.

Latest Cesium, Latest Chrome, OS X.

Omar Shehata

unread,
Dec 3, 2018, 12:09:30 PM12/3/18
to cesium-dev
Here is a 2018 version of the hacky solution:

  1. Go to Source/Renderer/UniformState.js
  2. Find the setSunAndMoonDirections function.
  3. Print out the sun direction by putting a `console.log(uniformState._sunDirectionWC);` in there. Run your app, put the sun where you want it, then check the console to see what the vector is, copy it. 
  4. Hardcode that position in, so instead of:
var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(frameState.time, uniformState._sunPositionWC);
Matrix3.multiplyByVector(transformMatrix, position, position);

Cartesian3.normalize(position, uniformState._sunDirectionWC);

My hack looks like:

var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(frameState.time, uniformState._sunPositionWC);
//Matrix3.multiplyByVector(transformMatrix, position, position);

position = new Cartesian3(0.31181546034703517, 0.8715375694318716, -0.3784090164852737);
Cartesian3.normalize(position, uniformState._sunDirectionWC);

And that should fix the sun position for everything while still letting you use the timeline.

If you need multiple models to have different sun positions, it's possible, but it'll be slightly more involved. I think you'd have to insert a check before rendering the object to see if it should have a "custom sun position". 

I hope this helps!

Niklas B

unread,
Dec 4, 2018, 3:12:18 AM12/4/18
to cesiu...@googlegroups.com
Thank you Omar! This is a great learning experience for me :)

--
You received this message because you are subscribed to a topic in the Google Groups "cesium-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cesium-dev/D1aOT3kVPpM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cesium-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages