Sign in to follow this  
Bow_vernon

Noise in deferred renderer

Recommended Posts

Hi sorry if I keep asking questions (Im learning).. Lately I've finished my deferred renderer demo. I asked my friends to run the demo on their PC. I saw it ran pretty well. Until a friend of mine told me that there's a "little" noise that really annoying, like this:

Artifact

And this is what it normally looks like:
Normal

Anyone can shed a light on this??I dont know what caused this. I thought that maybe some of you ever experienced a situation like this. I thx you for any help.

Best Regards,
Bow Vernon

Share this post


Link to post
Share on other sites
That can be more things imho, I'd try if it is not precision (using 16-bit depth buffer and reconstruct positions is not a good way to do it ... or rgba8 for normals ... they also need sign, so rgb10a2 should be minimum for normals).

Also it can be come wrong clamping/normalizing when computing light, or issue in self shadowing parallax occlusion mapping.

Share this post


Link to post
Share on other sites
Wow, I use 24bit depth buffer for position reconstruction, and I use viewspace normal, so the z buffer is not stored (calculated manually). any suggestion?? Should I use R16G16 format?? I'll try to use that and see if it gets better but while Im at it please share your knowledge about this problem....thx

Share this post


Link to post
Share on other sites
This sort of thing is usually a division by zero or square root of a (just barely) negative number in the pixel shader. E.g. if you are calculating your normal view space z via sqrt(1 - x^2 - y^2) and that sum of squares is just barely greater than one, badness ensues.

Share this post


Link to post
Share on other sites
#0xffffffff (btw. nice nickname ;)) - True, if it's that you can solve it the way 0xffffffff (= 4294967295 if you want him in dec instead of hex :D ... sorry for that, I had to do this joke :P) wrote, or maybe it might be better to store all 3 directions (x, y, z) of normals in rgb10a2 buffer. There are few reasons:
1) if you're using rg16f buffer - you have same storage as rgb10a2, but you use expensive sqrt operation on every pixel that wents through the normal reconstruction shader
2) if you're using otherwise - you probably have little less storage needed, but unless you're fillrate limited I think you should avoid that sqrt ... but it is up to you - someone would like to avoid it, someone not (probably based upon what are you going to add to rendering in the first case and if you're storage limited or computational power limited in the second case ... I'm mostly second case, so I would rather go without sqrt).

Share this post


Link to post
Share on other sites
oh well thx for the info. anyway, I use simple linear filtering, although the texel match the pixel (1:1 ratio). that is, I dont use power of two texture. but I guess that's no prob. I'll try ur suggestion. anyway, does fallout3 use deferred shading?

Share this post


Link to post
Share on other sites
Can you post your friends specs?

I also can look on your shaders (and I might see the mistake in them and try to fix/explain what is not working), I also might test it (On two laptops I have at home and on some (four currently) desktops also) - if you upload app or shaders source somewhere.

Share this post


Link to post
Share on other sites
How are you storing your normals? Do you store them in a XYZ form or do you use any form of packing?

I got these kind of artifacts when I used some kind of spherical mapping to pack the normals and I got simillar artifacts on the poles.

Share this post


Link to post
Share on other sites
There was some discussion about viewspace normals and storing only X and Y components and reconstructing Z - this does not work everytime: the sign of Z can also be negative.

And 8 bits is very bad precision for normals, you should really go to a R16G16 halfs.


On this page you will find many techniques to store your normals:
http://aras-p.info/texts/CompactNormalStorage.html

Share this post


Link to post
Share on other sites
Same issue here on Radeon HD 5470, Radeon HD 6800, Radeon HD 2900xt, GeForce 8600gt and some GeForce GTX (dunno which though) ... Yes, I have that much computers running at home (and no one is sponsoring me :( ... I have to run business myself :P).

Okay, I tried to fix your shaders and fixed them... two ways are possible (the one 0xffffffff described and one I described):
First Way (pass 3-channel normal to g-buffer):
In your source GBuffer.frag

//Scale And Bias Normal
vNewNormal.xyz = normalize(vNewNormal.xyz);
vNormal.xyz = (vNewNormal.xyz * 0.5) + 0.5;
vNormal.w = 1.0; //Unused....

And in you source PointLight.frag

vec3 ExtractNormal(in vec4 vColor)
{
vec3 outnormal = (vColor.xyz * 2.0) - 1.0;
return normalize(outnormal);
}

You had this uncommented, so you probably used it (this way it will work) - so you probably know the background behind it. By the way you must normalize the result.

Second Way (reconstruct normals using dirty sqrt):
First lemme describe how sqrt works, in CPU it often works based upon Heron's method of finding square root - which is (source = wiki):
1.Begin with an arbitrary positive starting value x0 (the closer to the root, the better).
2.Let xn+1 be the average of xn and S / xn (using the arithmetic mean to approximate the geometric mean).
3.Repeat step 2 until the desired accuracy is achieved.


This is quite good approximation, although GPUs are doing it somehow differently (they have worse precision, much worse). If you also count with float imprecision on GPUs, you'll find you that it can return NaNs (Not a Numbers).

So what is causing the problem?
This:

outnormal.z = sqrt(1.0 - (outnormal.x*outnormal.x) - (outnormal.y*outnormal.y));

Count with me, let me show you how can this work:

// What if outnormal.x * outnomal.x + outnorma.y * outnormal.y > 1.0 (F.e. 1.00010001000100010001)
// Accordng to float number description it can be (due to its imprecision)
// Then
outnormal.z = sqrt(1.0 - 1.00010001000100010001);
outnormal.z = sqrt(-0.00010001000100010001);
outnormal.z = 0xffffffff; //or if you wish outnormal.z = NaN;
// And thus you get noise where this can happen


So how to fix it?
It is simple, just use absolute value on (-(outnormal.x*outnormal.x) - (outnormal.y*outnormal.y)) to avoid having negative number in sqrt, like this:

vec3 ExtractNormal(in vec4 vColor)
{
vec3 outnormal;
outnormal.xy = (vColor.xy * 2.0) - 1.0;
outnormal.z = sqrt(1.0 + abs(-(outnormal.x*outnormal.x) - (outnormal.y*outnormal.y)));
return normalize(outnormal);
}


Bam... and noise is away! There is also a solution through clamp or min, max functions which is faster (and probably more stable).

Although note, when you're storing normals in R8G8 (8-bit values) you're losing their precision ... use RGB10A2 target instead of RGBA8 target ;) inside glTexImage2D (while generating texture for framebuffer), like this:

glGenTextures(1, &mrt_buffer[1]);
glBindTexture(GL_TEXTURE_2D, mrt_buffer[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, (int)wndWidth, (int)wndHeight, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

Share this post


Link to post
Share on other sites
hi villem, seriously, did u fix it??I mean, DID U FIX IT??thx God ure there to help, but I just cant believe myself, please confirm. Did u really fix it and the noise gone??please I cant believe myself. I cant test the app now coz none of the PC HERE SUPPORT SHADER(damn old pc). U saw the noise??

Share this post


Link to post
Share on other sites
thx 4 ur time I'll rate u up. anyway, I cant test right now but I'll do at the next few days, its nice to get help from the one who knows better. phew, by that can I say that it ran fine on (all of) ur pc??it's relieving u know how to kill a bug in a code.

Share this post


Link to post
Share on other sites
@unbird: cant complain, I made it quick just to test my VBO compliant format. well the texture's taken from my lil sis pic(only the face). anyway, thx unbird for testing. I wish this thread could be useful for those experienced the same prblm as mine.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this