3
votes

I have two canvases. The first is supposed to be the background and it's content is rendered via raw WebGL (3D). The second canvas is supposed to overlay the first one and is mainly transparent. It's content is rendered via three.js (3D content). Unfortunately the second canvas is not drawn on top of the first one, but next to it.

How can I draw the second canvas above the first one with transparent three.js scene background?

Update:

I integrated gaitat's idea. However it's still not working (see Fullscreen screenshot. Twice rendered grey box due to Oculus Rift support.). Canvas 2 is still not on top of the first one and it's background is not transparent as well. As a reminder: The grey square is drawn via raw WebGL on a canvas called webglcanvas. The box is rendered via three.js on leapcanvas.

Code 1 (Initialization of canvases and divs [Xtend/Java]):

Browser::getDocument().getElementById("view").appendChild(webglDiv)


    val Element webGLCanvasDiv = Browser::getDocument().createDivElement()
    webGLCanvasDiv.style.setCssText("position: absolute")
    webGLCanvasDiv.style.setCssText("z-index: 8")
    webGLCanvasDiv.setId("webGLCanvasDiv")      
    Browser::getDocument().getElementById("webglDiv").appendChild(webGLCanvasDiv)       


    val webGLCanvas = Browser::getDocument().createCanvasElement()
    webGLCanvas.setWidth(viewportWidth)
    webGLCanvas.setHeight(viewportHeight)
    webGLCanvas.style.setCssText("border-bottom: solid 1px #DDDDDD")
    webGLCanvas.setId("webglcanvas")        
    Browser::getDocument().getElementById("webGLCanvasDiv").appendChild(webGLCanvas)        


    val Element webGLLeapDiv = Browser::getDocument().createDivElement()
    webGLLeapDiv.style.setCssText("position: absolute")
    webGLLeapDiv.style.setCssText("z-index: 10")     
    webGLLeapDiv.setId("webGLLeapDiv")      
    Browser::getDocument().getElementById("webglDiv").appendChild(webGLLeapDiv)


    val leapCanvas = Browser::getDocument().createCanvasElement()
    // canvas size is handled via renderer in Javascript        
    leapCanvas.setId("leapcanvas")      
    Browser::getDocument().getElementById("webGLLeapDiv").appendChild(leapCanvas)

Code 2 (Rendering of three.js scene [Javascript])

var foreground = $doc.getElementById("leapcanvas");     

    var camera, scene, renderer;
    var geometry, material, mesh;

    init();
    animate();

    function init() {

        camera = new $wnd.THREE.PerspectiveCamera(75, 500 / 500, 1, 10000);
        camera.position.z = 500;

        scene = new $wnd.THREE.Scene();

        geometry = new $wnd.THREE.BoxGeometry(200, 200, 200);
        material = new $wnd.THREE.MeshNormalMaterial();         

        mesh = new $wnd.THREE.Mesh(geometry, material);
        scene.add(mesh);

        renderer = new $wnd.THREE.WebGLRenderer({
            canvas : foreground,
            alpha : true
        });


        renderer.setSize(viewportWidth / 2, viewportHeight);
        renderer.setClearColor(0x000000, 0); 

    }

    function animate() {

        requestAnimationFrame(animate);

        mesh.rotation.x += 0.01;
        mesh.rotation.y += 0.02;

        renderer.render(scene, camera);

    }
1
I think foreground.style.top = 0 did the trick. Have to check tomorrow.Sincostan
foreground.style.top = 0, foreground.style.left= 0 and foreground.style.position = 'absolute' were also necessary.Sincostan

1 Answers

4
votes

Assuming you have in your .html

<div id="container">
    <div id="webglContainer"></div>
    <div id="threeContainer"></div>
</div>

in your .css you need

/* make the canvases, children of the this container */
#container {
    position: relative;
}

#webglContainer {
    position: absolute;
    pointer-events: none;   /* this element will not catch any events */
    z-index: 8;    /* position this canvas at bottom of the other one */
}

#threeContainer {
    position: absolute;
    z-index: 10;      /* position this canvas on top of the other one */
}