Search Unity

run time light baking

Discussion in 'General Graphics' started by Ne0mega, Jan 22, 2020.

  1. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    i am making procedurally generated terrain, and it just kills me i cant bake the shadows of all the static objects under a static directional light. Maybe I can, and just do not know how? I am imagining a call to the API and maybe 20 more seconds of load time for the player while the initial map is generated.
     
  2. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    So I am thinking of a workaround.
    Since the parameters of the directional light will be static, as I intend to keep it fixed, I can know out exactly what every shadow is going to look like. They will be static, therefore the light can be baked.

    I could conceivably set all static objects on the map to shadow only, take an orthographic snapshot, call it from the texture renderer, then apply it as the texture2D to my terrain through shadergraph, then change the static object's lighting to cast no shadows.

    Edit: nope. I forgot, not entirely static. Trees can be chopped, and buildings built. So I would have to redo the snapshot every time a tree was removed or a building built. This would not be often, but it might cause a bit of a hiccup.
     
    Last edited: Jan 23, 2020
  3. Lockthav

    Lockthav

    Joined:
    Dec 6, 2018
    Posts:
    6
  4. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    Thanks, but this solution only works on flat planes, I was considering such a solution, perhaps I could use my heightmap to move the shadow projection plane.. Or I could maybe even use my generated heightmap to generate the shape of the shadow casting planes per tree and building, so it appear to lie flat on the terrain.

    I am targeting desktop. Also, planar shadows use stencils, which mobile can do, but is very expensive.
     
  5. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,493
    You can probably use a custom render texture and create your own shader that update only once, or when there is change.

    I'm trying to make a full GI system loosely based on that idea but with a full Gbuffer in lightmap space. Well as soon as my hardware is fixed.
     
  6. Shane_Michael

    Shane_Michael

    Joined:
    Jul 8, 2013
    Posts:
    158
    You can render your real-time shadows into a lightmap instead of the screen.

    Code (csharp):
    1.  
    2. o.vertex = mul(UNITY_MATRIX_P, float4(v.uv1.xy * _LightmapScaleOffset.xy + _LightmapScaleOffset.zw, 0, 1));
    3.  
    That will render each vertex at its position in the lightmap. Should be a simple substitution into any shader; you can make a small custom shader that only calculates shadows. Rendering looks something like this:

    Code (csharp):
    1.  
    2. Graphics.SetRenderTarget(lightmapTexture);
    3. gBufferMat.SetVector("_LightmapScaleOffset", renderer.lightmapScaleOffset);
    4. Graphics.DrawMeshNow(mesh, renderer.transform.localToWorldMatrix);
    5.  
    Render out the mesh for each renderer using its transform and lightmap offset. If you want to bake out shadows, you will need to render out your shadowcasters first into a shadow depth texture so you can sample it for your shadow calculation.

    Bounced lighting for GI takes time to bake, but shadows alone is nothing so it shouldn't take more than a few milliseconds.
     
    Ne0mega and neoshaman like this.