15

在 Three.js 中,是否可以像使用常规 HTML5 画布元素那样直接绘制到 WebGL 区域(例如,用于平视显示或 UI 元素)?

如果是这样,您如何获取上下文以及可用的绘图命令?

如果没有,是否有另一种方法可以通过其他可以与 Three.js 合作的 Three.js 或 WebGL 特定的绘图命令来完成此操作?

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

谢谢!

4

2 回答 2

11

您不能像使用常规画布那样直接绘制到 WebGL 画布。但是,还有其他方法,例如

  • 像往常一样绘制到隐藏的 2D 画布,并将其用作四边形的纹理并将其传输到 WebGL
  • 使用纹理映射的四边形绘制图像(例如你的健康框的框架)
  • 通过将顶点放置到 VBO 并使用适当的多边形类型绘制路径(和形状)来绘制路径(和形状)
  • 使用位图字体(基本上是带纹理的四边形)或真实几何图形(three.js 对此有示例和帮助程序)绘制文本

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

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

还请记住,您可以使用 CSS3 实现很多功能,例如圆角、alpha 透明度,甚至 3d 透视变换,如问题评论中 Anton 的链接所示。

于 2012-10-01T07:30:04.657 回答
10

我有完全相同的问题。我试图创建一个没有 DOM 的 HUD(平视显示器),我最终创建了这个解决方案:

  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/

于 2015-10-19T10:32:38.613 回答