Creating static shadow-maps at runtime. Possible?

Many objects in my game are static, and so their shadows casting doesnt need to update every frame.
However, my game is procedurally generated, so i cant prebake lighting - shadow maps would need to be made at runtime.
Does anyone have any ideas how/if this could be done in ue4?

1 Like

Shadow map compilation takes forever – you really don’t want to do this.
Modern games use dynamic lighting/shadowing, and even ray tracing – what’s the reason you can’t do this?
Add distance fields to your proecedural items and it’ll probably work well!

If anything…
OP needs to consider the fact that the performance gain you get from “static” light baking is only there because of the compilation time that producing it takes out of the final equation.

If the goal is to have a dynamic environment and reduce the performance cost, the answer can’t be “bake lighting” because that performance cost will still have to exist one way (distributed across all frames - dynamic) or another (precomputed at level load).

The process doesn’t have to take “forever” btw. A low cost “on load” adaptation could be made taking around 2m to load a level up.
So you really want your players to wait 2 minutes to load in though?

for procedurally generated levels (generated at the level’s loading time) I don’t see much against having static light baking as an option (which would also happen at that same loading time). it would be a tradeoff of longer loading times to get more runtime performance.

While CPU Lightmass is slow, nowadays GPU Lightmass would be an option (you’d need a raytracing GPU in the game’s system requirements though). back when they announced GPU Lightmass I asked if it would be possible to do baking at runtime but sadly I never got an answer.

I suspect it’s not entirely trivial to implement with all the texture resource assignment and shader upates. It depends how the system was designed, but if the editor can do it seamlessly I don’t think it’s all impossible that they could extend it to happen at runtime

The editor uses its own process for it though.
In a game that you are selling you can’t usually expect your users to have multiple things running at the same time.
Also, I don’t think you can actually package and release swarm as it may be proprietary to epic?

In engine you would basically be doing this with render targets.

You calculate how many you need by splitting up and assigning world driven UV space to each object’s lightmap. You produce each render target of 8k as an atlas. You write the computed shadow to it.
It’s a nightmare just thinking about it XD

And, if you don’t want to have to write functions into all materials to use the RT you also will need to create your own usf or shader file to inject the atlas shadow in… though maybe you can just hook into the existing system for that :thinking:

well swarm is as proprietary to epic as the entire engine. they’re free to include any editor accessories into the runtime as they see fit, it’s their engine after all :smiley:

a mustered solution such as using RTs is indeed a nightmare just to think about it.
also with RTs there would be no texture streaming, they’d all be in memory permanently, and without any texture compression. different lightmaps would mean different material parameters, breaking all instancing entirely.
unless the game is composed of small levels it’s easily gonna eat all the VRAM. it’s a memory problem and not a processing power problem but at that point it’s probably better for performance to just use dynamic lighting

for this to work in a serious manner it needs to be done on the engine side. it would need to save the resulting textures into disk (temporarily, with that game session) so they can be streamed in and out. and it needs to hook into the existing static lighting pipeline.
anything less than that means reinventing the wheel, redoing almost the entire static lighting system, at which point it’s surely not worth the effort

1 Like

I think you guys missed my point. What I would like, is simply to have a direction light which does not update it’s depth-map every tick for all objects.

The shadows from the directional light are going to change based on your camera location and everything, so it’s something that does still need to update every tick

I have had some success creating my own custom depth map with a rt+scenecapture. I used that depth map to create shadows in the directional light’s material function.

However, My shadows arent nice and smooth like unreals. they are blocky. My Shadows:


UE4 shadows:

Does anyone know what the maths is to make ue4’s nice soft edged shadows?

Currently mine looks like this:

This thread may help you: How to blur a custom shadow map?. I haven’t done any of this, I just remember reading this thread.

Also, for movable point & spot lights, the shadow maps are automatically cached and reused the next frame using shadow map caching, so you don’t have to worry about those.

thanks, it seems a blur function was recommended in that post you linked. I tried using ue’4s spiral blur function.



It looks better, however now it has a big issue with shadow bias, so its not really useable.

It would be great to know how ue4 does it, As I need my custom shadows to look very similar to ue4’s built in ones.

“2 minutes” and “forever” are equivalent for PC games.

I stopped playing The Outer Worlds because of the level load times. I want to play a game, not look at loading screens!

… use an SSD.
Never had any issue loading anything on that game.
And the optimization on it was great for eu4.
Nearly consistent 60FPS at 4k on a 1080TI, you cannot possibly complain…

This was on Xbox. Gaming on PC is totally different! Even Cyberpunk was totally playable.

Anyway, computing shadow maps manually for two minutes when starting a level ON A PC would turn off approximately most players.
You could do a better job, perhaps, but using the GPU to render shadow maps and then flatten them to the terrain.
But then, why not just use (cascaded) shadow maps, and call it good? I tend to turn on Force No Precomputed Lighting in my world settings, and run all dynamic, and the build times are much nicer! And all shadows Just Work (tm.)

We all do. But… that’s not the same.
You can’t always do that.
And you should not unless you need to for other reasons- open world, daytime cycle, etc.

For instance, 2m loading on a mobile app to get an always seamless level gameplay is not a bad trade off… even on a switch it could really be worth the time waiting to get a realistic light effect.

Remember the skyrim days where we probably all burned at least one gfx with mods? I know I did… looked like a different game in the end though. Was almost enjoyable despite the lackluster story…

Have you made money from a mobile game that way?
What I’ve learned is that mobile players may have a total of 3 minutes for a game session – waiting for the bus, or sitting on the loo, or whatever.
Spending 2 minutes to load a game? It will absolutely not sell according to all data I have and have seen from others.
Whatever data you have would be very welcome!

No data, but its a common tactic to provide revenue by having the player watch an ad or something.
Sure, 2m is lenglengthy. But 30sec is a constant in the world of ads.
If you could get the bake to only take that long (near impossible on a mobile) you’d be able to provide a “natural” way to make revenue.

Mind you, there’s nothing natural about it. You are charging them to load a game level, which is kinda preposterous, but I have seen and played stuff made this way

Much of the above conversation is a bit of the mark of what i wanted to achieve. What I wanted, was shadow depth maps that dont update every frame, but more like every minute. I Haven’t figured a good way to do this though.

You can disable per-frame capture and only capture the scene every minute. You can also save the captures out to disk (which can be useful for a big map): Export Render Target, Import File as Texture 2D.

But for each dynamic object (e.g. the character), you will need to render the shadow map for them separately per frame. I think the engine already handles per-object shadow maps for stationary lights (Shadow Casting, bCastInsetShadow, Dynamic Scene Shadows), but not sure if it’ll work in your case; you need to look into it to see.

1 Like

Just use normal dynamic shadows. Why make things harder for no reason?