Sign in to follow this  

De-interlacing in a shader

This topic is 2842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to write a shader to de-interlace an image, but I'm not having much luck at all. First I tried calulating the current line the pixel is on by doing
float lineNo = round(imageSize.y * texCoord.y); // imageSize passed in

if (lineNo % 2 == 0)
{
    // process even lines
}
I've tried with lineNo as an int, and many other combinations on this theme but I always get double lines every 40 pixels or so. I thought it might be floating point errors building up to a point where they roll over, but I'm unsure. I then tried another approach which was with a second black and white stripey texture, the same size as the source and destination, and I look up into that texture as I do the look up into the source, and if this mask texture is black I dont draw that pixel, like this;
outColour  = tex2D(cameraImage, texCoord);
float4 maskColour = tex2D(mask, texCoord);
        
if ( maskColour.x < 0.1) // in case it's not quite 0.0
{
    outColour = maskColour; //float4(0.0, 1.0, 0.0, 1.0 );
}
However, I now get a grayscale ramping (which I can see if I just draw this mask to the screen) which looks like it's filtering. But I've set SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT ); SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT ); SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT ); SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_POINT ); in the code so I thought it should't be doing that? Any help appreciated, or feel free to suggest a new tried and tested technique. Cheers

Share this post


Link to post
Share on other sites
Is your texture and back buffer in the same size?
I test the sign of "frac(input.vpos.x * 0.5) - 0.1" to figure out current pixel is odd line or even line.
Or, you can use "fmod" function, but not something like "lineNo % 2". it's for integer.

Share this post


Link to post
Share on other sites
I'd be very interested in your work as I'm trying to come up with an hlsl deinterlacer as well but just haven't gotten around to it.. I would think you would need at least two images to do deinterlacing. Use the code below to decimate odd fields, but better yet would be to duplicate the even field pixel onto the odd field if the two pixel colors are outside of some distance threshold. I think this would remove sawtooth patterns at the cost of some vertical image resolution. Otherwise weave the odd/even fields together. This should bring back some of that vertical resolution and sharpen up the image.

Maybe this could help..


// Parameter
float2 TextureSize : register(C0);

// Sampler
sampler2D TexSampler : register(S0);

// Shader
float4 main(float2 texCoord : TEXCOORD) : COLOR
{
// Default color is fully transparent
float4 color = 0;

// Scale to int texture size
float row = texCoord.y * TextureSize.y * 0.5f;

// Calc diff between rounded half and half to get 0 or 0.5
float diff = round(row) - row;
float diffSq = diff * diff;

// Even or odd? Only even lines are sampled
if(diffSq < 0.1)
{
color = tex2D(TexSampler, texCoord);
}
return color;
}



Source: Read Between The Pixels - HLSL Kill Pixel Shader

Share this post


Link to post
Share on other sites

This topic is 2842 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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