Skip to content

Add support for baking positional shadow maps #12248

@jitspoe

Description

@jitspoe

Describe the project you are working on

Retro FPS with realtime per-texel shadows.

Describe the problem or limitation you are having in your project

Hitting a lot of performance issues with dynamic lights, but baked lights don't allow my shader to do the self shadowing effects and some other features I've implemented, and the end result is extremely flat.

Image

Also, single-point lights create very hard details. For example these lights create unnaturally hard shadows on the ground here:

Image

Image

And, finally, baked lighting doesn't let you have cool monster shadows when stuff is lurking around the corner.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Rather than bake the lighting, a shadow for each light would be baked for the static geometry it comes into contact with. A radius could be added to the light to soften the shadows, and real-time shadows of dynamic objects could be combined with the pre-baked shadows. Only the dynamic objects would have to be rendered for the shadow pass, so that should help performance a lot.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

I haven't delved into the details, but it could possibly be implemented something like the shadowmap used for directional lights, except extended to omni/spot lights as a per-light baking option. godotengine/godot#85653

Ideally, it wouldn't be tied to the lightmap GI, though, as I'm not using that and don't want to add any extra data/rendering passes. For my Quake-like aesthetic, directional-only lighting seems to work best for the creepy vibe and some pitch-black shadows.

I'm not sure how feasible this is, as I don't fully understand how the depth maps for shadows and such work and why an atlas is necessary, but my general surface-level idea is this:

  • For each light, figure out which polygons of static meshes are impacted by the light and uv unwrap those. Might have to duplicate the mesh data or something if this is to be supported with lightmaps as well since I'm not sure there's something beyond uv2, also several lights might overlap the same polygons.
  • Bake line of sight to the light (using a 0-1 range so we can have partial occlusion with a bit of area to the light and also have anti-aliasing) onto either per-light textures or an atlas.
  • Dynamic objects rendered to shadow atlas as usual.
  • When the shader executes the light() function, it behaves like a normal dynamic light with the baked shadow simply calculated into the ATTENUATION value.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

Core rendering feature.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions