Three.js - Place a dynamic 2D Canvas on a PlaneGeometry

so I have a school project where I have to remake a GameBoy. For this I wanted to create a GameBoy model with ThreeJS (i’m a beginner) and use a public repo of a GameBoy emulator in JavaScript. So I somewhat finished the GameBoy model (still need some some stuff to be added but i’ll make it better later) and I decided to use this repo for the GameBoy emulator https://github.com/alexaladren/jsgameboy. This repo worked perfectly fine when it was given a canvas with an ID “display”. But when I tried to change the canvas to the canvas I made in ThreeJS it doesn’t display anything, here is the code of when I make the Canvas:

geometry = new THREE.PlaneGeometry( 0.55, 0.45, 0.1 );
for (let index = 0; index < 6; index++) {
    let x2 = document.createElement("canvas");
    let xc2 = x2.getContext("2d");

    x2.width = 320;
    x2.height = 288;
    xc2.fillStyle = "rgba(0, 0, 200, 0.5)";
    x2.style.id = 'display';
    screenCanvas = x2;
    xc2.fillRect(0, 0, x2.width, x2.height);
    let tex2 = new THREE.CanvasTexture(x2);
    screen.push(new THREE.MeshBasicMaterial({
        map: tex2,
        transparent:true,
        opacity:0.3
    }))
    number++;
}

material = new THREE.MeshBasicMaterial({color: 0xA1A935});
mesh = new THREE.Mesh( geometry, screen );
mesh.position.y = 0.25;
mesh.position.z = 0.3;
group.add(mesh);

Here is the code I edited in the emulator where the default “display” canvas was mentioned:

   if(window.gb != undefined){
  clearInterval(gb.interval);
  screenCanvas.getContext("2d").setTransform(1,0,0,1,0,0);
  }
  gb = new GameBoy(arraybuffer);
  gb.displaycanvas = screenCanvas.getContext("2d");
  screenCanvas.getContext("2d").scale(2,2);

The PlaneGeometry is correctly displayed (I also tried BoxGeometry but same results) but the game won’t display on the Canvas I created.

My thoughts on why it doesn’t work:

  • Because the Canvas is created in ThreeJS it doesn’t seem to be added to the DOM elements and probably to the already existing ThreeJS canvas?
  • Maybe the canvas I created isn’t updating? But I set it to a CanvasTexture so it should update?

Thank you for your help.

My initial guess at this would be that you need to set needsUpdate=true on the texture every time it changes, otherwise threejs won’t sync its new contents to the GPU.

I don’t quite follow why you’re creating six canvases/textures/materials in a loop, it’s possible that has something to do with it too.

Hey, I had a similar issue, but with Sprites instead.

I solved it by adding the canvas to the body element with document.body.appendChild(canvas);

Try document.body.appendChild(x2); just after x2 is created or maybe a try would be document.body.appendChild(screenCanvas);