Even/odd pixels (parity) in pixel shader

Started by
7 comments, last by Numsgil 12 years, 7 months ago
I'm working on a shader-level antialiasing scheme, and to make it work I need to determine if a given pixel is "even" or "odd" in the pixel shader.

I thought I could be clever about it and store the "pixel space" position of a vertex in the vertex shader, and I'd get back basically integer coordinates in the pixel shader because of the way that vertex values get interpolated when pixels get sampled. But that doesn't seem to be true (I wrote up a quick test shader and there's a lot of noise in the fractional component of the interpolated pixel position). Which gives me unintended even/odd artifacts.

Just wondering if anyone has any clever ways to actually do this, if I was on the right track storing off the pixel space position of vertices, etc.
[size=2]Darwinbots - [size=2]Artificial life simulation
Advertisement

I'm working on a shader-level antialiasing scheme, and to make it work I need to determine if a given pixel is "even" or "odd" in the pixel shader.

I thought I could be clever about it and store the "pixel space" position of a vertex in the vertex shader, and I'd get back basically integer coordinates in the pixel shader because of the way that vertex values get interpolated when pixels get sampled. But that doesn't seem to be true (I wrote up a quick test shader and there's a lot of noise in the fractional component of the interpolated pixel position). Which gives me unintended even/odd artifacts.

Just wondering if anyone has any clever ways to actually do this, if I was on the right track storing off the pixel space position of vertices, etc.


Hi,


If you are using SM4.0 level you can get the integer position automatically by casting the SV_Position (under D3D) variable to int.

Cheers!
The VPOS semantic in SM3 seems to do what I want, and it seems to return integers with no noise in the fraction. Which is great! But I'm trying to support SM2 if I can get away with it.

Has anyone had any experience faking VPOS in SM2?
[size=2]Darwinbots - [size=2]Artificial life simulation

I'm working on a shader-level antialiasing scheme, and to make it work I need to determine if a given pixel is "even" or "odd" in the pixel shader.

I thought I could be clever about it and store the "pixel space" position of a vertex in the vertex shader, and I'd get back basically integer coordinates in the pixel shader because of the way that vertex values get interpolated when pixels get sampled. But that doesn't seem to be true (I wrote up a quick test shader and there's a lot of noise in the fractional component of the interpolated pixel position). Which gives me unintended even/odd artifacts.

Just wondering if anyone has any clever ways to actually do this, if I was on the right track storing off the pixel space position of vertices, etc.


I use the pixel position to generate a stipple pattern and describes it over here.
what about

vec2 screencoord; //[0, 1]
vec2 odd = mod(screencoord * screensize, 2.);

and then do something like odd < 1 for even and so on
This is basically what I'm doing (or want to do) in the pixel shader for my test:


float2 parity = round(PixelPosition_PS) % 2
return colors[parity.x * 2 + parity.y];


The idea being to generate a "plaid" pattern for pixels that are drawn as a proof-of-concept that I can do something different for even/odd pixels.

This almost works, but I get artifacts where it loses track of what's even and what's odd. The most obvious ones are something like: even odd even odd even even odd even odd even odd, etc. That is, it sort of skips an even/odd pair. There are other artifacts where an arbitrary diagonal-y line of pixels has the pattern interrupted.

This explains better with screen grabs so I'll try to post some later tonight.

If I instead draw out the "error" (that is, the distance from integer coordinates for sampled pixel positions), I see some interesting patterns. If the render target size is a multiple of 2 it's a fairly regular pattern in a square grid, but non power of 2 sizes result in much noisier signals. Again, a picture explains this way better so I'll post some tonight.

If I use VPOS and SM3 instead of my interpolated pixel position, all the artifacts disappear, so I'm fairly certain my pixel shader is working correctly. I'm fairly sure the root of this issue is the inaccuracy of interpolation before things get sent to the pixel shader. But I'm also only interested in the alternating even/odd pattern of the pixels, so I'm wondering if there's a clever away around this problem.
[size=2]Darwinbots - [size=2]Artificial life simulation
Could try something like:

pixel = 1 / ViewportSize;
parity = (coord / pixel) % 2;

But if your running into an accuracy issue that could potentially make it worse.
You can't interpolate pixel position with a perspective projection. You can do it if you disable perpective-correct interpolation, but you can only do that in SM4.0+. What you can interpolate is your clip-space vertex position (basically the same float4 value that you output as POSITION from the vertex shader), then in your pixel shader you can do the homogeneous divide-by-w and then apply the viewport transform to get pixel position.

You can't interpolate pixel position with a perspective projection. You can do it if you disable perpective-correct interpolation, but you can only do that in SM4.0+. What you can interpolate is your clip-space vertex position (basically the same float4 value that you output as POSITION from the vertex shader), then in your pixel shader you can do the homogeneous divide-by-w and then apply the viewport transform to get pixel position.


I should mention that this is all in 2D, so my Projection matrix is basically diagonal (so I guess it's closer to an orthogonal projection than perspective).

...

Anyway, as I promised here's the artifacts I'm seeing. Similar to Z fighting, the pattern changes if you scale/rotate, etc. the elements. Which is why I think it's an issue with interpolation accuracy. Apologies if the artifact is hard to see. (Definitely click on the pictures so you can actually see the "plaid" pattern. The preview thumbnails just show green). Using the "magnifier" in windows helps out a lot here.
[attachment=5322:Artificat.Png]
[attachment=5323:Artifact2.png]

If I set any pixels that have an "error" (non 0 fractional component) greater than 0.1 to white, I get this (though I'm not entirely sure I'm doing it right since it doesn't seem to match up 100% with the artifacts I mentioned earilier).
[attachment=5324:Error.png]

At this point I've sort of resigned myself to Shader Model 3, since the artifacts go away with it, but if anyone has any ideas I'm all ears :)
[size=2]Darwinbots - [size=2]Artificial life simulation

This topic is closed to new replies.

Advertisement