Texture Combiners

From OpenGL Wiki
Jump to navigation Jump to search

Texture combiners became core in GL 1.3. You can combine by multiplying, replacing, adding, subtracting, DOT3 product.
GL 1.4 added to the core a crossbar feature. This means that you sample GL_TEXTUREX from any other texture image unit (TIU).

Example : multiply tex0 and tex1

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, textureID0);
 //Simply sample the texture
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
 //------------------------
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, textureID1);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 //Sample RGB, multiply by previous texunit result
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 //Sample ALPHA, multiply by previous texunit result
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);

The equivalent with GL 2.0 shaders

 //Fragment shader
 uniform sampler2D Texture0;
 uniform sampler2D Texture1;
 //------------------------
 varying vec2 TexCoord0;
 varying vec2 TexCoord1;    //Or just use TexCoord0
 //------------------------
 void main()
 {
    vec4 texel = texture2D(Texture0, TexCoord0);
    texel *= texture2D(Texture1, TexCoord1);
    gl_FragColor = texel;
 }

Example : Blend tex0 and tex1 based on a blending factor you supply

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, textureID0);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
 //------------------------
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, textureID1);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
 //------------------------
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
 //GL_CONSTANT refers to the call we make with glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor)
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_CONSTANT);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
 //------------------------
 float mycolor[4];
 mycolor[0]=mycolor[1]=mycolor[2]=0.0;    //RGB doesn't matter since we are not using it
 mycolor[3]=0.75;                         //Set the blend factor with this
 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, mycolor);

The equivalent with GL 2.0 shaders

 //Fragment shader
 uniform sampler2D Texture0;
 uniform sampler2D Texture1;
 uniform float BlendFactor;
 //------------------------
 varying vec2 TexCoord0;
 varying vec2 TexCoord1;    //Or just use TexCoord0
 //------------------------
 void main()
 {
    vec4 texel0 = texture2D(Texture0, TexCoord0);
    vec4 texel1 = texture2D(Texture1, TexCoord1);
    gl_FragColor = mix(texel0, texel1, BlendFactor);
 }

Example : Add tex0 and tex1

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, textureID0);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 //------------------------
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, textureID1);
 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
 //------------------------
 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);

The equivalent with GL 2.0 shaders

 //Fragment shader
 uniform sampler2D Texture0;
 uniform sampler2D Texture1;
 //------------------------
 varying vec2 TexCoord0;
 //------------------------
 void main()
 {
    vec4 texel0 = texture2D(Texture0, TexCoord0);
    vec4 texel1 = texture2D(Texture1, TexCoord0);
    gl_FragColor = clamp(texel0 + texel1, 0.0, 1.0);
 }