Image Sharpness in TextureMapping

Hi…
I am working as a programmer for a software company that targets Textile Industry. We are currently in the developement of a 3D software which uses OpenGL techniques, specially Texture Mapping using NURBS surfaces.
When I map a texture image (Normally a .bmp file which gets converted to openGL format)the image details are blured. i.e. mapped image is not as sharp as the original one.
Which is not the desired output.
Also user can’t explicitely set the repeat factor while mapping.
We are using these openGL features on Windows platform and with VC++ 6.0 MFC tools.
Kindly do the needful

Thanking you.
-Ankit

If you dont have to rescale the original image, and if you show it in the same size in opengl then you shoudnt have any difference ( oh yea, turn off linear filter in that comparison)

Whats probably happens is that you get a lower mipmap level than you want, and that can be adjusted with some LOD extension (cant remember the exact name)

Thank you Mazy for your reply…
but resizing is there also I have tried to turn off the linear filter but in some cases image gets distorted after mapping.
Can you please describe in detail about “lower mipmap level”

Originally posted by Mazy:
[b]If you dont have to rescale the original image, and if you show it in the same size in opengl then you shoudnt have any difference ( oh yea, turn off linear filter in that comparison)

Whats probably happens is that you get a lower mipmap level than you want, and that can be adjusted with some LOD extension (cant remember the exact name)[/b]

first… are you using Mipmaps?
and second, does it get more distorted when you look at it from the side, and less when youre looking right on it?

If you use mipmaps (e.g. if you use gluBuild2DMipmaps), OpenGL will automatically chose a mipmap level that best fits the image scaling required to represent the image on the screen.

The concept of mipmaps is basically this: You have an original, full sized, image, which is called mipmap level 0 (zero). Subsequent mipmap levels (1,2, etc) are filtered and scaled versions of the previous mipmap level. The scaleing factor between two mipmap levels is 2, so for instance if your original image (level 0) is 1024x1024, then level 1 is 512x512. There are always enough mipmap levels to get down to 1x1. In this case, there would be 11 mipmap levels (0 to 10).

Now, as I said earlier, OpenGL automatically selects the mipmap level that best fits the size on the screen. For instance, if you draw your texture on the screen so that it covers an area of about 500x500 pixels, mipmap level 1 will be selected (if the original image is 1024x1024). This is of course a simplification of the truth. Depending on the minification filtering method you choose, OpenGL may interpolate between different mipmap levels and even use several different mipmap levels (e.g. if you are looking at the texture from the side instead of from the front).

So - to the real question: why does it look more blurry? As I said, each mipmap level is a filtered version of its “parent” mipmap level. In other words, it has been low-pass filtered (similar to the “blur” effect in most image manipulation programs), and then downsampled. This means that smaller mipmaps have a lower level of detail than larger mipmaps.

I am using mipmapping in texture mapping. For your reference I m giving piece of code where I m using these functions.

::glEnable( GL_TEXTURE_2D );
::glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

//Following two lines are replacememnt of Linear Filter
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST );

::glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );//…16

// Generate a series of texture maps of decreasing size
::gluBuild2DMipmaps( GL_TEXTURE_2D, 3,
m_pRGBImage->sizeX, m_pRGBImage->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, m_pRGBImage->data );

With above code lines Image gets distorted when we look from side. However this reduses bluredness.

Now as per your guidance on Mipmap levels, we can conclude that as level gets increased, depending upon the filtering
openGl interpolates between mipmap levels (Here it may not interpolate).
So, finally we can say with linear filter, if mipmap level is not 0 then image get blured.
But Can I reduce this blurdness by-
1> Selecting low resolution image as texture
2> Selecting as small image as possible …??
Does these factors affect the image details?

Also if I use
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT );
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT );
can I control repeat factor of mapped Image? i.e . Instead of allowing OpenGL to repeat the texture, can I specify
the repeat value and depending upon this value the texture get repeated?

Thanks…
Regards
Ankit

Now as per your guidance on Mipmap levels, we can conclude that as level gets increased, depending upon the filtering
openGl interpolates between mipmap levels (Here it may not interpolate).

Correct. In your case (NEAREST_MIPMAP_NEAREST), OpenGL will not interpolate between mipmap levels. For the best result you should use LINEAR_MIPMAP_LINEAR. The image sharpness should not be affected. Well - in a way it will, but NEAREST_MIPMAP_NEAREST results in spatial aliasing (e.g. similar to what you get if you play back 8 KHz sound samples without analog filtering or digital interpolation - it sounds “pitchier”, but ugly).

So, finally we can say with linear filter, if mipmap level is not 0 then image get blured.

It will get blured even without linear filtering. It’s a result of the mipmap generation (as I said in the previous post, each mipmap level is a blured version of its parent mipmap).

But Can I reduce this blurdness by-
1> Selecting low resolution image as texture
2> Selecting as small image as possible …??

No, not really. The only thing you can do is:

  1. Make sure that your original image (level 0) is a sharp image (not just an upsampled version of a smaller image, or a fuzzy photo, for instance)

  2. Use a high resolution display. When OpenGL selects which mipmaps to use for rendering, it does not care about the apparant size on the screen (in centimeters or whatever), but only about how many pixels are used for displaying the texture. In other words, higher resolution display => more pixels per texture => bigger mipmap level => sharper image.

Instead of allowing OpenGL to repeat the texture, can I specify
the repeat value and depending upon this value the texture get repeated?

Not that I know of (except if there is some odd extension for handling this). The best level of control is that you can select repeat for one dimension (S or T) but not for the other dimension, if that helps. Otherwise it’s no repeat or infinite repeat.

[This message has been edited by marcus256 (edited 02-05-2003).]

Hi,

You can use scaling in the texture matrix to control the repeating. Like this:

glMatrixMode(GL_TEXTURE);
glScalef(s, s, s);

The bigger the scaling factor s, the more your texture gets repeated.

On some hardware you can use anisotropic filtering to reduce the blurriness. I think the extension is EXT_texture_filter_anisotropic, unless it’s part of the main spec by now. Never used it myself, but it should help in this case. Another thing is to use fullscreen antialiasing, that can also help with the blurriness since the colors get sampled from a more accurate mipmap.

-Ilkka