Pixel Perfect

Started by
4 comments, last by Hodgman 10 years, 5 months ago

Hi,

Not sure if this counts as a beginner question or not. I apologise if it's in the wrong section.

I'm currently playing around with some deferred rendering. It seems to be working ok. I have directional and point lighting. I'm rendering the lights in to a render target and then using that to calculate the final stuff. But I think my projective co-ords are slightly off. If you look at the image below you'll see that at the geometry edge there's a white line. As though the lighting texture doesn't quite match up.

zco7nx9.png

The code I am using to build the projective co-ordinates is as follows:


//suv are the co-ords for tex2Dproj()
//invWidth is (0.5f / screen_width)
//invHeight is (0.5f / screen_height)

v2fout.p       = mul(a2vin.p, wvp);
v2fout.uv      = a2vin.uv;	
v2fout.suv     = v2fout.p;
v2fout.suv.xy  = float2(v2fout.suv.x * 0.5, -v2fout.suv.y * 0.5);
v2fout.suv.xy += (0.5 * v2fout.suv.w);
v2fout.suv.x  += 0.5f * invWidth * v2fout.suv.w;
v2fout.suv.y  += 0.5f * invHeight * v2fout.suv.w;

Thanks for any help/advice.

Advertisement

I honestly have no idea what's causing it, based only on what you've said here, but the first couple of things that spring to mind when seeing that kind of artifact are checking to see if the edge is blending with something it shouldn't (AA artifact) or possibly there's z-fighting, since that's at the far edge. Those are just stabs in the dark, though.

Could you give some more detailed information about the process you're using?

The correct forum for this kind of question is 'graphics programming'. (It's not a big deal, though.)

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
It looks like that part of the terrain is not in the lights volume frustum.

It looks to me like you're using some kind of antialiasing that doesn't support transparency.

If you didn't implement the AA yourself, maybe the graphics driver is doing it. NVIDIA Control Panel has an option to enable "Antialiasing - FXAA", and there's also an option called "Antialiasing - Transparency", in the "Manage 3D Settings" option. So either disabling the "Antialiasing - FXAA", or enabling the "Antialiasing - Transparency" will get rid of that white line (if it really is AA).

It looks to me like you're using some kind of antialiasing that doesn't support transparency.

If you didn't implement the AA yourself, maybe the graphics driver is doing it. NVIDIA Control Panel has an option to enable "Antialiasing - FXAA", and there's also an option called "Antialiasing - Transparency", in the "Manage 3D Settings" option. So either disabling the "Antialiasing - FXAA", or enabling the "Antialiasing - Transparency" will get rid of that white line (if it really is AA).

Not using any AA. I checked the driver settings and they're all set to application controlled. Apart from 'Gamma Correction' but it says that only affects GL.

It looks like that part of the terrain is not in the lights volume frustum.

Outside of the point light in that screenshot the rest is lit by a full-screen quad directional light.

I honestly have no idea what's causing it, based only on what you've said here, but the first couple of things that spring to mind when seeing that kind of artifact are checking to see if the edge is blending with something it shouldn't (AA artifact) or possibly there's z-fighting, since that's at the far edge. Those are just stabs in the dark, though.

Could you give some more detailed information about the process you're using?

The correct forum for this kind of question is 'graphics programming'. (It's not a big deal, though.)

It's not z-fighting. I'm not sure about the blending. The 'process' is pretty hacky as I'm still learning. Not sure what information you need but I'll try and elaborate.

I'm rendering position and normals in to an MRT. From that I'm rendering the lights to a render target. I then take the lighting render target and project it on to the geometry as a sort of, I dunno, screen space lightmap. I'm pretty sure it's the projective co-ordinates that are wrong. I've never understood the texel offset stuff in D3D9.

v2fout.suv.x  += 0.5f * invWidth * v2fout.suv.w;
v2fout.suv.y  += 0.5f * invHeight * v2fout.suv.w;
^^ Try changing *v2fout.suv.w to /v2fout.suv.w.
Or, try removing those lines from the vertex shader and adding these to the start of the pixel shader:
v2fin.suv.x  += 0.5f * invWidth;
v2fin.suv.y  += 0.5f * invHeight;
Also, what kind of sampler states are you using when reading from the MRT textures?

The problem could also be occurring not during your projective texturing step, but during your lighting step.
What steps/passes/stages do you follow when rendering your scene?
1) Draw geometry, outputting positions/normals to MRT.
2) read MRT and output lighting.
3) Draw geometry again, reading lighting.
?

D3D9's bug is described here:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690(v=vs.85).aspx
Basically, when doing stuff in screen-space, you always want to shift your texcoords down and right by half a pixel, OR shift your vertex positions up and left by half a pixel.

[edit]

//invWidth is (0.5f / screen_width)
//invHeight is (0.5f / screen_height)

If that's true, then 0.5*invHeight is actually 1/4th of a pixel, not half a pixel!

This topic is closed to new replies.

Advertisement