2012-10-01 30 views
11

在Three.js中,是否可以直接绘制到WebGL区域(例如抬头显示或UI元素)常规的HTML5画布元素?使用Three.js将UI元素直接绘制到WebGL区域

如果是这样,你如何获得上下文和绘图命令是可用的?

如果不是,还有其他方法可以通过其他Three.js或WebGL特定的绘图命令来与Three.js合作吗?

我的备份计划是使用HTML div作为叠加层,但我认为应该有更好的解决方案。

谢谢!

+1

布兰登·琼斯从申报单由HUD元素的一个很好的演示:http://media.tojicode.com/webgl-samples/hud-test.html – Anton

+0

也看看这个主题:https://github.com/mrdoob/three.js/issues/1959 – WestLangley

+0

谢谢你们,这些真的很有帮助 – Dev

回答

9

您无法像使用常规画布一样直接绘制WebGL画布。然而,还有其他方法,例如

  • 绘制到隐藏2D画布照常并传送到WebGL的通过使用它作为一个纹理四
  • 绘制(例如帧健康盒)
  • 绘制路径使用纹理映射的四边形的图像(和形状)通过将它们的顶点放到VBO并使用适当的多边形类型绘制
  • 通过使用位图字体(基本上是纹理四边形)或实际几何体(three.js具有示例和帮助器)来绘制文本

使用这些通常意味着设置一个正交相机。

但是,所有这些都是相当多的工作,例如用真实几何图形绘制文本可能很昂贵。如果您可以使用CSS样式来处理HTML div,则应该使用它们,因为它的设置非常快。此外,绘制WebGL画布(或许使用透明度)应该是浏览器强烈暗示GPU加速其div绘图(如果它尚未加速所有内容的话)。

另外请记住,你可以用CSS3实现很多,例如,圆角,alpha透明度,甚至是3D视角转换,正如Anton的链接在问题评论中所展示的。

+0

伟大的答案,谢谢..也见上面评论作为安东和WestLangley有一些很好的见解 – Dev

+0

嗯... ...我想知道是否将我的页面的整个背景设置为空webgl画布会强制浏览器根据您的评论加速所有内容。出于某种原因,我认为它不会起作用。 – trusktr

5

我有完全相同的问题。我试图创建一个HUD(抬头显示器),而不DOM和我结束了创建此解决方案:

  1. 我创建了一个单独的场景与正视相机。
  2. 我创建了一个画布元素,并使用2D绘制图元来渲染我的图形。
  3. 然后,我创建了一个适合整个屏幕的平面,并将2D画布元素用作纹理。
  4. 我呈现的是次要的场景在原始场景

这就是HUD代码看起来的顶部,如:

// We will use 2D canvas element to render our HUD. 
var hudCanvas = document.createElement('canvas'); 

// Again, set dimensions to fit the screen. 
hudCanvas.width = width; 
hudCanvas.height = height; 

// Get 2D context and draw something supercool. 
var hudBitmap = hudCanvas.getContext('2d'); 
hudBitmap.font = "Normal 40px Arial"; 
hudBitmap.textAlign = 'center'; 
hudBitmap.fillStyle = "rgba(245,245,245,0.75)"; 
hudBitmap.fillText('Initializing...', width/2, height/2); 

// Create the camera and set the viewport to match the screen dimensions. 
var cameraHUD = new THREE.OrthographicCamera(-width/2, width/2, height/2, -height/2, 0, 30); 

// Create also a custom scene for HUD. 
sceneHUD = new THREE.Scene(); 

// Create texture from rendered graphics. 
var hudTexture = new THREE.Texture(hudCanvas) 
hudTexture.needsUpdate = true; 

// Create HUD material. 
var material = new THREE.MeshBasicMaterial({map: hudTexture}); 
material.transparent = true; 

// Create plane to render the HUD. This plane fill the whole screen. 
var planeGeometry = new THREE.PlaneGeometry(width, height); 
var plane = new THREE.Mesh(planeGeometry, material); 
sceneHUD.add(plane); 

而这正是我加入到我的渲染循环:

// Render HUD on top of the scene. 
renderer.render(sceneHUD, cameraHUD); 

你可以在这里玩完整的源代码: http://codepen.io/jaamo/pen/MaOGZV

而且阅读更多关于我的博客的实现: http://www.evermade.fi/pure-three-js-hud/