【问题标题】:Drawing UI elements directly to the WebGL area with Three.js使用 Three.js 将 UI 元素直接绘制到 WebGL 区域
【发布时间】:2012-09-21 23:04:54
【问题描述】:

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

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

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

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

谢谢!

【问题讨论】:

标签: user-interface webgl three.js hud


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 很好的答案,谢谢.. 还请参阅上面的 cmets,因为 Anton 和 WestLangley 有一些很好的见解
  • hmmmm......我想知道将我的页面的整个背景设为一个空的 webgl 画布是否会迫使浏览器根据您的评论加速一切。出于某种原因,我认为它不会起作用。
【解决方案2】:

我遇到了完全相同的问题。我试图创建一个没有 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/

【讨论】:

  • 感谢您提供清晰的示例。虽然我建议使用 OffscreenCanvas (chrome m69+) 而不是 document.createElement('canvas')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
相关资源
最近更新 更多