bilinear filtering from sample point (not center of pixel)?
"Matt Franklin" <[email protected]> Tue, 16 May 2006 14:19:25 -0800
| Newsgroups | gmane.games.devel.opengl |
|---|---|
| Organization | Fat City Network Services, San Diego, California |
| Message-ID | <[email protected]> |
This is a rather long post. First, my question in brief: is there a way
to get GLSL's texture sample to return an interpolated value from the
specified texture coordinate, and NOT from the center of the destination
pixel?
I'm attempting to port a simple box filter from DirextX+HLSL to
OpenGL+GLSL. In the HLSL version, I sample four points: plus or minus
.5 from the center of the texel, along x and y. By sampling at the
corners of the texel, this allows me to exploit bilinear filtering to
essentially get four samples per sample. I then average the four points
together, and bingo-- box filter suitable for blurring. (I've enclosed
the shader at the end of this e-mail, in case that's clearer.)
The same technique is not working for me in GLSL. I'm using
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN/MAG_FILTER, GL_LINEAR) to
enable bilinear filtering, but it appears I need something further.
Here's the key bit of documentation:
"GL_LINEAR: Returns the weighted average of the four texture elements
that are closest to the center of the pixel being textured."
Well, there's the issue. My source and destination line up perfectly
(I'm not magnifying or minifying, and they aren't offset). Since the
center of the pixel being textured lines up perfectly with the texture,
it doesn't sample four texture elements-- it just samples one. When I
attempt to offset the sample point by .5, .5 (which should put me at the
corner of the texel), it simply point samples the next texel over!
Is there a way to prevent OpenGL/GLSL from "snapping" to the center of
the texel, and instead get it to interpolate appropriately? Or do I
need to manually implement the interpolation within my shader? It's not
that writing the full box filter with the 9 samples is difficult, but if
there's a more optimized method that's supported by OpenGL, I'd prefer
to use that.
GLSL SHADER:
The behavior of this shader is to point sample the current texel, the
texel next to it in the positive x direction, the texel next to it in
the positive y direction, and the texel diagonal from it in the positive
x, y.
uniform sampler2D tex0;
void main() {
const float2 cg_vPixelOffset[4] =
{
{-0.5, -0.5 }, { 0.5, -0.5 },
{-0.5, 0.5 }, { 0.5, 0.5 },
};
float4 vColor = 0;
for (int i = 0; i < 4; i++)
{
vColor += texture2D(tex0,
gl_TexCoord[0].st+cg_vPixelOffset[i]);
}
gl_FragColor = vColor * (1.0f / 4.0f);
}
-----
FAQ and OpenGL Resources at:
http://www.geocities.com/SiliconValley/Hills/9956/OpenGL
--
Author: Matt Franklin
INET: [email protected]
Fat City Hosting, San Diego, California -- http://www.fatcity.com
---------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: [email protected] (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).