Weird artefacts in Deferred

Hi Everybody.

This is my first Post. I have been using Unity at work for 8 months now (and everybody there for much longer). But we have run into some weird artefacts. There appears to be some banding in the reflection while rendering in deferred, but in forward it seems nice and smooth.

If we take out all normals and let Unity import and interpret the mesh on its own, there doesnt seem to be any of this banding.

Importing the mesh with different setups for normals and different interpretations (or even splitting the mesh) had no effect.

We need deferred for our pipeline. Does anybody have an idea where the banding comes from and possibly how to fix it?

Cheers

The banding comes from using deferred.

Your response to reading that is probably “I know, that’s what I said!” Unfortunately that’s kind of the only answer.

Deferred works by storing stuff like the albedo, specular, and normal values in several full screen textures, referred to as gbuffers. In the case of the assets you’re using you’re hitting on the limits of the normal texture’s precision for storing normals. Unity uses a RGBA 10 10 10 2 format for the full screen normal gbuffer. That means the normals only get 10 bits per channel, which works pretty well for most situations. Unfortunately it’s not enough for you. You probably need a 16 bit per channel normal to get rid of the banding, and there’s no way to override Unity’s deferred pipeline to use a different texture format for the normals.

The work around would be to add a small amount of noise into your normals. Not enough that it would be obvious, but enough to break up the obvious banding. Basically you’d need to dither the normals that are output. You can’t do this with the standard shader. You can give it a normal map to use, but Unity’s normal maps are at best 8 bits per channel, so even the smallest amount of noise from that would be more than you’d likely want. You’d need to use a custom surface shader with a finalgbuffer modifier and add a tiny amount of RGB noise.

2 Likes

I just want to say that to my eyes there is neglible difference between the two images. I’ve been looking at them for a while and can barely tell them apart. Are you sure it’s much of a problem?

Look at the dark band in the reflection.

Does the Unity post stack not offer blue channel dithering? GitHub - Unity-Technologies/PostProcessing: Post Processing Stack

  • apologies if totally way off base.

That’ll help with HDR to LDR banding artifacts. That won’t help with banding from the normal buffer.

1 Like

Thank you bgolus, I will discuss this with my coworkers. Not sure if adding some noise in the normal will be the option we need, but neither is having the banding in these close-ups. Will look into the blue channel dither as well, just to cover all bases :slight_smile:

FYI, what @hippocoder was referring to is blue noise, not blue channel noise. Blue noise isn’t actually blue in color, it’s a type of noise.

http://momentsingraphics.de/?p=127

You could use one of the RGB noise textures sampled in screen space to add +/- some very small amount of noise to your normals (maybe only 0.001, or potentially less) and see a substantive quality difference. If done right you may be able to remove the visible banding with out adding any noticeable noise to the final image.

2 Likes

Thank you for clearing that up, very helpful! We are going to look into this, we already had a couple of discussions about how to implement some of this.