run time light baking

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.

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.

which platform you are targeting?
if the mobile you could try to use planar shadows in the trees and buildings (GitHub - ozlael/PlannarShadowForUnity: Planar Shadow is very cheap and useful for mobile games.)

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.

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.

You can render your real-time shadows into a lightmap instead of the screen.

o.vertex = mul(UNITY_MATRIX_P, float4(v.uv1.xy * _LightmapScaleOffset.xy + _LightmapScaleOffset.zw, 0, 1));

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:

Graphics.SetRenderTarget(lightmapTexture);
gBufferMat.SetVector("_LightmapScaleOffset", renderer.lightmapScaleOffset);
Graphics.DrawMeshNow(mesh, renderer.transform.localToWorldMatrix);

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.

2 Likes