Jump to content
  • Advertisement
Sign in to follow this  
RichPressence

OpenGL pixel offset after rendering to fbo?

This topic is 507 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

Hey, when I render the screen to an offscreen buffer for downsampling or storage for later it gets offset.

I noticed it when I was writing a wide radius bloom shader as the offset increased after every downsample and blur making it more and more noticeable.

 

im using opengl and have GL_LINEAR enabled for the offscreen buffer and the viewport size is 1024x1024 with the offscreen buffer matching that.

Shouldnt the offscreen buffer match the main exactly pixel for pixel if its not being resized or is this a side effect of using gl_linear?.

 

Heres the frag but it just passes through the color which gets sent to the next pass as an input.

uniform sampler2D ColorTexture;
uniform vec2 buffer_res;

vec2 texel = 1.0 / buffer_res;
vec2 texCoord = gl_TexCoord[0].xy;

void main() {
    // with this the offset pushes out from the center rather than off to the top right corner
    // but is still getting offset
    texCoord += vec2(0.5, 0.5) * texel;

    gl_FragColor.rgb = textureLod(bgl_RenderedTexture, texCoord, 0).rgb;
}

The images are crops from 1024x1024

Share this post


Link to post
Share on other sites
Advertisement

AFAIK, you're fighting a losing battle trying to get pixel perfect results with GL_LINEAR in OpenGL.

DirectX9 guaranteed you could do it by rendering at the right size with a half-pixel offset, but I think with OpenGL you just have to avoid bi-linear filtering.

Note, I'm not 100% confident in that assertion, so very happy to be corrected.

Share this post


Link to post
Share on other sites
Try this.

vec2 res = textureSize(bgl_RenderedTexture, 0);
texCoord = texCoord * (res / (res + 1.0)) + (0.5 / res);
Untested!

Share this post


Link to post
Share on other sites

How do you set up your vertex coordinates, your texture coordinates, your modelviewprojection matrix? In any case, interpolation free rendering using GL_LINEAR is definitely possible.

Share this post


Link to post
Share on other sites

Shouldnt the offscreen buffer match the main exactly pixel for pixel if its not being resized
Yep, assuming your geometry is correct. What do your vertices look like?

Note, I'm not 100% confident in that assertion, so very happy to be corrected.
OpenGL and D3D10+ should have no problem with this.
D3D9 uses a stupid coordinate system that requires a half-pixel offset to do this correctly. 

Share this post


Link to post
Share on other sites

If your goal is just to make a copy, why not use GL_NEAREST?


L. Spiro

While GL_NEAREST might theoretically be faster, there's nothing wrong with trying to get it right with GL_LINEAR first. GL_NEAREST might hide a scaling mistake which could also show up with GL_NEAREST for some target sizes. With GL_LINEAR it will show up as slight blurriness for all target sizes.

Share this post


Link to post
Share on other sites

Thanks for the replys guys. Seems I was doing a number of things poorly, one being how I was dividing my fbos down from my target res, im dividing and rounding now instead of div and flooring, they stay pretty square now at lower mips.

The other problem was with the fbo getting offset by 1 pixel towards the top right corner even if the res matched the main buffer.

Using this for the coords in my fbo frags when upsampling/downsampling stopped them getting offset.

uniform ivec2 buffer_res;
ivec2 intCoord = ivec2(gl_FragCoord.xy);
vec2 texCoord = vec2(intCoord + 0.5) / buffer_res;

Wouldn't surprise me its not completely bang on still need todo more checking I think.

 

If your goal is just to make a copy, why not use GL_NEAREST?


L. Spiro

Well I was doing this for a bloom shader and im heart set on making use of the linearly sampled gaussian blur trick to get some free taps which requires the use of gl_linear. But yeah for a straight full res copy I think gl_nearest would be best.

 

@Hodgman Yeah I originally thought the half pixel offset thing was the battle I was fighting till I found its a d3d9 thing.

 

before and now

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!