smooth texture

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.
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

smooth texture

Post by Strong99 »

When you play games the blend between dirt and grass is made,
how do i create that effect with irrlicht ? i thought 3 layers but that
didn't worked, and to greate 1 big texture for the ground is a easy
but not nice for preformance.

you see here between the grass and the road
Image

and here:

Image
Aranoth
Posts: 4
Joined: Sun Nov 12, 2006 11:53 am
Location: France
Contact:

Post by Aranoth »

i thought 3 layers but that
didn't worked
Yep. It's 'blending'.

But I think it is only possible to do it with shaders
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Post by Strong99 »

how do you mean? how to do that in irrlicht?
Aranoth
Posts: 4
Joined: Sun Nov 12, 2006 11:53 am
Location: France
Contact:

Post by Aranoth »

Exemple : you have two textures :

Image Image

and a texture for blending :

Image

The result will be that :

Image

But I think it's impossible to do it just with Irrlicht, you must use shaders.
Saturn
Posts: 418
Joined: Mon Sep 25, 2006 5:58 pm

Post by Saturn »

If it is any help, this thread discusses how to do it in a shader.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

IrrSpintz had a TEXTURE_SPLAT material. It does NOT require shaders, this material I'm posting code for and the on in IrrSpintz simply texture splats a single texture with an alpha map, but the code could easily be modified to handle 2 textures and an alpha image.

here's the code for DX -

Code: Select all

//! material renderer to perform texture splatting
class CD3D9MaterialRenderer_TEXTURE_SPLAT : public CD3D9MaterialRenderer
{
public:

	CD3D9MaterialRenderer_TEXTURE_SPLAT(IDirect3DDevice9* p, video::IVideoDriver* d)
		: CD3D9MaterialRenderer(p, d) {}

	virtual void OnSetMaterial(SMaterial& material, const SMaterial& lastMaterial,
		bool resetAllRenderstates, IMaterialRendererServices* services) 
	{
		pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

		pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_CURRENT );

		pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}

	virtual void OnUnsetMaterial()
	{ 
		pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );

		pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
		pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR );
	}
};
and for OpenGL -

Code: Select all

class COpenGLMaterialRenderer_TEXTURE_SPLAT : public COpenGLMaterialRenderer
{
public:

	COpenGLMaterialRenderer_TEXTURE_SPLAT(video::COpenGLDriver* d)
		: COpenGLMaterialRenderer(d) {}

	virtual void OnSetMaterial(SMaterial& material, const SMaterial& lastMaterial,
		bool resetAllRenderstates, IMaterialRendererServices* services) 
	{
		Driver->disableTextures( 2 );

		if( Driver->queryFeature( EVDF_MULTITEXTURE ) )
		{
			Driver->extGlActiveTextureARB( GL_TEXTURE1_ARB );

			// texture
			glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE );
			glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
			glTexEnvf( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS );

			Driver->extGlActiveTextureARB( GL_TEXTURE0 );
		}

		// alpha map
		glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE );

		glEnable( GL_BLEND );
		glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}

	virtual void OnUnsetMaterial()
	{
		if( Driver->queryFeature( EVDF_MULTITEXTURE ) )
		{
			Driver->extGlActiveTextureARB( GL_TEXTURE1 );
			glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
			glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
			glTexEnvf( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE );

			Driver->extGlActiveTextureARB( GL_TEXTURE0 );
		}

		glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE );

		glDisable( GL_BLEND );
		glBlendFunc( GL_ONE, GL_ZERO );
	}
};
If you need help with understanding this, just let me know...
Image
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Post by Strong99 »

what do you mean with splats?

couldn't i use alpha mapping, 1 first teture with an alpha map and the 3rd texture as other?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The SOLID_2_LAYER material should work. It takes the first texture as the main texture and blends the second based on the alpha value of the vertices.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

SOLID_2_LAYER will not provide smooth blending because the alpha values will just change in steps at a vertex, not smooth as can be achieved with an alpha texture.

Texture Splatting is a more proper term, because blending can refer to other things as well. But that just terminology, the concept is the same here.

What you're describing is the 1st texture as a base texture. Then you want to get the alpha from the 2nd texture and use that alpha to blend the 3rd texture with the 1st texture, right?
Image
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Post by Strong99 »

yes, that
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Now that I think about this, I think it can only be done in DirectX in the Fixed Function Pipeline, to do this in OpenGL, you'll probably need shaders.

This is because in the DX fixed function pipeline, you can save the results of a texture stages operations to a temp register and then use those results in a later stage. In OpenGL, at least as far as I know, you only have access to GL_PREVIOUS, so you can only access color or alpha values from the previous texture stage, not from any texture stage.

Anyone know any way to do that in OpenGL?
Image
monkeycracks
Posts: 1029
Joined: Thu Apr 06, 2006 12:45 am
Location: Tennesee, USA
Contact:

Post by monkeycracks »

Good luck with it. There's nothing out there that I've found that you can compile.

Sprintz I got tons of errors with that code ya posted and i couldn't compile IrrSprintz...

I've almost given up completely because I can't blend two textures!
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

For DirectX, here ya go, this will do exactly what you asked -

Code: Select all

//! material renderer to perform texture splatting
class CD3D9MaterialRenderer_TEXTURE_SPLAT_2 : public CD3D9MaterialRenderer
{
public:

	CD3D9MaterialRenderer_TEXTURE_SPLAT_2(IDirect3DDevice9* p, video::IVideoDriver* d)
		: CD3D9MaterialRenderer(p, d) {}

	virtual void OnSetMaterial(SMaterial& material, const SMaterial& lastMaterial,
		bool resetAllRenderstates, IMaterialRendererServices* services) 
	{
		// base texture( texture stage 0, normal operations, but save them to the temp register )
		pID3DDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_TEMP );

		// alpha texture( texture stage 1, we just need to grab the alpha value from the texture at this stage
		pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );

		// this the the blend texture, we want to blend this color with the color from texture stage 0( which is
		// in the temp register ) using the alpha we got from texture stage 1.
		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA );
		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_TEMP );

		services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
	}

	virtual void OnUnsetMaterial()
	{ 
		// base texture( texture stage 0, return the target to current, rather than the temp register )
		pID3DDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_CURRENT );

		pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
		pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		pID3DDevice->SetTextureStageState( 2, D3DTSS_COLORARG2, D3DTA_CURRENT );
	}
};
Image
monkeycracks
Posts: 1029
Joined: Thu Apr 06, 2006 12:45 am
Location: Tennesee, USA
Contact:

Post by monkeycracks »

That's the same as the above that wouldn't compile...
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post by Spintz »

Why won't it compile? You have DX right???
Image
Post Reply