how do i change the texture of an image on each side of the triangle?

I’m not sure what kind of help you are looking for.

The normal way to put a different image on each side of a pyramid is to use a texture atlas. Here’s an article that covers it.

Effectively you put all the images in to one texture and then use texture coordinates on each face of the pyramid to select one of the images.

The reason I ask if that’s what you want is because using a texture atlas is pretty much how 99% of all WebGL apps and 3D graphics apps in general would solve the issue of putting a different texture on each face of a pyramid.

Solving it by actually using multiple textures is possible but it’s generally not considered a good solution since then you’d need a different shader to shade a cube (8 textures) from a 4 sides pyramid (4 textures) and again different shaders for every number of textures. Further, there’s a limit to the number of textures a single shader can use in one draw call.

Otherwise, the code you posted seems to only make 2 textures and multiplies them together

gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));

So there’s nothing in your code to select one texture or the other. You need to add some data to select the texture.

One way would be to add another attribute to your shaders to select the texture. You’d set that attribute to 0 to select Tex0 and 1 to select Tex1

varying float mixAmount;  // passed in from vertex shader via attributes

...

vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color = mix(color0, color1, mixAmount);

gl_FragColor = fColor * color;

Where it selects texture 0 when mixAmount = 0 and texture 1 when mixAmount = 1

var canvas;
var gl;

var numVertices  = 24;

var texSize = 256;
var numChecks = 8;

var program;

var texture1, texture2;
var t1, t2;

var c;

var flag = true;

var image1 = new Uint8Array(4*texSize*texSize);

    for ( var i = 0; i < texSize; i++ ) {
        for ( var j = 0; j <texSize; j++ ) {
            var patchx = Math.floor(i/(texSize/numChecks));
            var patchy = Math.floor(j/(texSize/numChecks));
            if(patchx%2 ^ patchy%2) c = 255;
            else c = 0;
            //c = 255*(((i & 0x8) == 0) ^ ((j & 0x8)  == 0))
            image1[8*i*texSize+8*j] = c;
            image1[5*i*texSize+5*j+3] = c;
            image1[6*i*texSize+6*j+4] = c;
            image1[4*i*texSize+4*j+3] = 255;
        }
    }
    
var image2 = new Uint8Array(4*texSize*texSize);

    // Create a checkerboard pattern
    for ( var i = 0; i < texSize; i++ ) {
        for ( var j = 0; j <texSize; j++ ) {
            image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
            image2[6*i*texSize+6*j+1] = 127+127*Math.sin(0.1*i*j);
            image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
            image2[4*i*texSize+4*j+3] = 255;
           }
    }

var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var mixAmountsArray = [];

var texCoord = [
    vec2(0, 0),
    vec2(0, 1),
    vec2(1, 1),
    vec2(1, 0)
];

var vertices = [
    vec4(0.5, -0.2722, 0.2886),
    vec4(0.0, -0.2722, -0.5773),
    vec4(-0.5, -0.2722, 0.2886),
    vec4(0.5, -0.5443, 0.0)
];
var vertexColors = [
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red
    vec4( 1.0, 1.0, 1.0, 1.0 ),  // white
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue
    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta
    vec4( 0.0, 1.0, 1.0, 1.0 ),  // cyan
    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan
];  

   
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;

var theta = [45.0, 45.0, 45.0];

var thetaLoc;

function configureTexture() {
    texture1 = gl.createTexture();       
    gl.bindTexture( gl.TEXTURE_2D, texture1 );
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
    gl.generateMipmap( gl.TEXTURE_2D );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, 
                      gl.NEAREST_MIPMAP_LINEAR );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

    texture2 = gl.createTexture();
    gl.bindTexture( gl.TEXTURE_2D, texture2 );
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
    gl.generateMipmap( gl.TEXTURE_2D );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, 
                      gl.NEAREST_MIPMAP_LINEAR );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}

function quad(a, b, c, mixAmount) {
     pointsArray.push(vertices[a]); 
     colorsArray.push(vertexColors[2]); 
     texCoordsArray.push(texCoord[0]);
     mixAmountsArray.push(mixAmount);

     pointsArray.push(vertices[b]); 
     colorsArray.push(vertexColors[2]);
     texCoordsArray.push(texCoord[1]); 
     mixAmountsArray.push(mixAmount);

     pointsArray.push(vertices[c]); 
     colorsArray.push(vertexColors[2]);
     texCoordsArray.push(texCoord[2]); 
     mixAmountsArray.push(mixAmount);
   
     pointsArray.push(vertices[a]); 
     colorsArray.push(vertexColors[2]);
     texCoordsArray.push(texCoord[0]); 
     mixAmountsArray.push(mixAmount);

     pointsArray.push(vertices[b]); 
     colorsArray.push(vertexColors[2]);
     texCoordsArray.push(texCoord[2]); 
     mixAmountsArray.push(mixAmount);

     pointsArray.push(vertices[c]); 
     colorsArray.push(vertexColors[2]);
     texCoordsArray.push(texCoord[3]);    
     mixAmountsArray.push(mixAmount);
}

function colorCube()
{

      quad( 0, 1, 2, 0 ); // bottom
    quad( 1, 0, 3, 1 ); // side0
    quad( 1, 2, 3, 0 ); // side1
    quad( 2, 0, 3, 1 ); // side3
}


window.onload = function init() {

    canvas = document.getElementById( "gl-canvas" );
    
    gl = WebGLUtils.setupWebGL( canvas );
    if ( !gl ) { alert( "WebGL isn't available" ); }

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
    
    gl.enable(gl.DEPTH_TEST);

    //
    //  Load shaders and initialize attribute buffers
    //
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );
    
    colorCube();

    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
    
    var vColor = gl.getAttribLocation( program, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );

    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
    
    var vPosition = gl.getAttribLocation( program, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );
    
    var tBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
    gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
    
    var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
    gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vTexCoord );

    var mBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, mBuffer);
    gl.bufferData( gl.ARRAY_BUFFER, flatten(mixAmountsArray), gl.STATIC_DRAW );
    
    var vMixAmount = gl.getAttribLocation( program, "vMixAmount" );
    gl.vertexAttribPointer( vMixAmount, 1, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vMixAmount );

    

    
    configureTexture();
    
    gl.activeTexture( gl.TEXTURE0 );
    gl.bindTexture( gl.TEXTURE_2D, texture1 );
    gl.uniform1i(gl.getUniformLocation( program, "Tex0"), 0);
            
    gl.activeTexture( gl.TEXTURE1 );
    gl.bindTexture( gl.TEXTURE_2D, texture2 );
    gl.uniform1i(gl.getUniformLocation( program, "Tex1"), 1);

    thetaLoc = gl.getUniformLocation(program, "theta"); 
    

 document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
 document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
 document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
 document.getElementById("ButtonT").onclick = function(){flag = !flag;};
                       
    render();
}

var render = function() {
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    if(flag) theta[axis] += 2.0;
    gl.uniform3fv(thetaLoc, theta);
    gl.drawArrays( gl.TRIANGLES, 0, numVertices );
    requestAnimFrame(render);
}
canvas { border: 1px solid black; }
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>


<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
attribute  vec2 vTexCoord;
attribute  float vMixAmount;

varying vec4 fColor;
varying vec2 fTexCoord;
varying float mixAmount;

uniform vec3 theta;

void main() 
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );

    // Remeber: thse matrices are column-major
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
            0.0,  c.x,  s.x, 0.0,
            0.0, -s.x,  c.x, 0.0,
            0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
            0.0, 1.0,  0.0, 0.0,
            s.y, 0.0,  c.y, 0.0,
            0.0, 0.0,  0.0, 1.0 );


    mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
            s.z,  c.z, 0.0, 0.0,
            0.0,  0.0, 1.0, 0.0,
            0.0,  0.0, 0.0, 1.0 );

    mixAmount = vMixAmount;
    fColor = vColor;
    fTexCoord = vTexCoord;
    gl_Position = rz * ry * rx * vPosition;
} 
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;

varying vec4 fColor;
varying  vec2 fTexCoord;
varying float mixAmount;

uniform sampler2D Tex0;
uniform sampler2D Tex1;

void
main()
{
    vec4 color0 = texture2D(Tex0, fTexCoord);
    vec4 color1 = texture2D(Tex1, fTexCoord);
    gl_FragColor = fColor * mix(color0, color1, mixAmount);
}
</script>

<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="texture.js"></script>

<body>
<canvas id="gl-canvas" width="200" height="200">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

That’s only 2 textures. To do 4 textures you’d have to do more math and maybe have your mixAmount be 0 to 3

vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color2 = texture2D(Tex2, fTexCoord);
vec4 color3 = texture2D(Tex3, fTexCoord);
vec4 color = color0 * clamp(mixAmount, 0, 1) +
             color1 * clamp(abs(1 - mixAmount, 0, 1) +
             color2 * clamp(abs(2 - mixAmount, 0, 1) +
             color3 * clamp(abs(3 - mixAmount, 0, 1);

gl_FragColor = fColor * color;

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top