Texture mask shader

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
oldskoolPunk
Posts: 199
Joined: Wed Nov 29, 2006 4:07 am

Texture mask shader

Post by oldskoolPunk »

Hi again.

I have been asking lots of questions and bugging alot of people for a few days but I have finnally made my first steps here.

I have made a simple texture shader material that accepts 2 tiled textures, and one mask texture, that blends the two together.

Image
This is an example mask texture, just a brush stroke.

Image
This is what the material looks like rendered on a plane.. It seems like it will be quite easy to extend this shader to accept more textures, but (I think) the drawback being dramatic drops in framerates. Maybe someone can look at it and tell me ways to speed it up?

Here are the shader files

Code: Select all

// my vertex shader


void main()
{
	gl_TexCoord[1] = gl_MultiTexCoord1;

	gl_TexCoord[0] = gl_MultiTexCoord0;

	gl_Position = ftransform();
}

Code: Select all

// my fragment shader


uniform sampler2D grass;
uniform sampler2D soil;
uniform sampler2D mask;

void main()
{
	vec4 first = texture2D(grass,vec2(gl_TexCoord[0]));
	vec4 second = texture2D(soil,vec2(gl_TexCoord[0]));
	vec4 third = texture2D(mask,vec2(gl_TexCoord[1]));
	float x = clamp(third,0.0,1.0);
	float y = 1.0-x;
	vec4 color1 = first*x;
	vec4 color2 = second*y;
	gl_FragColor = vec4(color1+color2);
}

Here is what to put in the shader callback

Code: Select all

class MyShaderCallBack : public irr::video::IShaderConstantSetCallBack
{
public:

	virtual void OnSetConstants(irr::video::IMaterialRendererServices* services, irr::s32 userData)
	{
        irr::s32 grass = 0;
        services->setPixelShaderConstant ( "grass",reinterpret_cast<irr::f32*>(&grass),1);
        irr::s32 soil = 1;
        services->setPixelShaderConstant ("soil",reinterpret_cast<irr::f32*>(&soil),1);    
		irr::s32 mask = 2;
        services->setPixelShaderConstant ("mask",reinterpret_cast<irr::f32*>(&mask),1);
	}
};

Just open for discussion or whatever. Im gonna try it on my level and see how bad it slows everything down. :D

Edit: The tiled textures must be loaded into texture slots 0 and 1, and the mask texture loaded into slot 2. Also the mesh must contain 2 sets of UV coords, one for the tiled textures and one for the mask.(lightmap UV coords)
Signature? I ain't signin nuthin!
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Hi, oldskoolPunk

Very nice!

That's the way Ubisoft do it for their Dunia Engine. (Far Cry II)
They are using that technique to add usage on objects.

A gun, for example. As 2 textures. One of the gun, super clean like a brand new thing, the other texture is the same gun but very used and worn. They do some dynamic mask painting to let show the damage.

For vehicles, they use it also to let it get damaged and show the rust coming out of the paint.
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

nice, you finally got it.
Image
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

it looks like a reader can be coded to read an rendermonkey .rfx file into a scene similar to the code written in the above example.

at the moment, i'm building a scene in rendermonkey.

what would be nice is to have a reader import that .rfx file loading it into a scene. all that scene objects will show up in irrlicht along with the other code.
Image
oldskoolPunk
Posts: 199
Joined: Wed Nov 29, 2006 4:07 am

Post by oldskoolPunk »

Yes RenderMonkey looks awesome. I have looked at it a couple of times, but the 65mb download is a little out of my range. Is there a way to just buy it through the mail or somthing?
Signature? I ain't signin nuthin!
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

oldskoolPunk wrote:Yes RenderMonkey looks awesome. I have looked at it a couple of times, but the 65mb download is a little out of my range. Is there a way to just buy it through the mail or somthing?
If you live in the UK I can send you a CD via snail mail with the the latest RenderMonkey on it and anything else (legal!) you'd like burned on it. If you live in the UK, PM your address to me and a list of (legal!) stuff you'd like burnt. If you live elsewhere maybe someone else will offer the same...

Code: Select all

void main()
{
   vec4 first = texture2D(grass,vec2(gl_TexCoord[0]));
   vec4 second = texture2D(soil,vec2(gl_TexCoord[0]));
   vec4 third = texture2D(mask,vec2(gl_TexCoord[1]));
   float x = clamp(third,0.0,1.0);
   float y = 1.0-x;
   vec4 color1 = first*x;
   vec4 color2 = second*y;
   gl_FragColor = vec4(color1+color2);
} 
Err...unless I'm mistaken, this is alpha-blending. Include the mask in one of the textures and use srcalpha/invsrcalpha blending. Using a shader for this is overkill and probably slower. Unless there's something special you're doing that I've missed.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Yah, this exact behaviour is currently possible without a shader, through the blending functions.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
oldskoolPunk
Posts: 199
Joined: Wed Nov 29, 2006 4:07 am

Post by oldskoolPunk »

Oh nice! Can you show me how please? Is it faster?
Signature? I ain't signin nuthin!
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Code: Select all

Material.MaterialType = EMT_ONETEXTURE_BLEND;
Material.MaterialTypeParam = pack_texureBlendFunc( EBF_SRC_ALPHA , EBF_ONE, EMFN_MODULATE_1X );
When you use this, you store your blending texture inside the alpha channel of the first texture, and it should lerp between the two based on that.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
oldskoolPunk
Posts: 199
Joined: Wed Nov 29, 2006 4:07 am

Post by oldskoolPunk »

Thanks Blindside. When I looked at ONETEXTURE_BLEND I had no idea it could do so much. I will learn this way and post back my results.

sio2 I really appreciate that! I'm sorry I missed your post earlier. Sadly I do not live in the UK, but many thanks for your offer anyways! :D
Signature? I ain't signin nuthin!
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Blindside. That is great, but if the 2 textures are tiled and need the mask to cover the entire mesh?

Is there another trick? Or we'll need to use the shader then?
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

Most games just model the road over the terrain, that way only the road has the special shader(or even a texture with alpha) while the terrain can use a solid simpler one.

Look at how many terrain fragments are in that picture vs road fragments, why should all these terrain fragments go through a complex shader?

Yes it will be slow, however the shader will become more "economic" if you have equal numbers of road and grass texels visible in a complex way that you cant model in a mesh.

your shader is clean , you can use the mix() function in glsl to help the compiler optimise your code better(gives it a hint), however your code will probabbly be just as fast.
"Irrlicht is obese"

If you want modern rendering techniques learn how to make them or go to the engine next door =p
dlangdev
Posts: 1324
Joined: Tue Aug 07, 2007 7:28 pm
Location: Beaverton OR
Contact:

Post by dlangdev »

interesting, i'm changing my previous n00b opinion regarding terrain shading. it looks like dividing scene object to static/dynamic will save some gpu cycles.

pre-computed values stored in textures will work for static, though. while dynamic lighted materials can get the full shader treatment. it would also be nice to allocate shaders to static materials for explosions or moving lights.

that's one reason why i still need tools like gile[s], i'll probably get it sooner than i expected.
Image
Post Reply