PDA

View Full Version : weird shader behavior



shelll
01-24-2006, 03:16 AM
this is my simple shader used for reductions, which works ok:


#define GL_ARB_texture_rectangle 1;
uniform sampler2DRect tex;
void main() {
vec4 data;
data.x = texture2DRect(tex, gl_TexCoord[0].st).x;
data.y = texture2DRect(tex, gl_TexCoord[0].st + vec2(-1.0, 0.0)).x;
data.z = texture2DRect(tex, gl_TexCoord[0].st + vec2(-1.0, -1.0)).x;
data.w = texture2DRect(tex, gl_TexCoord[0].st + vec2(0.0, -1.0)).x;
gl_FragColor.x = max(max(data.x, data.y), max(data.z, data.w));
}but first i used this shader:


#define GL_ARB_texture_rectangle 1;
uniform sampler2DRect tex;
void main() {
vec4 data;
data.x = texture2DRect(tex, gl_TexCoord[0].st).x;
data.y = texture2DRect(tex, gl_TexCoord[0].st - vec2(1.0, 0.0)).x;
data.z = texture2DRect(tex, gl_TexCoord[0].st - vec2(1.0, 1.0)).x;
data.w = texture2DRect(tex, gl_TexCoord[0].st - vec2(0.0, 1.0)).x;
gl_FragColor.x = max(max(data.x, data.y), max(data.z, data.w));
}which worked only in some cases, what is wierd :( and it should give the same results.

my first shader was this, which gave compleltly bad results, i don't know why :(


#define GL_ARB_texture_rectangle 1;
uniform sampler2DRect tex;
void main() {
vec4 data;
data.x = texture2DRect(tex, gl_TexCoord[0].st).x;
data.y = texture2DRect(tex, gl_TexCoord[0].st + vec2(1.0, 0.0)).x;
data.z = texture2DRect(tex, gl_TexCoord[0].st + vec2(1.0, 1.0)).x;
data.w = texture2DRect(tex, gl_TexCoord[0].st + vec2(0.0, 1.0)).x;
gl_FragColor.x = max(max(data.x, data.y), max(data.z, data.w));
}my rendering code for quad is like this:


glBegin(GL_QUADS);
glTexCoord2f(0.5f, 0.5f);
glVertex3f(0.0f, 0.0f, -0.5f);

glTexCoord2f(vWidth + 0.5f, 0.5f);
glVertex3f(vWidth >> 1, 0.0f, -0.5f);

glTexCoord2f(vWidth + 0.5f, vHeight + 0.5f);
glVertex3f(vWidth >> 1, vHeight >> 1, -0.5f);

glTexCoord2f(0.5f, vHeight + 0.5f);
glVertex3f(0.0f, vHeight >> 1, -0.5f);
glEnd();i have been experimenting with many different vertex and texture coordinates and shaders, but only current give me good results. i am especially curios about the difference between the 1st and the 2nd shader, which *must* gave same results, but do not.

gf6600gt, 81.85, xp sp2

shelll
01-26-2006, 02:48 AM
no one? any nvidia guy around to tell us why the first and second shader don't do the same? perhaps driver bug?

zed
01-26-2006, 10:28 PM
from my look its looks ok
the only thing is with texture rect u have to supply the actual texture dimensions for texture coords, where u have the 0.5 offset which looks suss (perhaps its ok?)

shelll
01-27-2006, 01:31 AM
opengl samples from center of texel, so first texel has coord (0.5f, 0.5f) and oposite corner has texcoords (width - 0.5f, height - 0.5f) so this should be ok

Relic
01-27-2006, 02:08 AM
I guess the original question is just a compiler bug. Check the assembly output to verify. Install newer drivers if available.

Right, OpenGL samples at texel centers, but you should not start the vertex on the corner of the pixel and the texture cooredinate at the center of the pixel, because the texcoord interpolation inside the fragment pipeline takes the interpolated coordinates at the pixels center to lookup the texture.
Means, when doing a 1-to-1 mapping of texels to pixels, the correct texture coordinates are (0,0) to (width,height) for a rectangle texture. The interpolation cares for the centering automatically.
Your code has shifted the texture by half a texel to the lower left during rendering and you're constantly sampling the texture on the razor edge between two texels, which might shift it a whole texel when doing nearest filtering.
You probably didn't notice, because you're mapping 4 texels to one pixel, but still the same inital texture coordinates apply.

And BTW, you didn't use (width - 0.5f, height - 0.5f) in your code either.

shelll
01-27-2006, 02:30 AM
according to this: correct texture coordinates (http://www.gpgpu.org/wiki/FAQ#What_do_correct_texture_coordinates_look_like. 3F) , we should use 0.5f and width - 0.5f

its true, that i didn't use width - 0.5f, because it produced bad results. i emplemented calculating maximam value in texture (single channle floating point texture) on GPU thorugh reductions (map 4 texels to 1 texel). i have seen some tutorialas and i have seen example implementation, but with that, the results were bad :( so i did som experiments and found the "correct shader and quad setup"

i will look at he assembly output ASAP.

Relic
01-27-2006, 02:49 AM
No, you misunderstood the GPGPU document.


The centers of OpenGL texels along the diagonal of a GL_TEXTURE_RECTANGLE_ARB are therefore(0.5, 0.5), (1.5, 1.5), (2.5, 2.5), etc. (To see this try writing WPOS to the output of a shader on a screen-aligned quad.) Is exactly what I said.

because the texcoord interpolation inside the fragment pipeline takes the interpolated coordinates at the pixels center to lookup the texture.

WPOS is the interpolated fragment (vertex) coordinate. OpenGL rasters at pixel centers, those are the above halves for a screen aligned quad.
If the vertex coordinates are given so that the resulting WPOS are 0.5, 1.5, etc. then the exact same applies for texture coordinates.

Means for 1-to-1 mapping of texels to pixels you must use the full range (0,0) to (width, height) for vertex and texture coordinates.

shelll
01-29-2006, 07:11 AM
i changed tex coords to zeros and width/hight and now both shaders do the same... but he third shader is still broken, but that is fine.

i have another problem, these shaders do bad things when width or height is 1 and when dimensions are 2x1 or 1x2 the result is always zero! :'( textures are clamped to edge, so there shouldn't be problem... should i write a 1D reduction shader for this case and switch to it when one dimension is 1?

Relic
01-29-2006, 11:06 PM
That's probably because you're not rendering anything.
If vWidth and vHeight are integers and either is 1, then vWidth >> 1 == 0 or vHeight >> 1 == 0.
See the zero area quad?


glBegin(GL_QUADS);
glVertex3f(0.0f, 0.0f, -0.5f);
glVertex3f(vWidth >> 1, 0.0f, -0.5f);
glVertex3f(vWidth >> 1, vHeight >> 1, -0.5f);
glVertex3f(0.0f, vHeight >> 1, -0.5f);
glEnd();You need to special case that and keep the right and/or top vertex coordinate constant at 1.0 for the input size which is < 2.

shelll
01-30-2006, 12:35 AM
thanks man :D my stupid mistake :(