texture matrix with shaders?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

texture matrix with shaders?

Post by xDan »

Hi,

It seems the texture matrix has no effect when I use a shader instead of a built in fixed function material. Is this the correct behaviour?

How can I make the texture matrix "work" when using a GLSL shader?
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Yes that is correct behavior.

To make it work with a shader you can send the texture matrix as a shader constant and multiply it with the texcoords inside the shader (matrix * texcoords).

Cheers
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

*whine* I can't get it to work :(

I have a tilemapped world, with each tile (smiley face) a unit cube:

Image


Now I want to scale the textures, so I alter the texture matrix for each side of each cube as follows:
(surface must be translated after scaling so it tiles correctly)

Code: Select all

		for (u32 i = 0; i < node->getMaterialCount(); i ++)
		{
			
			video::SMaterial &material = node->getMaterial(i);
			
			//printf("%s\n",material.TextureLayer[0].Texture->getName().c_str());
			
			core::matrix4 matrix;
			core::vector3df pos = GetPosFromCoord(mapCoord);
			
			const f32 scale = 3.0;
			
			switch (i)
			{
			case 0://front
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( pos.Y/scale, pos.X/scale );
				break;
			case 1://back
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( -pos.Y/scale, pos.X/scale );
				break;
			case 2://top (grass)
			case 6://side (in case of edge tile)
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( pos.X/scale, -pos.Z/scale );
				break;
			case 3://bottom
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( -pos.Z/scale, pos.X/scale );
				break;
			case 4://right
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( pos.Y/scale, pos.Z/scale );
				break;
			case 5://left
				matrix.setTextureScale( 1.0/scale, 1.0/scale );
				matrix.setTextureTranslate( pos.Y/scale, -pos.Z/scale );
				break;
			}
			
			material.setTextureMatrix(0, matrix);
			
			IShader *shader = world->CreateShader("hemisphere.vert", "hemisphere.frag");
			shader->ApplyToIrrMaterial(material);
		}
Now with the shader disabled and just using fixed function it works fine and I get this:
Image

But with the shader I incorrectly get this:
Image

It seems to me scale is working correctly with the shader but translation is ignored.


My shader is:

vertex

Code: Select all

const vec3 GROUND_COL = vec3(0.33, 0.33, 0.46);
const vec3 SKY_COL = vec3(0.93, 0.93, 0.53);
const vec3 SUN_POS = vec3(0.0, 100.0, 0.0);

void main(void)
{
	gl_TexCoord[0] = gl_MultiTexCoord0 * gl_TextureMatrix[0];
	
    vec3 normal = normalize(gl_Normal);
    vec3 ecPos = vec3(gl_Vertex);
    
    gl_Position = ftransform();
    
    gl_FrontColor = vec4(
        mix(GROUND_COL, SKY_COL, 0.5 + 0.5 * dot(normal, normalize(SUN_POS - ecPos))),
    		1.0
    		);
}
pixel

Code: Select all

uniform sampler2D texture0;

void main(void)
{
	vec4 col = gl_Color;
	
	col *= texture2D(texture0, gl_TexCoord[0].xy);
	
	gl_FragColor = col;
}
as you can see here I am using gl_TextureMatrix[0] rather than setting a constant, but I have also tried using a shader constant for each material and the problem is exactly the same.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Does it work if you do gl_TextureMatrix[0] * gl_MultiTexCoord0 like I said? Matrix mul is NOT commutative.

EDIT: But if it still doesn't work I suggest just doing texcoords += foo; texcoords *= bar; in the shader.
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
xDan
Competition winner
Posts: 673
Joined: Thu Mar 30, 2006 1:23 pm
Location: UK
Contact:

Post by xDan »

Does it work if you do gl_TextureMatrix[0] * gl_MultiTexCoord0 like I said? Matrix mul is NOT commutative.
That works great, thanks Blindside!

Sorry I didn't realise the ordering had any effect :S
Post Reply