I was implementing a TimeSystem into my game which internally increases a counter every 1/60 second. At the moment one in-game-hour has 3600 ticks, which is a minute in real-time. Therefore, the maximum tick count is 86400 (24 In-Game-Hours/In-GameDay * 3600 Ticks/In-Game-Hour). The count 0 means an in-game-time of 6 am. The TimeSystem notifies all listeners if the ticks changed, one of the listeners being the LightingState. This one calculates the new light direction like so:
float timeOfDay = FastMath.PI / (2f * 21600) * ticks;
float x = FastMath.cos(timeOfDay) * HORIZONTAL_AMPLITUDE;
float y = FastMath.sin(timeOfDay) * VERTICAL_AMPLITUDE;
float z = FastMath.sin(timeOfDay) * HORIZONTAL_AMPLITUDE;
direction.set(x, y, z);
The tick count of 21600 corresponds to 12 am (where sun is at the highest point). I am using a DirectionalLightShadowFilter for shadows, and it works fine if the directional light doesn´t change its direction. But when changing the direction with the above code I get weird shadows.
I have tried changin the shadow map resolution and using a DirectionalLightShadowRenderer instead of a Filter. Nothing worked, but I can´t see the problem. The light is changing like is supposed it (at least I can´t see any mistakes in the calculation, PLS correct me if I am wrong).
Though the way you calculate the lighting direction is going to create really strange arcs, I think… since they are all calculated independently. Would be better to use quaternion and multiply a fixed vector to get direction.
They could but not the way you have them. Presumably you want a straight arc overhead but tilted at some angle off of directly vertical. In that case, you’d have to first calculate the regular arc:
x = cos(angle)
y = sin(angle)
z = 0
…and then rotate that position again north/south… which is more complicated than I want to write here since I’d just use a quaternion for it.
Keep an angle for time of day and an angle for “planet tilt” or “season” or whatever. Assuming you want the sun to rise and set in +x/-x then I think you can even do it with one fromAngles() call.
timeAngle = 0 to 2 * PI = midnight to midnight.
seasonAngle = -QUARTER_PI to +QUARTERPI = winter to summer or summer to winter… not sure.
rot = new Quaternion().fromAngles(seasonAngle, 0, timeAngle);
dir = rot.mult(Vector3f.UNIT_X);
it fades the shades to invisible, and increases the resolution in the now smaller range / together with limit)
I found 50-100meter for larger ground terrains to be a nice value. this makes the shadows vanish slowly enough to not be that noticeable, but still saves quite a lot of distance and inaccuracy, especially for larger frustrums.