PDA

View Full Version : perfect screen quad aligned and GL_NEAREST



qnext
09-05-2013, 02:27 PM
Hi,

I am trying to improve my yuv->rgb convert .. Now I only draw quad (scaled, rotate, ..) in my scene with a texture with GL_NEAREST, GL_CLAMP_TO_EDGE and a shader that do yuv->rgb and the bilinear filtering.
but it seems it's not perfect.

It's perhaps better to render a screen aligned quad in an fbo with GL_NEAREST with a basic yuv->rgb shader, then render use the texture of the fbo in RGB space.

What is the exact correct definition (hardware independant) of a a screen aligned quad ? Do I need to use GL_CLAMP_TO_EDGE (it seems that texture is not exactly from 0.0 to 1.0) ?

Dark Photon
09-05-2013, 04:22 PM
Assuming you're using a half-recent version of GL, just use texelFetch (http://www.opengl.org/sdk/docs/manglsl/xhtml/texelFetch.xml) and then forget about the sampling and filtering details. Just pass in the integer coordinates of your current fragment and be done with it:


texelFetch( tex, ivec2( gl_FragCoord.xy ), 0 );


If this is an older OpenGL (pre-texelFetch), then you can still do it just fine with GL_NEAREST 0..1 quad (then CLAMP_TO_EDGE is fine but not needed). Just remember that for texcoords, 0 and 1 are coords of "texel edges", but the texcoords of texel "centers" should be done for the lookup (cell-centered data). So for instance if your texture is NxN, and you wanted to know the texcoords of the center of the Ith texel (I in 0..N-1), then its texcoord is: (I+0.5)/N.

GClements
09-05-2013, 04:48 PM
Another option is to use textureGather() to obtain one component from each of the 4 texels surrounding the specified texture coordinates, convert the data to RGB, then interpolate. E.g. (untested):


vec3 textureYUV(sampler2D sampler, vec2 p)
{
vec4 y = textureGather(sampler, p, 0);
vec4 u = textureGather(sampler, p, 1);
vec4 v = textureGather(sampler, p, 2);
vec4 r = y + 1.14 * v;
vec4 g = y - 0.39 * u - 0.58 * v;
vec4 b = y + 2.03 * u;
vec3 c10 = vec3(r[0], g[0], b[0]);
vec3 c11 = vec3(r[1], g[1], b[1]);
vec3 c01 = vec3(r[2], g[2], b[2]);
vec3 c00 = vec3(r[3], g[3], b[3]);
vec3 c0 = mix(c00, c01, p.s);
vec3 c1 = mix(c10, c11, p.s);
return mix(c0, c1, p.t);
}

qnext
09-06-2013, 02:26 AM
If I understand correctly : texelFetch bypass any filtering,works in non normalized texture coordinate ? In this case, I need to render a quad aligned without bilinear filtering ?
In this case I need to do that ?
create fbo of the yuv420 texture size
glviewport (texture size)
glortho(0,0,widthTexture,heightTexture)
drawopenglquad (size of the texture) ?
and use texelfetch with basic yuv->rgb and no bilinear filtering

Is it correct ?

thokra
09-06-2013, 03:20 AM
The OpenGL Shading Language texel fetch functions provide the ability to extract a single texel from a specified texture image. The integer coordinates passed to the texel fetch functions are used as the texel coordinates (i, j, k) into the texture image. This in turn means the texture image is point-sampled (no filtering is performed), but the remaining steps of texture access (described below) are still applied.

For what you want, texelFetches are perfect. Otherwise use Dark Photons approach. I can't speak to GClement's suggestions, however, without more background on the conversion you're doing.

GClements
09-06-2013, 08:17 AM
If I understand correctly : texelFetch bypass any filtering,works in non normalized texture coordinate ? In this case, I need to render a quad aligned without bilinear filtering ?
texelFetch() doesn't perform any filtering, interpolation or mipmap selection. You pass in integer texture coordinates and a mipmap level, and it returns the requested texel.

How you use that is up to you. One option is to render a same-size, aligned rectangle to produce a 1:1 copy, but in RGB rather than YUV. Another option is to perform the conversion as you render the final polygons, implementing the texture filtering logic in the shader. The latter option requires more processing but less memory bandwidth.

thokra
09-06-2013, 08:31 AM
You pass in integer texture coordinates and a mipmap level

... except in the case of a buffer textures, texture rectangle, or multisampling samplers. These have no mipmaps.