Search code examples
javascriptthree.jstexturesshader

Is it possible to use 2 textures (one on top of the other) as a Material without using custom Shaders?


I'm learning three.js and I've done a few a examples on it and basic shaders (One being Codrop's "the aviator" tutorial), but right now I'm stumped trying to create a simple cube with 2 textures at once.

I would like to use 2 transparent .png textures at the same time for each of the square's face. Is this possible without recurring to custom shaders? I already saw this answer, but I've had no success getting it to work correctly because of it's complexity and being rather new to shaders.

For context, my code is pretty much the same on this example, just a simple 3D cube with a texture, which I'm trying to have 2 different ones (on on top of the other)


Solution

  • Dynamically draw the images on a canvas and set that canvas as the texture.

    function getCanvasImage() {
    
      var canvas = document.createElement('canvas');
      canvas.width  = 512;
      canvas.height = 512;
      var context = canvas.getContext('2d');
      var texture = new THREE.Texture(canvas) ;
    
      var imageObj = new Image();
      imageObj.src = "my_image1.png";
      imageObj.onload = function(){  
        context.drawImage(imageObj, 0, 0);
        texture.needsUpdate = true;
        var imgObj2 = new Image();
        imgObj2.src = "my_image2.png";
        imgObj2.onload = function(){
          context.drawImage(imgObj2, 0, 0);
          texture.needsUpdate = true;
        }
      };
    
      return texture;
    
    }
    
    material = new THREE.MeshBasicMaterial({map:getCanvasImage()});
    

    Here is a fiddle

    The fiddle shows a background pattern, overlayed with a png with transparency.

    Notice in the fiddle I am calling function for the image sources that return a dataURL. This is just to get around the cors issue.

    EDIT:
    Having re read your question, I'm not exactly sure what you want. Specifically "2 transparent .png textures at the same time for each of the square's face". Do you mean a different image on each face? If so, then my answer will not help you.
    If you mean that you need the background color to be visible as in the answer WestLangly linked to, you could possibly paint the canvas background color before drawing the images on it.

    Of course... Just adding a custom shader like WestLangley suggests is probably easier than fiddling around with canvas just to create a texture.