Jump to content
  • Enter the Shadows.....


    JPLRepo

    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.

     

    Trees

    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?

    vGQyt5t5z4ubNIL_Lfs4zCTndoBdu3maS3f9rCjTx3MLrG46bIoQQRw2Z46csMP6TScUOA-h4H84r86J

     

    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.

     

    oDrCjyNNxNySNsx5XDGTzfynDAoggxXNBzx5zSND

     

     

    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.

    W4aeXLPijpzog0JDgQlhzXZbVBDlv5cmgmOKMRHJ

     

    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.

     

    YTzwBdnxeZYaQoMQB1PBM37gkPHXtSBoPuRxC6iQ

    2p2XEVk1xhzZe-_KyX8sxpZidl2wi2t2ZThdmWH2


     

    KSC Buildings

    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

    MX6l3pycmAErHQsQkR4RvbTu6H8VrNJ5d0UG0d4o

    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).


    UJWlWzkWvZXpYAkz6vmr77dznekaVeIoRky-5yfX

     

    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.


    M_1Q11YahA-SXkgPwetN0pzfiVnKTfFaTXYhspHn

     

    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.


    apVsIWwMXA5RCS2b69DVph3HkP09qfyIKqGGvbuz
     

     

    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


    User Feedback

    Recommended Comments



    Oh wow! This looks like some awesome work improving things. Kinda disappointed about the "ticking sun" but it explains why that is used in many games with day night cycles I guess. Interesting.

    Link to comment
    Share on other sites

    Why can't you use omni light for Sun? With 64-bit version, you should be able to put it at the proper distance, right?

    Dynamic lights (suit lamps, part lights) - why don't they cast shadows?

    Edited by J.Random
    Link to comment
    Share on other sites

    On 6/19/2017 at 8:50 PM, Manwith Noname said:

    Oh wow! This looks like some awesome work improving things. Kinda disappointed about the "ticking sun" but it explains why that is used in many games with day night cycles I guess. Interesting.

    The ticking sun is fixed for the upcoming patch release.

    Link to comment
    Share on other sites

    On 6/20/2017 at 10:01 AM, J.Random said:

    Why can't you use omni light for Sun? With 64-bit version, you should be able to put it at the proper distance, right?

    Dynamic lights (suit lamps, part lights) - why don't they cast shadows?

    I'm not sure what you mean by omni? but KSP uses a directional light as the article mentions for the Sun.
    Here are the types of lights available in Unity https://docs.unity3d.com/Manual/Lighting.html
    64-bit? has nothing but everything to do with floating point precision here when we are talking about the numbers in KSP.
    The bottom line is that a32-bit float has a maximum of 6 significant digits of accuracy, and a 64-bit double has a maximum of 15. Both are nowhere near enough when dealing with very large numbers such as Solar scale (or even Kerbin scale), let alone inter-stellar scale.
    The point is there is not a lot you can do about floating point precision. Unless you use doubles, but even those have limitations and trade-offs.
    As for dynamic lights - I assume your question is why doesn't KSP cast shadows with the Kerbal's lights and the part's lights? This is simply a performance design decision.

    Link to comment
    Share on other sites

    10 hours ago, JPLRepo said:

    I'm not sure what you mean by omni? but KSP uses a directional light as the article mentions for the Sun.
    Here are the types of lights available in Unity https://docs.unity3d.com/Manual/Lighting.html

    @J.Random is wondering why point lights aren't used for the sun, as the sun more closely resembles a point light source than a directional one. The confusion is that KSP uses both point light sources and directional sources to represent the sun, whereas only the directional light was affected by the issue being fixed.

    @J.Random : My understanding is that point light sources are used for the sun for planets in scaled space (i.e. when you are far enough away to see that they're round), but when you're on or near the surface in the flight scene, a directional light source lights the terrain and vessel, as it's more accurate in that scenario. You often have both lights at once: Sitting on the launchpad on Kerbin, the launchpad and rocket are lit using a directional light, and the Mun is lit by a point light. @JPLRepo is this reasonably accurate?

    Edit: Just reading the Unity light types, would an area or emissive light be more accurate in low sun orbit? Craft there shouldn't have strong shadows as the sunlight is coming from nearly prograde through 180° to retrograde.

    Edited by pizzaoverhead
    Link to comment
    Share on other sites

    5 hours ago, pizzaoverhead said:

    @J.Random is wondering why point lights aren't used for the sun, as the sun more closely resembles a point light source than a directional one. The confusion is that KSP uses both point light sources and directional sources to represent the sun, whereas only the directional light was affected by the issue being fixed.

    @J.Random : My understanding is that point light sources are used for the sun for planets in scaled space (i.e. when you are far enough away to see that they're round), but when you're on or near the surface in the flight scene, a directional light source lights the terrain and vessel, as it's more accurate in that scenario. You often have both lights at once: Sitting on the launchpad on Kerbin, the launchpad and rocket are lit using a directional light, and the Mun is lit by a point light. @JPLRepo is this reasonably accurate?

    Edit: Just reading the Unity light types, would an area or emissive light be more accurate in low sun orbit? Craft there shouldn't have strong shadows as the sunlight is coming from nearly prograde through 180° to retrograde.

    No that's what I was saying. I didn't understand the reference to omni lights because the Sun is a directional light. To clarify, there are no other lights representing the sun. Point lights are not used in scaled space to light planets. Point lights are not used to light the Mun at the launchpad. There is a spotlight... sitting on top of the level 3 launchpad tower. pointing at the launchpad.

    Link to comment
    Share on other sites

    I don't get it.

    I mean, I understand that the Sun is a directional light. It's well known because of how planets look with telescope mods. By "omni" I meant, of course, point light. Why use directional light instead of a point light? I mentioned 64-bit because I thought the reason was that you couldn't put light source far enough away in the scene.

    @pizzaoverhead Tha's what I was thinking too, and now I'm wondering what the hell lits up the Mun. The same directional light, I guess.

     

    As for the dynamic lights - can you make it optional? KSP isn't very taxing GPU-wise, and I'd expect a modern videocard to easily manage a couple (of dozens :D) additional light sources in the scene.

    Link to comment
    Share on other sites

    On 6/22/2017 at 7:11 AM, J.Random said:

    I don't get it.

    I mean, I understand that the Sun is a directional light. It's well known because of how planets look with telescope mods. By "omni" I meant, of course, point light. Why use directional light instead of a point light? I mentioned 64-bit because I thought the reason was that you couldn't put light source far enough away in the scene.

    @pizzaoverhead Tha's what I was thinking too, and now I'm wondering what the hell lits up the Mun. The same directional light, I guess.

     

    As for the dynamic lights - can you make it optional? KSP isn't very taxing GPU-wise, and I'd expect a modern videocard to easily manage a couple (of dozens :D) additional light sources in the scene.

    The light source is not far away. It is actually at 0,0,0. But the calculations to calculate the rotation based on the celestial bodies is based on where they actually are.
    Because a single directional light has better performance that point lights. And you have to consider the rendering paths forward vs deferred and all the pros vs cons of each.
    Dynamic multiple lighting support is not currently planned.

    Link to comment
    Share on other sites

    On 6/25/2017 at 2:21 AM, JPLRepo said:

    And you have to consider the rendering paths forward vs deferred and all the pros vs cons of each.

    I have no idea about either of them, which is why I'm asking stupid questions. =)

    On 6/25/2017 at 2:21 AM, JPLRepo said:

    Dynamic multiple lighting support is not currently planned.

    Oh, well. Thanks anyway.

    Link to comment
    Share on other sites

    This shadow issue is like in Quake Army Knife or Quark editor for Quake 2. If the light is not configured propely in the editor.

    Link to comment
    Share on other sites

    I hope you can fine tune these solutions.

    Remember, you can always use lookup tables to improve calculation policies.  Also remember, some platforms, like Linux Mesa, use the lower precision numbers permitted by the standard unless you explicitly state otherwise.  Setting the precision to be high explicitly will drastically increase the quality in these cases where the precision is actually needed.    (I generally think it's good practice to explicitly set precision in most cases, but other coders disagree with me.  There are reasons for either choice, and I'm old school, which eliminates the most common choice of trusting the compiler. :cool:)

    Link to comment
    Share on other sites



×
×
  • Create New...