Better DFAO everytime with simple easy tweaks

It’s 2021 and I’m not sure if I am writing this topic too late but recently I’ve been playing around with Distance Field Ambient Occlusion and found some little settings to tweak which make the results “significantly” improved. I thought I’d better share this for the guys who are trying to use DFAO after this moment. DFAO is performance friendly and used in Fortnight so you might also want to use it in your project.

First of all, DFAO is for open type levels and fully dynamic levels to achieve darker interiors and shaded areas. NEVER use DFAO for arch viz as it’s quality is not reliable enough to achieve realism.

I’m only going to talk about DFAO and not going to talk about Distance Field Shadows. I’ve lit the scene with only skylight with DFAO enabled without directional light and SSAO so that u can easily see how it works.

See how to enable DFAO here.

Once you apply DFAO into your level you’ll notice that it has a lot of artifacts, the shadows are very harsh and pretty much unusable.

To disable these pitch black artifacts, turn on two sided Distance Field Generation in Mesh Details panel of your meshes. I’m not sure what kind of cons it will bring but this thing magically solves pitch black artifact issue in my scenes. You might wanna set DF resolution scale to more than 1 if the mesh in your scene is large or complex.
Capture2

Now tweak these settings in SkyLight to make the shadows less harsh and evenly distributed.

  1. Brings up Occlusion Max Distance if you want large shaded areas. You can bring it up pass 1500.
  2. Occlusion Contrast to 0.5 to make the shadows more defined.
  3. Min Occlusion to 0.2 to lighten very dark harsh black shadows. This make overall DFAO shadows lighter.
  4. Occlusion Exponent value to more than 1 to make the shadows darker again.
  5. Occlusion Combine Mode to “Multiply” if you want to combine DFAO with other AOs like SSAO.

You might also wanna play with Lower Hemisphere Color to achieve dark ceilings.

Now look at the final results!

The shadows are well distributed, the areas are well shaded, no pitch black problem and it just looks better. I hope this topic will help your projects.

EDIT: If you want further optimization, only generate DF for walls and roofs, disable DF for probs by setting DF resolution to 0 and use SSAO for a nice AO around the probs.

5 Likes

If you can’t see the attached images, it is chrome problem. Use other browser.

It does cost more. But its worth it.

Two-sided distance fields cost more to raymarch.

When you are getting pitch black spots on a solid mesh (especially in crevices like a staircase) it typically means your distance field resolution is not sufficient to approximate the mesh. The solution is just to increase the resolution scale until it goes away.

Enabling two sided distance fields isn’t necessary. They are really intended for porous surfaces with a lot of high density detail (such as foliage), not solid geometry.

3 Likes

While raising the scaling may have helped on those stairs. It didn’t do much for some other meshes I was having issues with. I went and tried turning on two-sided and it completely got rid of the issue for whatever reason. Even after setting scale back to 1.

1 Like

Could you provide an example?

The particular ones I tried were the antennae meshes and several others from Infiltrator demo I think. There’s been issues on meshes as simple as cubes though. Scaling just altered the artifact without removing it most of the time.

I assume you’re probably talking about the infamous “1M_Cube” that some of the templates use:

Here it is at 1.1 Distance Field Resolution Scale:

Anyway, the reason I asked for an example is because personally I have not found a mesh that had problems that couldn’t be solved by increasing the resolution (not yet at least). That being said, if you encounter a mesh that you can’t fix by increasing the resolution scale, by all means use two-sided. But that should be a last resort, not a first choice imo.

Concievably, if you had a huge mesh with a lot of detail that was just the right shaped detail, you could hit the 8mb limit on distance fields while still not having enough resolution to reasonably represent the mesh. Something that comes to mind would be something like a steam locomotive, very large with an immense amount of detail that includes a lot of sharp angle crevices. Most scenarios like this are solvable simply by breaking the mesh up into a few different pieces. Up to you whether you want to do that when you can just slap the two-sided button and call it a day.

Increasing the resolution didn’t solved for me too even if I’m using perfectly solid meshes. I was even setting like value 7 and the artifacts still exist. Two sided DF with resolution 1 completely solves the pitch black issue.

I know it works. You could set the resolution to .001 and it would still work.

My point is not that it doesn’t work, it’s that there are better ways to solve this problem in most cases.

How do you guys use 2 sided mesh distance field without making it look completely horrible?

2 sided mesh distance fields


Horribleness

Same scene without 2 sided, just the normal mesh distance field.

not enable it on trees? you can pick this option per object. I rarely use DFAO on trees… more of SSAO.

Irrelevant, I only used a tree because it was a scene that I had ready, the same applies to anything.

2 sided


Standard

2 sided ALWAYS 100% of the time looks horrible for me, this is why Im asking what do you do to avoid it looking like that.

It does not make much sense to use DFAO these days. The artifacts just aren’t worth it and there are better solutions. Especially since DFAO nonsensically relies on existence of SkyLight. Here’s what I suggest:

  1. Turn off SSAO/RTAO AO completely. by setting it’s intensity to 0 in the post process volume. Check “stat gpu” cvar to verify there are no AO related costs.
  2. Turn off DFAO.
  3. Enable SSGI using “r.SSGI.Enable 1”
  4. To get performance comparable to DFAO/SSAO, use “r.SSGI.HalfRes 1”

This will give you indirect contact shadowing much more accurate than both SSAO or DFAO, and with the HalfRes cvar, the performance impact should be similar. You can further reduce it by also tweaking the “r.SSGI.Quality”. If you have HalfRes enabled and reduce quality to 2 or 3, you should actually get even smaller GPU cost than with SSAO/DFAO. While at the same time, better quality indirect shadowing effect than AO can provide. Especially in the example scene you can see in the first post, you should be surprised how much better it looks.

It is very important to first disable SSAO/RTAO/DFAO. SSGI is mean to replace these effects, not supplement them, but there seems to be a workflow issue that if you enable SSGI, it actually replaces these effects visually, but the performance cost of AO effects is still there, even if they are not visible. So make sure to turn them off.

SSGI is not meant to replace DFAO, they are completely different things and can be used alone or together.
SSGI is in screen-space so it can only give you small-scale detail (you can crank up the scale but you’ll get more off-screen artifacts), while DFAO is in world-space which means you get occlusion from objects that are off-screen.
SSGI rebounds light and works on any light, while DFAO occludes light and only works on ambient (sky) light.

Working with only GI you have to think of lighting as “additive”, i.e. your sky light should be the minimum desired ambient light (start with a dark base) because light rebounds will add up light to your scene.
On the other hand AO is more of a “subtractive” way of lighting, i.e. your sky light should be the maximum desired ambient light (start with a bright base) because AO will make things darker on occluded areas.

The fact that they work so differently makes them a good cause to use them together: use an average desired ambient light, knowing that SSGI will brighten it up in some places (on a smaller scale) and DFAO will darken it in other places (on a medium scale)
Couple them up with a larger-scale AO or GI solution (such as LPV) and you’d be covering small, medium and large scale real-time AO and/or GI, which is exactly what Lumen in UE5 will do (except Lumen will supposedly blend between the different-scale solutions instead of just stacking them up)

_

btw the infamous Cube problem with DFAO is due to non-uniformly scaling (and excessive scaling in general) of the asset. I thought by now it was widely known that scaling + DFAO was a limitation :thinking:

Sorry, but this is just not right. SSGI completely overrides the AO. At least the SSAO effects, and DFAO is just a different way of approximating the same effect - indirect shadowing. When you enable SSGI you immediately see the SSAO effect go away, as expected. So the fact DFAO and SSGI can work together is way more of a bug than a feature.

In traditional rendering, the AO was originally invented as a means or providing indirect contact shadows in areas which would be otherwise uniformly lit by an ambient lighting. It’s a remnant from the times when ray tracing skylight illumination was expensive even in offline rendering.

Then, AO became something a bit different. It was often used in rendered which had really terrible, low accuracy global illumination solutions such as Final Gather in Mental Ray, where AO was used as a means of “detail enhancement” where the FG would take care of general indirect surface illumination while AO would supplement the more accurate local indirect shadowing. But this whole approach was not very physically based.

This has spawned a gross trend where people would tend to just render AO pass and multiply it over final image. And they would do it even without actually knowing the reason. Many people would just render an AO pass and multiply it over the the beauty pass just because they learned it somewhere.

Once better GI solutions appeared, mostly using brute force path tracing for primary bounces and some sort of radiance/light cache for secondary ones, the indirect illumination contact shadowing was no longer lost due to the inaccuracy, so multiplying an additional AO pass on top of the beauty image actually made it look worse and less realistic. The interior visualizations for example would look like there’s a layer of dirt/soot in most of the concave areas.

And this trend unfortunately made it in games too, where people think that the more knobs they turn on, the better and more realistic will their scene look. And that’s just no true. If you enable DFAO alongside SSGI, you will get the benefits of SSGI compromised by the inaccurate, blurry artifacts of DFAO. SSGI actually approximates local indirect bouncing, so if you have a cube lit by sun and sky, on sunny side, the concave areas will actually glow, where as on the shadowed side, there will be subtle indirect shadow. DFAO on the other hand just adds the ugly, blurry dark blobs even on sunny side where they do not belong.

SSGI disables SSAO in its current implementation of UE4 yes, but that’s not quite right. to me that’s the bug, and not the fact that you might be able to use DFAO with SSGI.

I agree SSAO has been misused over the years, since AO is just indirect lighting occlusion it’s only meant to add contact detail where only indirect lighting is present, or in other words where direct light is not hitting it. The current SSAO implementation in UE4 is true to this principle btw.

So even if in UE4 SSGI replaces SSAO there’s no reason why it should be that way. In a perfect world rendering the ambient light would be true ‘exterior’ sky light (and not a general ambience) and GI would just flood everything with that exterior light towards the interiors based on exposure (occlusion), so you’d get less and less light on interiors and closed areas from the effect of occlusion up until you can have complete darkness, and therefore AO would be unnecessary.
However due to approximation it’s very common to just use a general ambient light which in itself prevents complete darkness, and triggers the need to use AO. but just because you darken the ambient light with AO doesn’t mean you can’t also increase the light with bounces using an approximated GI.

So, if GI were to properly work with AO, the desired result should be having a general ambient light, have the AO darken it where applicable, and have the GI add more light from bounces where applicable. And of course remove some of that added AO where light bounces hit. And that should be the expected behavior in UE4 if SSGI wouldn’t be disabling SSAO, all the same as it should be the expected behavior of using SSGI and DFAO (just working at different scales). I haven’t really tried it myself though, so bear with me as this is just theory and expectation

Eventually we’ll get to a point where GI will take over and AO will be unnecessary, but in the meantime I’m convinced that game renderers should try to mix GI and AO.
Any of the current GI systems that work as an additive light bounce process (without AO) are simply not gonna block ambient light to allow dark interiors, and if you try working without a general ambient light (from a pitch-black ambient base) you’ll probably find it impossible to light everything with just bounced light from GI - everything will just be too dark. So in general you’ll probably want to mix GI and AO unless the GI system is already mixing GI and AO itself (like LPV was doing IIRC)

Sorry, but you still seem to have things mixed up.

SSGI has both additive and subtractive component. The local indirect illumination means both light bounces and light bounce attenuation. You certainly do not want to use it alongside SSAO. It just makes absolutely 0 sense, because you would get the worse SSAO artifacts, and the double cost of both SSAO and SSGI sampling, to ultimately get double (less accurate) occlusion with the smudginess of SSAO that SSGI does not suffer from.

Here’s a simple proof. A stereotypical example of a sphere on a plane lit by skylight environment of constant color (bottom hemisphere is solid color is unchecked on skylight):

You can see that with SSAO and SSGI off, all you can see is perfectly solid color, which makes this somewhat calibrated environment to show that SSGI does have occlusion component. If it was only additive, the scene would either not change or the concave areas would actually brighten up a little. It’s just that due to excessive overuse of AO by inexperienced people, they generally expect the occlusion factor to be unrealistically strong, as SSAO does offer multiple “artistic control” knobs to break the accuracy while SSGI does not.

There’s no such thing as “GI Properly working with AO”. AO is just very poor approximation of GI. As you say, it’s a consequence of technical limitations, but it has nothing to do with proper solution.

You are right to point out that SSGI, like SSAO, can not consider surfaces outside the camera frustum. I agree that using the DFAO for general mid scale occlusion solution would be somewhat acceptable in specific cases where lightmass is not an option (the scene geometry changes at runtime). It’s still a really poor solution, but until there’s lumen, we probably don’t have many more options.

The reason I originally replied to this thread is because according to the pictures in the original post, the author of the thread is trying to use DFAO in a way which does a lot more harm than good, both in terms of performance and visual quality. I guess you can see it for yourself. And in this case, the SSGI would really make a tremendous difference, because flipping just a couple of knobs would make his scene instantly appear a lot more realistic, and at the same time there would be no longer need for any tedious DFAO artifact troubleshooting.

But yes, I can see a scenario where subtle DFAO for large scale skylight occlusion of interior spaces could work, even alongside SSGI. Especially in larger levels with frequent exterior<->interior transitions. On the other hand, I still disagree that SSGI should work with SSAO, and if it did, I would personally consider that to be a bug. I am really happy someone at Epic had enough foresight to prevent them both being enabled at the same time. There’s already more than enough traps in the UE4 for beginners to fall into when it comes to proper rendering setups :slight_smile:

This is not correct…

  1. If you looked at the distance field through the mesh distance field visualizer you would immediately realize this is a problem with the distance field generation.
  2. If your theory were remotely true, increasing the resolution scale by 10% would not have solved it. But it did.
  3. This doesn’t even look like the artifact for non-uniform scaling. Excessive non-uniform scaling produces stretching and ringing/rippling in the AO, not black splotches. Here is an example:

I have to admit I’ve never encountered this issue before and I’ve no idea what might be causing it… Sorry.

Hey, thanks for the suggestion, but when I turn ssgi on the performance halves, and when i try the halfres command I get this

The effect is limited to that square, what am I missing?