Search Unity

How can I bake shadows in a scene that appear when I turn off the light in game?

Discussion in 'Global Illumination' started by drugges, Oct 8, 2019.

  1. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    Hi, I am trying to figure out how to setup my lighting to achieve a certain effect. I have a 3rd person game where the user can enter different areas. Some areas are underground and I want the area to be totally black (no lighting) except for a radius around the player. The lighting itself works. I just set the Environment Lighting to black and only have a Spot light that follows the players. BUT, I also want to pre-bake some fake shadows into the scene to give it more life, using a Directional light. I know the shadows won't be correct in game since the shadows won't match the spot light, but that is fine.

    This is current setup:
    I have Environment Lightning set to black. Baked global illumination ON. Lighting mode shadowmask. I have a (mixed) Directional Light that I only use when baking the scene. I bake the scene and get all the shadows in the editor like I want. When the game starts I deactive the directional light. This turns the scene black, light I want. I then have a (real time, no shadow caster) spot light that follows the player around and illuminates the area around him as a torch.

    But the problem is: when I turn off my directional light, the shadows that was baked from it dissapears in the scene as well! Is there a way to turn off the light, but keeping the shadows it contributed with in the baked shadow map?

    This is how it looks in the editor after baking:
    upload_2019-10-8_10-46-29.png
    I have shadows baked like I want to.

    But this is how it looks in game after I have turned off the directional light that created the baked shadow:
    upload_2019-10-8_10-47-43.png

    If I turn on the directional light again in the game, the shadows appear (although brighter due to the spot):
    upload_2019-10-8_10-48-22.png
    But when I turn on the directional light the whole area gets visible for the player which I don't want to.

    Does anyone know how I can achieve this effect? A "torch lit area, with pre baked shadows".

    Thanks!
     
  2. kristijonas_unity

    kristijonas_unity

    Unity Technologies

    Joined:
    Feb 8, 2018
    Posts:
    1,080
    The behavior you are seeing is intended. However, for you particular case, you could try using a fully baked directional light + baked indirect lighting mode.
     
  3. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    Thanks for the answer. But if I use baked indirect lighting mode, my shadows won't get baked, right? From what I understand, indirect lighting mode will only bake indirect shadows/colors and not the shadows. Is that correct?

    I understand that the behaviour is intended. It makes sense and is probably what you normally want. I just wanted to come up with a solution that didn't use any real time shadows. But if it isn't possible out of the box, I might go with indirect baking on the directional light like you say, and use real time shadows on the spot light.
     
  4. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    Adding to this again. I tested with indirect baking mode but it still gives me the problem that I cannot make the scene go dark when I turn off the directional light.

    This is the effect I want. When I turn off the directional light and only use the spot, I get this torch like feeling:
    upload_2019-10-9_11-28-59.png

    But when I use the directional light as fully baked and bake the scene, the light values get baked and I cannot get the scene to turn fully dark. This is how it looks when I have turned off the directional light after baking and using the spot:
    upload_2019-10-9_11-30-21.png
     
  5. kristijonas_unity

    kristijonas_unity

    Unity Technologies

    Joined:
    Feb 8, 2018
    Posts:
    1,080
    I see what you are trying to achieve, but I don't think that using directional light is the best approach. Players will quickly notice that the baked shadow from the directional light does not move when you go about baked objects with your character. If you want to simulate a torch-like effect, you'd have to use realtime shadows.

    What I'd recommend in your use case is to have some baked omni-directional occlusion into your scene, that will help ground the objects. You could use a neutral/overcast HDRI for that. Then, if you'd still feel that your scene is too bright, you can use post processing to tone it down.
     
  6. uy3d

    uy3d

    Unity Technologies

    Joined:
    Aug 16, 2016
    Posts:
    187
    Another thing you could try is baking the directional light as a mixed light in shadowmask mode (maybe with a really low multiplier), then at runtime copy the directional light's bakingOutput (https://docs.unity3d.com/ScriptReference/Light-bakingOutput.html) to the realtime light, essentially hijacking the lightmap. This way you could force the runtime to sample the "wrong" lightmap data for the spot light. Doing this may have other undesired side effects, though.
     
  7. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    Thanks for help everyone.

    Kristjonas, I totally agree with you that the players will see that the shadows don't move. But this solution is intended for mobile devices with low quality settings. I will also use a real time lightning mode for higher quality settings.
    I did some tests with just baking ambient occlusions from a skybox (no light sources in the scene, just a skybox, baked indirect mode). It really does help to "ground" the items. But I still cannot make the scene go completely black when I do it like that. I was hoping I would be able to change the scene environment lightning after the baking, but that wasn't the case. I guess I need to use post processing like you say if I want to continue down this path. I could probably just write a shader that returns black pixels if they are too far away from the player.

    uy3d, this sounds really interesting. This could be exactly what I am trying to do. I will test this as well and see how it goes. If I am "lucky", the spot will work as a mask for the directional light's baked data.
     
  8. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    I just had to test uy3d's advice right away :)

    This was fun. This is what I did:
    I baked the directional light as mixed, shadow mask. At runtime I just gave the torch the bakingOutput from the directional light. And this was the result:
    upload_2019-10-9_14-36-22.png
    I know it looks terrible, the shadow is no way near realistic. But this is really something I can work with. I am thinking of combining this trick with Kristjonas advice. So I will try and bake the ambient occlusion with a really nice skybox and then hijack that lightmap and give it to the spot! In that way I can get baked AO using a realtime spot light.

    This was really good help from the two of you. Thank you very much.
     
    kristijonas_unity and neoshaman like this.
  9. drugges

    drugges

    Joined:
    Dec 28, 2018
    Posts:
    42
    This was a bit harder than I hoped. I have been struggling with a way to access LightBakingOutput from the baked environment lighting. Maybe this is not even possible. But I was hoping I would be able to access the baking data from the environment lighting just as easy as I could access it on a regular light.

    For regular light I can just access it like this:
    Code (CSharp):
    1. directionalLight.bakingOutput;
    I can then use that information on my spot:
    Code (CSharp):
    1. torchLight.bakingOutput = directionalLight.bakingOutput;
    Does anyone know if it is possible to get access to the baked information for the global illumination as well?