使用Three.js将UI元素直接绘制到WebGL区域

Dev*_*Dev 12 user-interface hud webgl three.js

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

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

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

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

谢谢!

Tap*_*pio 11

您无法以与使用常规画布相同的方式直接绘制到WebGL画布.但是,还有其他方法,例如

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

使用这些通常意味着设置正交相机.

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

还要记住,你可以用CSS3实现很多功能,例如圆角,alpha透明度,甚至是3D透视变换,如问题评论中Anton的链接所示.


小智 7

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

  1. 我用正交相机创建了一个单独的场景.
  2. 我创建了一个canvas元素,并使用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 );
Run Code Online (Sandbox Code Playgroud)

这就是我添加到渲染循环中的内容:

// Render HUD on top of the scene.
renderer.render(sceneHUD, cameraHUD);
Run Code Online (Sandbox Code Playgroud)

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

在我的博客上阅读有关实施的更多信息:http: //www.evermade.fi/pure-three-js-hud/