guycalledfrank / bakery-issues

Bug tracker for Bakery
4 stars 0 forks source link

Merging volumes at runtime #100

Open laurentopia opened 3 years ago

laurentopia commented 3 years ago

This is for the following scenario: In a mountainy landscape the player adds buildings, the ground gets darkened by their AO and get some bounce light from the green walls. as the village becomes tightly packed the buildings get bounce light off one another. Each prefab has its own volume. runtime volume merge merge them in the world volume.

guycalledfrank commented 3 years ago

There is no proper way (that I'm aware of) to combine two volumes. Partially it should block the light on another volume (darken/multiply occlusion), partially it should add more light (emissives, bounces).

You may have seen my experiment: https://youtu.be/Y-oxFqwWqJQ

Here I only used the multiplication; you can see how two trees placed in one position produce double darkening.

It also worked using compute shaders, so it's not viable on mobile platforms. It is possible to reimplement the same thing on the CPU, but it would cause performance spikes when combining decently sized volumes...

Even in this case, the volumes are greatly simplified and use 8-bit color + 8 bit direction instead of the full RGB16 * 4.

In a deferred renderer it's probably easier to draw each volume separately and make it recolor the pixels inside it, similar to how deferred lights work. But again, it won't suit all platforms.

Probably worth to be a separate asset or something.

laurentopia commented 3 years ago

I saw that a while ago and loved it. The overdarkening didn't bother me and unless you go for super high realism this is not a big issue so I think adding this or making another asset has merit. Also there might be a better blend method than multiply, more expensive for sure but perhaps photoshop overlay is better.

Regarding production & platform readiness. Deferred or compute is acceptable comprimise for such a neat effect. Also I think cpu merging is an option: compute the world volume with a staggered bursted job. The benefit of a staggered update is that production can dial in the budget of that effect. For example a switch game would have to bake the volume at 1/16th the resolution and stagger update every 10 frames. There are also ways to be more aggressive with the update optimization:

Budgeting & controlling effect cost is very production friendly.

guycalledfrank commented 3 years ago

Photoshop's overlay doesn't make much sense in a HDR scene, as it assumes fixed 0-1 range (and gray at 0.5):

(base < 0.5 ? (2.0 base blend) : (1.0 - 2.0 (1.0 - base) (1.0 - blend)))

Using 8 bit color (as I did) is also a significant (!) limitation that won't work out of the box for most scenes. In my case the plan was to have a separate layer of "regular" static, full-range, volumes and another simplified layer used for this combined volume.

Burst jobs could work. Didn't play with them yet.

But honestly it's a lot of work and I'd rather use more lightweight workarounds for cases like these.

laurentopia commented 3 years ago

What lightweight workarounds do you use to get that?

I use volume shadows which is fabulous for non directional shadows and non directional additive lights. It doesn't come close to AO or GI though as it lacks point data or directionality. the dev tried to add directionality but URP 8.31 lacks a way to get scene normals in a shader. Maybe that's a way to produce the same effect for cheap.

guycalledfrank commented 3 years ago

Deferred-only approach would be the most reasonable. This way there is no need to merge, base volumes and additional multiplicative volumes can be completely separate. We can basically have a box attached to a dynamic object that samples another volume and blends it into the GBuffer.

laurentopia commented 3 years ago

Deferred only is a worthy constraint for such an effect!