Problem with terrain texture filtering

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
mits
Posts: 8
Joined: Tue Jan 16, 2007 9:53 pm

Problem with terrain texture filtering

Post by mits »

I render the terrain using the IterrainSceneNode and doing the following:

Code: Select all


scene::ITerrainSceneNode *terrain = m_Smgr->addTerrainSceneNode("E:\\Program Files\\Mitsos\\irrlicht-1.2\\media\\terrain-heightmap.bmp");
	terrain->setScale(core::vector3df(30.0f, 1.5f, 30.0f));
	terrain->setMaterialFlag(video::EMF_LIGHTING, false);
	terrain->setMaterialFlag(video::EMF_BILINEAR_FILTER, true); 
	terrain->setMaterialTexture(0, m_Driver->getTexture("E:\\Program Files\\Mitsos\\irrlicht-1.2\\media\\texture-ground1.bmp"));
	terrain->setMaterialTexture(1, m_Driver->getTexture("E:\\Program Files\\Mitsos\\irrlicht-1.2\\media\\drygrass.bmp"));
	terrain->setMaterialTexture(2, m_Driver->getTexture("E:\\Program Files\\Mitsos\\irrlicht-1.2\\media\\terrain-heightmap.bmp"));
	terrain->setMaterialTexture(3, m_Driver->getTexture("E:\\Program Files\\Mitsos\\irrlicht-1.2\\media\\texture-ground1_detail_map.bmp"));
	terrain->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);



The newMaterialType1 is a HLSL shader material in which I do a texture blending of the two first textures and then I apply the detailmap. So far, everything seems surprisingly good. But I have problem in texture filtering because it looks like it is pointsampled. I have enabled the bilinear filtering but it seems that it doesn't work. I read in another post that it might be a bug. Any thought?
Thanks.
mits
Posts: 8
Joined: Tue Jan 16, 2007 9:53 pm

Post by mits »

I forgot to upload two screenshots which show the pixelated terrain.
Thanks again.

http://www.geocities.com/gabrielk42/Pos ... rrain1.JPG
http://www.geocities.com/gabrielk42/Pos ... rrain2.JPG
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

looks pretty good, but i see the pixelation. is this the same shader from your other post??
Image
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

When I complained about this issue I was told that "texture support isn't complete". When you set bilinear filtering Irrlicht isn't setting all four texture units to bilinear.

Seems that when Irrlicht went from 2 to 4 texture units noone bothered to add code to actually update the extra two units.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

This problem has been fixed for some month now, and it's in Irrlicht 1.2 so what are you complaining about?
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

hybrid wrote:This problem has been fixed for some month now, and it's in Irrlicht 1.2 so what are you complaining about?
1. If that's so then why is this poster seeing point filtering?

2. So, since I raised the issue someone has gone through the OpenGL, D3D8 and D3D9 drivers and made sure all four texture units are updated? Then why is the texture matrix only set for the first two units then in D3D9 (svn 424)? There isn't even enums in E_TRANSFORMATION_STATE for the third and fourth texture matrix.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Well, I don't think this issue has anything to do with the texture filtering mode, but by all means, continue the argument :D ( maybe it does )

Anyways, can you make available the textures you're using and the shader code you ended up with. It looks similar to when you do vertex based lighting/shading rather than pixel based lighting/shading.
Image
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

I just looked at the code and it's wrong for DX9. The only way it doesn't use pointer filtering is if trilinear filtering is enabling. Whomever has changed that code recently bothced it a bit. As far as I know, Anisotropic Filtering > Trilinear Filtering > Bilinear Filtering > Point Filtering. So if Aniso filtering is TRUE, the ( min, mag and mip ) filters should be setup for aniso filtering, but the code does not represent that at all. The code for the D3DSAMP_MIPFILTER has been like that for a long time, wonder how it hasn't been screwing so many other things up.
Image
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I'm pretty sure it is right as is.

Code: Select all

              | MIN         MAG         MIP
----------------------------------------------
Bilinear      | LINEAR      LINEAR      POINT
Trilinear     | LINEAR      LINEAR      LINEAR
Anisotropic   | ANISOTROPIC ANISOTROPIC LINEAR
Of course the code isn't very readable as it currently is, but it appears that it does set the sampler states correctly.

Travis
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

sio2 wrote: 1. If that's so then why is this poster seeing point filtering?

2. So, since I raised the issue someone has gone through the OpenGL, D3D8 and D3D9 drivers and made sure all four texture units are updated? Then why is the texture matrix only set for the first two units then in D3D9 (svn 424)? There isn't even enums in E_TRANSFORMATION_STATE for the third and fourth texture matrix.
1. Might be due to Shader stuff. The fixed pipeline works.
2. All states were updated for all four textures in Irrlicht 1.2. The texture matrix thing was changed in later revisions, and this is not yet finished. But it hopefully will be done for the next release.
mits
Posts: 8
Joined: Tue Jan 16, 2007 9:53 pm

Post by mits »

To Spintz : Yes it's the same shader code from my other post. It occured to me that it might be a filtering problem, I am not quite sure about that. The code is here :

Code: Select all


float4x4 matViewProjection;

struct VS_INPUT
{
   float4 Position : POSITION0;
   float2 inTxr1 : TEXCOORD0;
   
};

struct VS_OUTPUT
{
   float4 Position : POSITION0;
   float2 inTxr1 : TEXCOORD0;
};

VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;

   Output.Position = mul( Input.Position, matViewProjection );
   Output.inTxr1 = Input.inTxr1;
   
   return( Output );
}



// The constants
float minHeight1 = 0.0f;
float maxHeight1 = 0.7f;
float minHeight2 = 0.3f;
float maxHeight2 = 1.0f;
 
// Calculate percentage1
float Percentage1(float height, float minHeight, float maxHeight)
{
   // The percentage
   float p = 0.0f;
   
   // Check to see if it's in the boundaries
   if(height<=maxHeight)
   {
      // Calculate percentage
      p = 1.0f - (height/(maxHeight - minHeight));
   }
   
   // Return it
   return p;
}
   
     
// Calculate percentage2
float Percentage2(float height, float minHeight, float maxHeight)
{
   // The percentage
   float p = 0.0f;
   
   // Check to see if it's in the boundaries
   if(height>=minHeight)
   {
      // Calculate percentage
      p = (height - minHeight)/(maxHeight - minHeight);
   }
   
   // Return it
   return p;
}

// Ground texture
sampler Texture0 : register(s0) 
{
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

// Grass texture
sampler Texture1 : register(s1)
{
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

// Heightmap texture
sampler Texture2 : register(s2)
{
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

float4 ps_main(float2 inTxr1 : TEXCOORD0) : COLOR0
{   
   // Get the height from heightmap
   float height = tex2D(Texture2, inTxr1).x;
   
   // The percentages
   float p1 = Percentage1(height, minHeight1, maxHeight1);
   float p2 = Percentage2(height, minHeight2, maxHeight2);
   
   return clamp( (p1 * tex2D(Texture0, inTxr1)) + (p2 * tex2D(Texture1, inTxr1)), 0, 1);
} 

The ground and grass images are both 1024x1024. I am not at home, so I don't have them with me but when I get there, I'll send them. Thanks.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

vitek wrote:I'm pretty sure it is right as is.

Code: Select all

              | MIN         MAG         MIP
----------------------------------------------
Bilinear      | LINEAR      LINEAR      POINT
Trilinear     | LINEAR      LINEAR      LINEAR
Anisotropic   | ANISOTROPIC ANISOTROPIC LINEAR
Of course the code isn't very readable as it currently is, but it appears that it does set the sampler states correctly.

Travis
There's another issue I've previously mentioned. If you set, for example, "Trilinear" and the hardware only supports max. bilinear then the results are undefined (as you're setting state that's not supported).

I posted a minor fix for this some weeks back, but it only solved a portion of the issue (don't know if it was integrated into svn). Better is to have a little table that can be filled in once (constructor, say) via a caps check - if the HW can't do "trilinear" then fill it with "bilinear" state, then do a table lookup when state needs to be set.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

mits wrote:To Spintz : Yes it's the same shader code from my other post. It occured to me that it might be a filtering problem, I am not quite sure about that. The code is here :

Code: Select all


float4x4 matViewProjection;

struct VS_INPUT
{
   float4 Position : POSITION0;
   float2 inTxr1 : TEXCOORD0;
   
};


// Ground texture
sampler Texture0 : register(s0) 
{
   MIPFILTER = LINEAR;
   MAGFILTER = LINEAR;
   MINFILTER = LINEAR;
};

The ground and grass images are both 1024x1024. I am not at home, so I don't have them with me but when I get there, I'll send them. Thanks.
Irrlicht's vertex format has float3 for the POSITION semantic. Safer to have...

Code: Select all

"float3 Position : POSITION0;"
...and...

Code: Select all

Output.Position = mul( float4(Input.Position,1), matViewProjection );
to ensure that the W component is 1 (you will have issues if it's not 1).

You have filtering state in your samplers but Irrlicht sets filtering state too based on material settings. Anyway, you're setting trilinear - what if the hw doesn't support trilinear? This may be a minor point but it's something to keep it mind.

To see if filtering is the issue you could try reordering the textures/samplers - if a different layer looks point filtered then you know it may be a filtering issue.
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

hybrid wrote: 1. Might be due to Shader stuff. The fixed pipeline works.
2. All states were updated for all four textures in Irrlicht 1.2. The texture matrix thing was changed in later revisions, and this is not yet finished. But it hopefully will be done for the next release.
I think 2. might be incorrect. I just opened up the 1.2 source and looked at CD3D9Driver.cpp. There's a few places where all four aren't being updated. It looks to me that filtering state is only being set for the first two texture units, which would explain the issues of the original poster. I redownload the official 1.2 SDK to make sure I'd got a good copy.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, you're right sio2. It was revision 338 which was later than the last SDK release. I thought that I fixed it earlier, but that was only OpenGL state fixing. Sorry. It feels so far away already.
So the following patch file might help
http://irrlicht.svn.sourceforge.net/vie ... view=patch
The other fix mentioned was applied in revision 324 which you might also want to add in case you have problems with anisotropic filtering.
So DirectX will probably mess up everything if you enable a feature that is not supported? That's what I call a good design :roll: OpenGL has a pretty deterministic behavior for such cases with well-defined states. That makes it somewhat slower, but much more reliable...
Post Reply