There have been a steadily growing list of shadow issues since KSP moved to Unity 5. This list now included (but was not limited to) shadow issues with Trees, KSC buildings, Green lines over water and Sun shadows flickering in flight.
Looking at them one by one, each of these issues appeared to have different root causes.
So let’s look at them one by one.
As soon as I started looking at the tree issue it was quickly apparent this was a shader issue given it only affected one particular tree model and its vertex shapes.
Where do we start?
Digging into the shader being used by our tree that is causing us issues I quickly found that the alpha cutoffs and fallback shader are just not quite right because of changes Unity made in Unity 5.
A few adjustments later to the shader and we have our result.
KSP's Camera System
KSP uses a two Main camera system for the main game view. Of course there are a number of other cameras for displaying UI, Graphic FX, etc.
But these two are the ones that show you the game world. Let’s look at a picture so I can describe it.
There are two cameras located where the camera icon is in the top left of the picture.
This is their location in the game world.
They are both looking in the same direction and are linked to the same camera transform.
The first camera, or Camera00, is known as the Near Camera. It is set to show only the first few hundred meters of the game world and it’s view of the world ends at it’s Near Camera Far clipping pane, as seen in the picture.
The second camera, or Camera01, is known as the Far Camera. It is set to show the game world where the Near camera ends out to a very very long distance away.
There have been long standing issues with this system including shader issues where the two cameras overlap, or where the Near Camera’s Far Clipping Pane ends and the Far Camera’s Near Clipping Pane starts. This has been particularly visible as a green line over water.
The primary reason for why these two cameras overlap is to provide a seamless view of the game world. So changing the camera settings we can reduce the overlap to the very minimum and we see that the green line that used to be visible over water has now vanished.
The KSC buildings had also been suffering from this same two camera system since Unity had introduced changes to the way it draws shadows.
In Unity's built in shadow shaders is an automatic fade out of shadows as you approach the far clipping plane (the furtherest the camera can see).
This is why we had things like this
where the shadow would fade away, get cut, or not appear around the area of where the closest game camera far clipping plane ended.
This problem has been known about for some time.
Here is a link to an article written by Harvester asking for help about the problem. Here also, is a picture by Harvester describing the problem (from the article).
So how do we fix this? Well luckily as a developer I am able to get access to the Unity built in shaders and create a modified version that does not have this fade out feature. So I take the Unity built in shader used for the building shadows and change its code to remove the fade out processing.
Once I have the shader fixed to not fade the shadows I also need to write a script (code) that will replace the built-in Unity shadow shader with our modified one.
Finally I add this script to the KSP cameras and we get a much better result.
But we weren't quite done with the building shadows. Another known issue in Unity 5 is the way sharp edges in object geometry cause gaps in shadows to appear.
Luckily this is much easier to resolve by changing the settings of the geometry on our building objects to use two-sided shading.
The Sun and Flight Scene.
Everyone has probably noticed the flickering/sliding shadow effects that have plagued the game in flight mode since the move to Unity 5.
Without a doubt the trickiest problem of the bunch and hardest to resolve. There is a combination of factors at play here. First is a known issue with the way Unity draws shadows with directional lights and the second issue, that only tends to exacerbate the problem, is floating point precision issues calculating very large numbers which represent the very large distances (even at the scale the Kerbin system is in).
The SunLight we see in the game is generated by a Unity Directional Light. This light is rotated over time based on the position of the celestial bodies.
The position and rotation is calculated every tick of the clock and the light itself is rotated based on the body positions.
Due to floating point imprecision this means the calculations between the bodies can vary even the smallest amount between clock ticks and this is exacerbated further by a known
bug in Unity with regard to shadows drawn by directional lights.
By reducing the precision of the calculations between the celestial bodies we can reduce these tiny variations so we have a solid number that gradually changes over time.
The downside of reducing the precision is that the rotation of the sun is less smooth, so we end up with a sun that tends to move in small steps rather than one fluid motion across the sky.
But the plus side is we reduce the difference between clock ticks and we don't get light shadows flickering all over the place.
This work-around solution, whilst not ideal, is the best compromise to alleviate the issue working within the known limitations and Unity issues that we have.
These known issues with Unity 5.4 directional lights and shadows have been fixed and much improved in Unity 5.6. Along with improved shaders, effects and other enhancements that come with Unity 5.6.
Edited by JPLRepo