Controlling texture mipmaps

Everything related to 3D programming
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Controlling texture mipmaps

Post by mrw »

Hi,
I´m experimenting with OGRE and textures and I have problem getting mipmaps to work as I want.
Now I can´t find anything regarding mipmaps in the PB manual so I´m guessing this is configured completely in the material-scripts?
I know that if I set "filtering none" then there is no mipmaps. But if I set that value to anything else I don´t get the fullsize texture on closeups.
Or perhaps it is the correct but it gets blurred.
I have looked through the Material settings in the OGRE manual and there are lots of different settings, and I have tried lots of stuff but I still can´t fix the blurred closeup texture.

Does anyone have any experience in this?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

Hello,

If you're getting blurred textures up close then you either need higher resolution textures, or use UV scaling to get the texture to repeat itself over the mesh. Which gets more out of the texture you have without increasing resolution.
The UV scaling depends on the texture though because it doesn't work good in certain cases.

Also material filtering and mipmaps are two different things. The filtering is used to remove material aliasing problems at certain camera view points, and the mipmaps are used to allow different textures at certain distances.

In order to use mipmaps you need to use a material script with the commands lod_values and lod_index.
I believe I have an example of this lying around somewhere. If I can find it I'll post it later on when I have some free time.
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

Thanks for your reply!

Well, the texture is not blurred when I set "filtering none". It displays just as it should. But then I get the standard Moire patterns when the textured mesh gets further away and in greater number. That´s why I need to use mipmapping.
From OGREs website: http://www.ogre3d.org/docs/manual/manua ... #filtering it says: "No filtering or mipmapping is used" when setting "filtering none" so I would think that this setting definately has to do with mipmapping.

And if I set filtering to anything other than "none" I get blurred on closeup, so there must be other material options I need to configure for this to work.

If you can give me a working example of a material-script or PB code I would be very grateful!
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

You're right material filtering is using mipmaps. The reason your getting blur is because your textures are too low of resolution when up close with your current display.
Take for example a 512x512 texture up close and personal on a display of 1920x1080.
The material filtering would be working with texture elements of 512x512 and lower. Which with that big of a display your going to get blending because there aren't enough fragments to choose from. With filtering off it doesn't care and will just stretch the fragments across without trying to choose the correct element.

On the more technical side OGRE (on opengl side) is using glTexParameter under the hood to choose what type of filtering it wants.
If you where only using straight opengl you could tweak the filtering with glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); which should remove the nearest filtering, but keep the far in effect to remove the Moire effect you noticed. Problem is I'm not sure how safe it is to use opengl calls directly when using OGRE.

Which means you'll probably have to use material LOD in a script to have high resolution textures up close and lower resolutions ones when far away. Then you should be able to have material filtering on always without issue.

Also I found the example I was looking for, but it will need a little tweaking before I can post it.
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

Here's an example of material LOD in action.
Material LOD.zip

Just use the arrow keys to move the cube closer or farther away, and then you should see the texture changes. I made the textures quite a bit different from each other to make the effect more noticeable.
Right now I'm using a 1024x1024 texture for the nearest texture, but to make things even clearer you could go up to a 2048x2048 resolution. That or set up some UV scaling.

The PB code, material script, and textures are included in the download above, but I'll also post the code here for future reference.

Purebasic Code

Code: Select all

Enumeration
  #Window
  #Camera
  #Material
  #Mesh
  #Entity
EndEnumeration

If InitEngine3D(#PB_Engine3D_DebugLog) = 0
  End
EndIf
If InitSprite() = 0
  End
EndIf
If InitKeyboard() = 0
  End
EndIf
 
ExamineDesktops()
Define.i DesktopW = DesktopWidth(0)
Define.i DesktopH = DesktopHeight(0)

Define.d Z
Define.i Event
Define.i Quit

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "Material LOD")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)

    Add3DArchive("Textures", #PB_3DArchive_FileSystem)
    Add3DArchive("Scripts", #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    GetScriptMaterial(#Material, "Material_LOD")
    
    CreateCube(#Mesh, 10)
    CreateEntity(#Entity, MeshID(#Mesh), MaterialID(#Material))
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 0, 10, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)
    CameraBackColor(#Camera,RGB(20,20,20))
        
    Repeat
      Event = WindowEvent()
      
      If ExamineKeyboard()
        If KeyboardPushed(#PB_Key_Up)
          Z = -0.2
        ElseIf KeyboardPushed(#PB_Key_Down)
          Z = 0.2
        Else
          Z = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_Escape)
          Quit = 1
        EndIf
      EndIf

      MoveCamera(#Camera, 0, 0, Z, #PB_Relative)

      RenderWorld()
      FlipBuffers()

    Until Quit = 1 Or Event = #PB_Event_CloseWindow
  EndIf
EndIf
End
Material Script

Code: Select all

material Material_LOD
{
	lod_strategy Distance 
	lod_values 25 50
	technique near
	{
		lod_index 0
		pass
		{
			texture_unit
			{
				texture Marble1024.png
			}
		}
	}
	technique far
	{
		lod_index 1
		pass
		{
			texture_unit
			{
				texture Marble512.png
			}
		}
	}
	technique distant
	{
		lod_index 2
		pass
		{
			texture_unit
			{
				texture Marble256.png
			}
		}
	}
}
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

Nice!
Excellent example of controlling mipmaps.

But your example handles the mipmap generation manually and I would like for OGRE to handle that, without me providing several versions of the texture. If possible?
And yes my texture image is really small but since it looks fine up close to about a distance of 8 or so I would like to keep that and more focus on what happens after that distance.
Using your example I created this materialfile(with some lighting options removed to shrink it abit):

Code: Select all

material Mat1
{
    lod_strategy Distance
    lod_values 8  
    technique near
    {
        lod_index 0
        pass
        {
          texture_unit
          {
            texture tex1.png
            filtering none
          }
       }   
    }
    technique far
    {
        lod_index 1
        pass
        {
          texture_unit
          {
            texture tex1.png
            filtering trilinear
          }
       }   
    }
 }
And it sort of work as intended. To a distance of 8 the texture looks perfect. And after that it gets filtered.
The problem with this is that it is very obvious when textures reach the 8 distance and not as smooth as a want at all.

Is it possible to tweek this more to get more subtle changes to the filtering? without using several texturefiles?

Or, when thinking a bit more. What I think I want is to have automatic mipmap-generation done by OGRE without using any filtering(since filtering screws up my texture in closeup.)
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

Looking further through the docs it appears OGRE automatically generates mipmaps down to a 1x1 texture. You can cut this down by specifying how many mipmaps you want in the texture unit.
Example.

Code: Select all

          texture_unit
          {
            texture tex1.png 2d x
          }
X being the total amount of mipmaps for this texture. Not sure if that will help, but it's about all I could find on it.

One thing you could try is instead of using trilinear filtering is to use anisotropic with a low maximum value.
For example this is how your second texture unit would look.

Code: Select all

          texture_unit
          {
            texture tex1.png
            filtering anisotropic
            max_anisotropy 2
          }
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

I tried using anisotropic filtering but there is still a too defined line when ogre switches texture unit.

I have also googled lots about OGRE using mipmap without any filtering but I haven´t really found anything that definitive.
One thing I did find though is that apparently Minecraft uses mipmaps without filtering but to my knowledge Minecraft isnt´using any engine but straight OpenGL. And I also think that Minecraft generates the mipmap-images itself, which is not what I want..
But it tells me that mipmap without filtering is possible if using OGL but perhaps not in OGRE. It would be nice to have this solved ones and for all if this is supported or not.

And I know that I can use mipmaps without filtering in OGRE, as long as I create all the mipmap images myself and specifying "filtering none" in all texture units in the material.
But since OGRE can handle all the mipmap-generation itself it would be nice if it could do that when filtering is set to none.

Perhaps I should ask the official OGRE forum about this?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

mrw wrote: Perhaps I should ask the official OGRE forum about this?
You could try, but I wouldn't expect much out of it unless the feature you need is already implemented in OGRE.

One more possibility is to write your own code in Purebasic to auto generate the smaller textures and scripts needed to display them.
It would save on time in the long run and also allow you to only require one large texture because the smaller ones can be created and destroyed on the fly.
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

Yes, I thought about generating the textures from large and down to 1x1 on the fly, which would be pretty easy. But how can I enable these generated textures to become the mipmaps of a certain texture or material?

If I generated these "offline" I could easily just save lots of smaller imagefiles, and then just add these to the materialscripts. But that would be pretty ugly.

Or are you saying that I could create the materialscripts with all the imagefiles defined, but they wouldn´t exist until I create them and save them, before I parse the scripts?
Would that work? And then delete them when the program ends?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

mrw wrote: Or are you saying that I could create the materialscripts with all the imagefiles defined, but they wouldn´t exist until I create them and save them, before I parse the scripts?
Would that work? And then delete them when the program ends?
Yep, this will work, and if desired you can even create the material script in Purebasic because the script is just a text file.
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

Very interesting ideas.
But is it really a good idea to create lots of files and then delete them at the end? If the program crashes all those files would be there for all to see..
If I could skip the "save to disc" step it would be much cleaner.
Would this be possible to achieve?
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Controlling texture mipmaps

Post by Samuel »

Using just opengl or directx you can create a texture from an image in memory.
So, I'm positive OGRE would allow you to skip the disk write, but as far as I know Purebasic doesn't support it.
mrw
User
User
Posts: 76
Joined: Wed Dec 31, 2014 1:01 pm

Re: Controlling texture mipmaps

Post by mrw »

Just wanted to add that I "think" I solved my issue by using the complex format of the filtering option.
If I set it to "filtering point point point" I get automatic mipmapping and the texture is sharp up close.

This solutions seems too easy though and I think I´ve tried it before, but for some reason it works as I want now. :)
Post Reply