GLSL - merging two textures

Started by
4 comments, last by Civilwar 12 years, 5 months ago
Hi, this will be a little longer question.

What I have:

Two grass textures

gra1.jpg gra2t.jpg

And one big alpha-white texture like this:

alpha2j.jpg




I need to map both textures on my mesh and it depends on alpha texture how much it will show first or second texture. I mean, if there is 70% alpha in one point, it will show 70% first grass texture and 30% second one. So the result should look like

mergedpu.jpg

I think it shouldn't be so dificult, but I have no expirience with shaders, so I don't even know where to start.

I'll be glad for every help.
Advertisement


gl_FragColor = mix(FirstTextureColor, SecondTextureColor, coeff);



Where:

FirstTextureColor is a color returned by texture2D(<first texture>,...);

SecondTextureColor is a color returned by texture2D(<second texture>,...);

coeff -> X% of second texture and (100 - X)% of first texture.




Best wishes, FXACE.




gl_FragColor = mix(FirstTextureColor, SecondTextureColor, coeff);



Where:

FirstTextureColor is a color returned by texture2D(<first texture>,...);

SecondTextureColor is a color returned by texture2D(<second texture>,...);

coeff -> X% of second texture and (100 - X)% of first texture.




Best wishes, FXACE.




Ok, but I don't know how to use it :( For example, how can I get coeff, eg. % of alpha in given point? Could you please write me whole shader?

Thanks a lot.


No problem.




Which shader version you need? (1.0 is enough?)

Did you have the algorithm to load shaders?



//vertex shader

void main()

{

 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

 gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
}


// fragment/pixel shader

uniform sampler2D firstGrassTexture;

uniform sampler2D secondGrassTexture;

uniform sampler2D maskTexture;

void main()

{

 gl_FragColor = mix(texture2D(firstGrassTexture,gl_TexCoord[0].xy), texture2D(secondGrassTexture,gl_TexCoord[0].xy), texture2D(maskTexture,gl_TexCoord[0].xy).a); 
}







you need to do this in your application:



GLhadleARB shaderProgram; // somewhere defined in your application (of course it must be loaded)

glUseProgramObjectARB(shaderProgram);

glUniform1iARB(glGetUniformLocationARB(shaderProgram,"firstGrassTexture"),0);

glUniform1iARB(glGetUniformLocationARB(shaderProgram,"secondGrassTexture"),1);

glUniform1iARB(glGetUniformLocationARB(shaderProgram,"maskTexture"),2);

glUseProgramObjectARB(0);



The code which was introduced above is a initialization of uniforms setup (so, just call it once).

The next code you need to call each time when you render your object with this shader:



glActiveTextureARB(GL_TEXTURE0_ARB);

glBindTexture(...);// here you bind first grass texture

glActiveTextureARB(GL_TEXTURE1_ARB);

glBindTexture(...);// here you bind second grass texture

glActiveTextureARB(GL_TEXTURE2_ARB);

glBindTexture(...);// here you bind mask texture

glActiveTextureARB(GL_TEXTURE0_ARB);

glUseProgramObjectARB(shaderProgram);




Draw the mesh




glUseProgramObjectARB(0);// disable using shader (maybe you have some object below which you want to draw them without using shaders













Best wishes, FXACE.




Also I want to add:



gl_FragColor = mix(texture2D(firstGrassTexture,gl_TexCoord[0].xy), texture2D(secondGrassTexture,gl_TexCoord[0].xy), texture2D(maskTexture,gl_TexCoord[0].xy).a);



It would work if you loading "mask" texture as .png or any other format which supports 32-bit. Otherwise, you need to change value 'a' (alpha) of "texture2D(maskTexture,gl_TexCoord[0].xy).a" to one of the following channels:

x, r (red);

y, g (green);

z, b (blue);

which you set as mask channel.




Best wishes, FXACE.

It works! Endless thanks.

This topic is closed to new replies.

Advertisement