是否可以在不使用自定义着色器的情况下使用 2 个纹理(一个在另一个之上)作为 Material?

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

我正在学习 three.js,我已经完成了一些关于它和基本着色器的示例 (One being Codrop's "the aviator" tutorial),但现在我很难尝试创建一个简单的立方体一次 2 个纹理。

我想为正方形的每个面同时使用 2 个透明 .png 纹理。这是否可以不重复使用自定义着色器? I already saw this answer,但由于它的复杂性和对着色器来说相当新,我没有成功让它正常工作。

就上下文而言,我的代码在 this example 上几乎相同,只是一个带有纹理的简单 3D 立方体,我试图有 2 个不同的立方体(在另一个之上)

如果没有着色器,您可以尝试这样的操作:

var myMaterialA = new THREE.MeshBasicMaterial({map:myTextureA, depthWrite:false});
var myMeshA = new THREE.Mesh( new THREE.BoxGeometry(1,1,1) , myMaterialA );

var myMaterialB = new THREE.MeshBasicMaterial({map:myTextureB,transparent:true});
var myMeshB = myMeshA.clone();
var myMeshB.material = myMaterialB;

第二个 material 透明将迫使另一个立方体在第一个立方体之后绘制。如果这两者立即相继发生,就可以产生预期的效果。

在 canvas 上动态绘制图像并将 canvas 设置为纹理。

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()});

这是一个fiddle

fiddle 显示背景图案,上面覆盖有透明的 png。

请注意,在 fiddle 中,我正在为 return 数据 URL 的图像源调用函数。这只是为了解决 cors 问题。

编辑:
重新阅读您的问题后,我不确定您想要什么。特别是“每个正方形的脸同时有 2 个透明的 .png 纹理”。你的意思是每张脸上都有不同的图像吗?如果是这样,那我的回答对你没有帮助。
如果您的意思是您需要像 WestLangly 链接到的答案那样显示背景颜色,您可以在绘制图像之前先绘制 canvas 背景颜色。

当然...只需添加像 WestLangley 建议的自定义着色器可能比摆弄 canvas 只是为了创建纹理更容易。