Problem with Cascaded Light Propagation Volumes

Started by
7 comments, last by jcabeleira 10 years, 7 months ago

Hello,

at the moment I work on implementing cascades for my Light Propagation Volumes implementation and I always have "problems" with the different cell sizes and the results produced by this.
First a picture of the Problem ( I only draw indirect light here, the bottom plane is white and the light Comes from straight above):

cascades.jpg

As you can see the 3 different cascades are clearly visible, and now a picture where I draw spheres for each cell shaded with the spherical harmonic of this cell (of the cascade with the smallest cells and the one with the biggest cells) :

spheresCascades.jpg

Here you can see where the problem is, in both displayed cascades the light comes from straight above and therefore the cells near to the bottom are the brightest, thats fine. (The blue line is the bounding box of the cascade with the smallest cell size)
And in both cascades the first 1- 3 or 4 levels of cells (from bottom to top) are receiving a considerable amount of light. The problem is that the cell size is different and therefore in the end with greater cell size the light seems to travell much further than with small cells and this is the problem.

To me this problem is clear and I really have no idea how to really solve this. In the papers about cascaded light propgation volumes, they dont seem to have this problem or because of the fact that usually the center of all cascades is centered around the camera (with some offset sometimes) it might not as obvious but I dont really believe that, they must do something different.
Another way would be to use the cellsize in the propagation of light and try it with a quadratic or some kind of falloff, but even the you would see a difference just because of the different positions of the brightest cells.
My feeling is that there is no really solution, just some fixes which makes this a little bit smoother like Interpolation between cascade borders.

So far I tried to handle each cascade independently and in another approach I even propagate light between cascades which is a little bit better but the described problem is in both cases clearly visible.

If some one has any thoughts or ideas I would really appreciate it.
Thank you

Marc

Advertisement

Are you propagating the same amount of cell steps for each cascade? If you are, obviously the larger cell sizes will propagate light farther than the smaller cells sized cascades, as light will be "going farther" thanks to the larger cell size. I'm not sure if Crytek actually ever implemented cascaded LPV in a shipping game though. I imagine in part because of the effect demonstrated in your first picture, which seems to come directly from the differing quality of spherical harmonic coverage for each cascade. Maybe having the cascades centered around the player would indeed reduce this enough to not be terribly noticeable.

Yes I use the same amount of iterations (propagate steps) for each cascade. And yes what you are saying about the obvious fact that light "goes further" with larger cells is exactly what I would expect. And most of the thesis about LPVs or implementations do not consider cascades (maybe for this reason??). But the orignial ones from Crytek just gave me the feeling that I miss something important and that it should just look fine or at least not as worse as it was with my implementation.

Beside that the Crytek paper mentions that they convert the intensity of the spherical harmonics to incoming radiance by using half of the cellsize but only for rendering the result but not in the propagation, therefore this can not be the solution of the problem.

When I find something new about this I will post it here.

I will try it with the sponza scene in the next days, at the moment I think that it might be that with centering around player ormaybe select the cascade to use with caution, as an example first evaluate if the complet object is in that cascade et, it might not be terrible.

Thank you for your thoughts and the acknowlegement that I am not completly crazy.

Yes, the light will travel more distance on the larger volumes. But I think you're missing the point. I assume you are using the cascades like this:

if distance < 5 then

radiance = sampleFromCascade1()

else if distance < 20 then

radiance = sampleCascadeCascade2()

else

radiance = 0

However, they are not mutually exclusive, they should be combined like this:

radiance = sampleFromCascade1() + sampleFromCascade2() <- (you can weight each cascade to tune the effect)

Why? Because larger cascades are used to provide global illumination effect for a large area. With it, two distant walls can bleed light between each other because the larger cascades can cover the area between them. However the detail of the illumination won't be great because the resolution is too low for the covered area.

The smaller cascades are used refine the detail of the global illumination where it's important: near the viewer. In this case you're using a small propagation volume to simulate the interaction between smaller objects that are near the viewer.

By combining the two you are complementing the rough global illumination of the large cascade with fine detail of the smaller one. You'll get rough light bouncing for the entire scene and rough + fine light bouncing for nearby objects.

Of course, with this approach you might be adding some duplicate bounces but in general that is not noticeable and the whole effect looks very good.

BTW, the gradient of the lighting I can seen on the walls in your screenshots looks exactly as expected. Your implementation seems to be on the right track.

Yes you are right more or less, I look up which is the finest cascade at the current position and use that one.

I tried your suggestion and I scaled the radiance from the biggest cascade with 3 the middle one with 2 and the smallest with 1.

This results in the following Image:

cascadeAdditive.jpg

It is in a way not as bad as before but not really great. I could play with the scale factors and so on.

However you seem also too agree that the base problem is there and that it might be difficult or impossible too overcome it without "cheating" a little bit.
Other ideas someone?

Overlapping cascade? On the cell the cascades overlap each cascade only contributes half luminance, so you sum to your full normal luminance but get a halfway transition?

I'd been thinking about a paper where they voxelized static geometry for the scene, injected into the LPV grid, and used that as a means of secondary shadowing (i.e. don't transmit beyond a cell that's solid). Using that you could also create a Sparse Voxel Octree instead of a regular grid. Your cell sizes would get progressively larger, you'd have to less iterations to get light farther and use less memory, minimizing the need for cascades. But with the jump in quality differences I'm not sure how well that would work. And you'd get greatly varying amounts of light distance based on areas of scene complexity.

I'd also thought about something like LPV just transmitting anti-radiance. I.E. if you have a typical hemispherical light term you transmit the opposite of that to "block" it as a shadow. Voxelize the scene, iterate enough to transmit anti radiance (no color needed) a good enough ways, you'd get a nice realtime shadow term from your skylight. Not what you probably had in mind, but I'm just spewing ideas. The guys over at Crytek recently complained that there's no good solution to GI/Reflections and exhorted others to solve this problem, since they invented (and for Crysis 3 improved upon) LPV to begin with I assume they're just not happy with it, probably for much the same reason you're seeing now.


Overlapping cascade? On the cell the cascades overlap each cascade only contributes half luminance, so you sum to your full normal luminance but get a halfway transition?

Sorry I am not sure that I understand what you are saying.
In the first pictures I posted I had no overlapping cascades (the big one is left empty where the smaller one fits in, and the propagation also accounts for this), and I had propagation between cascades in it.

The new picture uses overlapping cascades (way easier to implement) where each cascade propagates independently.
Then for rendering I took (3*Cascade1Value+2*Cascade2Value+Cascade3Value)/6 for a position in the finest cascade. I know that summing up something there is physically completly wrong, just tried it to see the visual result.

At the moment I am just trying how good this cascade approach works, but I really appreciate your ideas.


Overlapping cascade? On the cell the cascades overlap each cascade only contributes half luminance, so you sum to your full normal luminance but get a halfway transition?

Sorry I am not sure that I understand what you are saying.
In the first pictures I posted I had no overlapping cascades (the big one is left empty where the smaller one fits in, and the propagation also accounts for this), and I had propagation between cascades in it.

The new picture uses overlapping cascades (way easier to implement) where each cascade propagates independently.
Then for rendering I took (3*Cascade1Value+2*Cascade2Value+Cascade3Value)/6 for a position in the finest cascade. I know that summing up something there is physically completly wrong, just tried it to see the visual result.

At the moment I am just trying how good this cascade approach works, but I really appreciate your ideas.

Transferrence between cascades is fine and well and probably should be done. I mean instead of choosing the finest cascade in the overlapping areas you average the results of the two cascades so you get a nicer transition than just an arbitrary and obvious cut off.




It is in a way not as bad as before but not really great. I could play with the scale factors and so on.
However you seem also too agree that the base problem is there and that it might be difficult or impossible too overcome it without "cheating" a little bit.
Other ideas someone?

Actually it looks good, that's pretty much how LPVs look like when applied to a scene alone. Maybe your second volume should be larger to extend the reach of the GI, ensure that you have a setup of volumes that gets you GI for the whole room (no black walls). Once you have that, you can try to use a more "decent" scene and add direct lighting to see how the GI looks on it, you may be surprised with the results. ;)


Then for rendering I took (3*Cascade1Value+2*Cascade2Value+Cascade3Value)/6 for a position in the finest cascade. I know that summing up something there is physically completly wrong, just tried it to see the visual result.

It's not physically correct but then again neither is computing the GI in 2 different volumes. We only do this due to technical limitations, ideally we would want a single high-resolution volume covering the entire scene. Since we can't get it we use several volumes with different coverage areas to get a fairly decent estimate of the scene radiance. The effect takes some hand tuning so play with the volumes weights until you get something that looks good.

This topic is closed to new replies.

Advertisement