Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Directional Lightmaps + Realtime Shadows and light probes.

Discussion in 'Editor & General Support' started by CorruptScanline, Jun 19, 2012.

  1. CorruptScanline


    Mar 26, 2009
    This thread is a rant about the current Directional Lightmap implementation when combined with dynamic shadow casting objects, and suggestions on how to fix it.

    The Problem:
    Directional Lightmaps use 100% baked lighting while preserving the light normal for shading purposes. This is great, but the current implementation has some major problems/bugs when combined with dynamic non-lightmapped objects and light probes.

    One of the problems is that the results are very different between deferred and forward mode.
    Forward: You get dynamic shadows cast onto the static objects, but there still some problems.
    Deferred: No dynamic shadows from static lights at all.

    The problem with forward mode dynamic shadows is that the shadows continue to cast through static geometry which results in shadows being cast where they shouldnt be. For example if a directional light and a player is running on a roof, then you could see the shadow casting on the floor inside the building, especially if you have other interior lighting inside that building. On top of that, static (Auto) point lights dont seem to cast shadows from from dynamic objects, even if their shader has fullforwardshadows. Also RealtimeOnly point lights will only cast shadows from dynamic objects, not static objects.

    Switching to Deferred mode results in no dynamic shadows on static surfaces at all. You can use exclude_path : prepass in a shader to get shadows on static surfaces, but this results in another big problem, those static surfaces also now cast realtime shadows.

    LightProbes: When enabling light probes on a renderer it disables direct lighting on the object. I think the idea is that light probes get direct lighting baked into them? This is only ideal for something like a low end mobile game where you dont want any realtime lighting. In most situations you only want indirect light baked into the probes and apply standard realtime lighting onto the object. This should be an option (and default). Light probe rendering is also not very good, because its applied at a vertex level. This can be overcome of course by creating custom shaders with custom lighting models, but it should really default to applying them on a pixel level, except on mobile devices.

    The Solution:
    Make deferred mode have the same results as forward mode, with the exception of point light shadows and stuff of course.
    Add a system for masking dynamic-to-static shadow casting. One way I can think of to do this would be to render shadow map depth buffers for all of the "Auto" lights at lightmap build time. Only include static objects in this depth map. Store those textures with the lights. Use this stored texture when rendering the screenspace shadows from dynamic objects. This would be done basically by doing the same thing as the dynamic shadow map calculation: Project the texture from light camera space (you already have this uv calculated from when projecting the dynamic shadow map). Compare the surface depth against the projected baked depth. If surfaceDepth < projectedBakedDepth-bias projectedDynamicDepth < projectedBakedDepth you apply the shadow like normal, otherwise you dont apply the shadow because the surface is already in shadow from a static object. Of course for directional lights you couldnt bake a shadow map at bake time, the static depth map would have to be rendered at runtime.

    Make this optional per light, and probably off by default, because many cases its not needed, but in some cases, especially for directional lights it is needed.

    Light Probes: Add an option to have only indirect light baked into light probes and dont disable real time lighting on the object if this option is chosen.
    Last edited: Jun 19, 2012
    Pawl likes this.
  2. artician


    Nov 27, 2009
    I appreciate this post, it saved me a lot of time, thank you!
  3. Marble


    Aug 29, 2005
    I bumped into this problem today. I'd just like to corroborate that as of 4.1.5 this is still how things are. I'd love to get realtime shadows working on lightmapped surfaces in deferred rendering.
    Last edited: Jul 9, 2013
  4. bigzer


    May 31, 2011
    Having a similar issue here. I try to have a lightmapped environement with dynamic objects with real time shadows all in deferred rendering.
    In my case the problem is that both shadows can't have the same intensity without messing the light up.

    I'm not sure if this is possible technically but if we could have real time shadow intensity higher than 1 it would fix the issue as we could cheat and add the value of the baked light into account. So if bake light intensity is 0.8 and real time light intensity is 0.4 , we would put the shadow strenght of the real time light to 1.2 to obtain real time shadow as strong as the baked ones.
    Last edited: Aug 6, 2013
  5. MajorNightmare


    Nov 27, 2012
    I was having a similar issue getting real-time with baked, to match shadow intensity. To solve it, I put all the static objects on 1 layer, and the real-time object on another, make 1 directional light set to "bake only" on the static layer, then tell a second directional light (just a dupe of the first), to light only the real time object(s), like the player. No point in given the baked layer anymore light or... shadow, only the real time. Separate the 2 clearly, RT and Baked, you'll get better results. My example is simple, just a player getting real time, the rest baked. I was able to match the shadow intensity after that. Now I can get on with my Marmoset Skyshop IBL baking(They make such Purdy textures) versus regular bake testing... PS. Test bake without probes or AO for that matter, it's much faster to bake without them while you are testing for the right light and shadows values.
    Hope it helps someone. Cheers
    Last edited: Sep 18, 2013