【问题标题】:Overlay canvas (WebGL) with canvas (three.js)用画布(three.js)覆盖画布(WebGL)
【发布时间】:2016-01-27 12:20:36
【问题描述】:

我有两张画布。第一个应该是背景,它的内容是通过原始 WebGL (3D) 呈现的。第二个画布应该覆盖第一个画布,并且主要是透明的。它的内容是通过 three.js(3D 内容)呈现的。不幸的是,第二个画布没有绘制在第一个画布的顶部,而是在它旁边。

如何使用透明的 three.js 场景背景在第一个画布上方绘制第二个画布?

更新:

我整合了 gaitat 的想法。但是它仍然无法正常工作(请参阅Fullscreen screenshot. Twice rendered grey box due to Oculus Rift support.)。 Canvas 2 仍然不在第一个之上,而且它的背景也不透明。提醒一下:灰色方块是通过原始 WebGL 在名为 webglcanvas 的画布上绘制的。该框是通过 leapcanvas 上的 three.js 渲染的。

代码 1(画布和 div 的初始化 [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)

代码 2(三个.js 场景的渲染 [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);

    }

【问题讨论】:

  • 我认为foreground.style.top = 0 成功了。明天必须检查。
  • foreground.style.top = 0, foreground.style.left= 0 和 foreground.style.position = 'absolute' 也是必要的。

标签: css canvas three.js webgl


【解决方案1】:

假设你的 .html 文件中有

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

在你需要的 .css 中

/* 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 */
}

【讨论】:

  • 我将 GWT 用于我的应用程序。画布是通过 Java 动态创建的(编译为 Ajax)。目前,两个 Canvas 共享相同的 div。在该 div 上调用全屏模式。今晚我会试试你的解决方案。
  • 基于Mr. Doob's example,我创建了一个简短的 JSFiddle 示例来展示一个有效的solution,感谢这个答案。我现在将尝试在我的 GWT 应用程序中实现相同的目标。未来的读者:由于我的原始 WebGL 渲染器,我故意使用了两个渲染器。请参阅this post 以了解如何使用一个渲染器。
  • 更新了我的帖子。也许你可以添加一些东西?
  • 做了但忘记复制了,抱歉。父容器是 webglDiv。
  • 谢谢您,您的解决方案对我帮助很大。
猜你喜欢
  • 2014-11-07
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-22
  • 2010-12-12
  • 2012-09-10
  • 2012-07-23
相关资源
最近更新 更多