Dynamic GI : Getting the Most out of LPV ( Light Propagation Volume )

Hi All,

I decided to write a little guide about getting the mode out of LPV as a Dynamic GI solution. I believe we have achieve a very solid use-case with Dynamic GI and have gained some insight into the usage. With this we would like to give back to the community, there were very little guide on using LPV properly in Unreal Engine 4. I hope this would help someone along the way. Note that this is something I continue expand on as I learn more about LPV , so right now it might be a very long guide.

A lot of people seems to suggest that LPV isn’t production ready. I don’t quite agree ; but I digress since this isn’t the point of discussion.
But before we begin , I’d like to point out that this isn’t a guide on how to setup LPV but how to maximize it’s usability using LPV settings in post process and in general our experience of using it.
Official guide on how to setup can be found here

What’s great about LPV :

  • Easy to Setup. One edit of .ini is all it takes.
  • Relatively Cheap in performance comparing to other solution
  • Cost is highly scalable to your liking. You can adjust the size, and easily turn on and off with a single boolean.

There are 2 major highlights that I want to cover in this tutorial/guide. It’s the thing that LPV doesn’t do out of the box(default settings)

  • LPV is great but it does NOT look good out of the box. It’s inaccurate and make things look weird. You will need to adjust some extra settings when using it.
  • LPV isn’t just used to add GI to areas. It’s also use to occlude ( darken certain areas ). For dynamic light setup , this is good because skylight fills the world up with constant light and if you have large shadowed area , it looks somewhat ‘unlit’ on these areas. I will cover occlusion as an important aspect of LPV ( again this isn’t automatically there out of the box ).

Firstly before we being, in order for you to unlock LPV’s settings. If you have yet to have a post process volume. Drop one in , uncheck ‘unbound’ and proceed to edit it’s LPV settings. Everything we’re talking about here deals with this section.

Let’s begin to deal with each issues of LPV:

Light Injection Bias

The first problem we face when we use LPV was the fact that light leaks through surfaces, making them look translucent. LPV works by splitting the affected area into small cube area and then calculate which area is affected by bounce and what color value it is. I don’t know the full working behind this , but adjusting this value prevents light from spilling over small surfaces. I noticed that somehow BSP are less affected by this. Here’s how it looks like with and without adjustment. Note the huge differences.

**Occlusion **
The second most useful option is occlusion. As mentioned earlier , most people tend to use LPV to light up additional areas with extra light bounces. But what they tend to forget is that occlusion is as important.
When you got with full dynamic lighting ( assuming you use DFAO ) , the skylight tend to flood shadowed area with a very uniform light , this create a very monotonous lighting. Turning on occlusion and adjusting them gives
you the advantage of darkening occluded areas. Some might think this is too subtle , however, when it comes to lighting , I believe subtle notes are sometimes the key factor in creating realistic environment…

To enable this , just increase the Occlusion intensity to above 0.0.

In the screenshot below , note the area behind the tree on the first picture and the general ambient inside the cafe. It has a very strong contrast. In the second picture , you can see shading of the pavement area totally differ from the one before tweaking.

Some extra info:

  • In LPV settings . The Size parameter could significantly impact performance. It’s the size area where the LPV affects. You can tweak this value to balance performance vs quality.
  • To allow scalability options for user to enable/disable Dynamic GI ingame, you can always enable/disable 'DynamicIndirectLighting 'boolean in DirectionalLight. This is the easiest way IMO.
  • Secondary Light bounce can be enabled , I personally don’t find them significant , but the cost is extremely low. I suggest trying them out.

Here are some extra screenshot of what it wouldn’t be possible without LPV.
Additionally here are also some GIF Comparison of LPV turning Off and On; with the right tweaks the difference are quite significant.

Note that these are screenshot from our WIP game and there are some untextured assets, the point of this is to appreciate the subtle lightbounce of the environment.

Thanks for the tutorial Frozenfire.

I was tweaking a bit the LPV settings few days ago. For now i am making mobiles games, but for a future project i was looking for some real time GI solution, for an open world type of game.

How would you handle a big landscape for example 5kmx5km with LPV?

By the way great work so far on Eximius, and on Puzzle Match-3 Template too.

LPV isn’t dependent on map size. It generally only calculate a certain distance from where the player is. Hence it’s a very viable solution for big map as long as it’s majority an outdoor map.

thanks for the guidance, but im not quite sure about what LPV does and the reason behind its creation. is it some kind of solution (analog to lightmass importance volume for static lighting) for quality dynamic ligthing? and in what cases this would be convenient to implement?

Thank you for posting this :slight_smile:

@maquina LPV is a dynamic GI solution. It deals mainly with GI only. Because we don’t have lightmass/lightmap in Dynamic lighting , what we have is mostly AO ( either from SSAO or DFAO ). This means that other than the AO applied , shadowed area lack the depth of contrast ( they’re flatly lit or unlit ). Large shadowed area suffers the most.

A few points for you:

  • LPV works globally , it’s not a volume per se, but it calculates a certain distance from Camera.
  • The post process I mention about is needed because LPV’s settings are somehow in post process. Without post process volume , you can’t adjust the more important settings.
  • LPV works best for Outdoor scene with very intense lighting ( harsh shadowed environment ), something like sunlight.

thanks man, really appreciate the answer. i have to say after reading this and digging into Ray Traced Distance Field Shadows, DFAO and the stuff related its freaking mind blowing :).

Thanks for sharing!

We followed your tutorial and have an outdoor scene (large landscape)w with a day/night cycle and only dynamic lighting. However, we cannot see any visual difference with the LPV. Would you have a guess as to what we have not done correctly?

Got a question here, what difference you got from one of these right images and the skylight in dynamic, cause looks like LPV is doing near nothing with the colors at all, so you can save probably all of that and use a skylight that gives basically the same result ?

By the way thanks for share with the community.

@Hevedy LPV affects the scene subtly but significantly IMO.

Here are some animated comparison shots. Imgur: The magic of the Internet
In a lot of the scene it’s mostly use to create tighter shadows around larger objects ( buildings ) etc ,

@Rhynedahll do you have some screenshots? I’m not entirely sure where you’re stuck at .
Do verify if your LPV is actually working , and then you can work on tweaking.

I’ve just posted an animated comparison of what you can expect from a well-tweaked LPV in my reply to Hevedy.

That’s just it. We cannot verify if the LPV is working because no adjustment makes any change.

Is there some setting elsewhere that must be enabled in order to make it function?

have you set the post process volume to unbound ?

Yes. We have completed all steps listed above. :slight_smile:

wait let me get this correct… you don’t know if youre LPV Is working of if you don’t know your ‘tweak’ is working?

if you’re not sure if your LPV is even working follow the guide in the official LPV documentation ;

use the visualize

To clarify: Our LPV is not working at all.

We’ve looked at the official docs previously and again after looking at your tutorial. The docs are so seriously out of date as to be of little practical use.

Again, thanks for your tutorial. We’ll work on it. :slight_smile:


Getting LPV shouldn’t be hard. Here are some checklist;

  1. Ensure your .ini in the ENGINE folder ( not project folder ) is edited as per in documentation. If you’re unsure , PM me for further details
  2. Ensure you’re using Movable skylight.
  3. Ensure that you have one directional light and it has 'DynamicIndirectLighting ’ boolean turned on. Search for keyword ‘dynamic’ in the property. it should be there

Thanks! You’ve been very helpful. :slight_smile:

We had, however, already sorted out that the missing step was #1, editing the .ini file. Perhaps you should consider adding that to your tutorial.

As soon as we convince Jenkins to build the client with the edited config, we’ll be good to go. :slight_smile:


I have some issues with the LPVs too. Does anyone know if there have been any changes from 4.12 to 4.14? Because I have set up a quick test following your tutorial in 4.12 and it worked absolutely fine. But in 4.14 the shadows suddenly are pitch black - with the same project files.
Does anyone have an idea what the reason for this strange behaviour might be?

Thanks in advance!

This may not relate to your issue (and you perhaps already know) but updating the engine overwrites the .ini file and turns off LPV by default.