Three.js: Creating HUD over 3d Scene (WebGLRenderer) ?

Created on 29 May 2011  ·  19Comments  ·  Source: mrdoob/three.js

Hi

does anyone know what's the correct way to create a HUD layer (2d sprites, UI) over a 3d scene with THREE.js ? I want emulate a mouse-cursor and render some images over scene. My idea is creating an ortho-camera and using of sprites. but i don't know how i can layer this renderings over the main rendering. On the examples i found some "postprocessing", but i don't think this is the way to go.

Thanks
Remo

Question

Most helpful comment

I was working on a WebVR project and DOM solution wasn't an option. I ended up doing the HUD with pure Three.js. I created a separate scene and rendered that on top of my original scene.

You can see the live example here:
http://codepen.io/jaamo/pen/MaOGZV

And blog post about the solution here:
http://www.evermade.fi/pure-three-js-hud/

All 19 comments

Use HTML

+1 for HTML. You're developing for a platform _designed_ for UI; make use of it. :)

Actually I don't see why you SHOULDN'T use HTML! +1

Yep, unless it needs to be integrated in the 3d scene I would go with HTML on top of the canvas.

Thanks.
mrdoob, yes i want to integrate in the 3d scene. I want to use WebGL for some 2d graphics. But i didn't see a working sample to do this with THREE.js.

When you say "intergrate in the 3D scene" you mean you don't want the UI as an overlay on top of the 3D, righ?

I would simply use HTML for the GUI, so simply < div>'s etc on top of the < canvas> element...

If you want the GUI to be rendered with Three.js on top of your actual scene, I would use two canvas elements on top of each other, one for the game/scene/whatever, and the top one for the gui. You would need to ensure that the top one is transparent between the GUI elements, but I don't know if that is possible with Three.js...

Yes, for the most cases HTML is the way to go, it's much simpler.

If you do want to get fancy and have your HUD rendered by WebGL (e.g. for animated 3D or some shader effects), you could do something like this:

http://mrdoob.github.com/three.js/examples/webgl_rtt.html

(there is probably some way how to do it without FBO just playing with depth writing / reading / masking, at least for 2d overlays)

alteredq, thank you for this link. I currently haven't found a way with "playing". But i analyse the code on WebGLRenderer and found out that i can use something like that:

var sprite = new THREE.Sprite( { map: tex, useScreenCoordinates: true } );
scene.addChild(sprite);

This works.

But i'm still interested about the way with dual rendering and blending this.

I was working on a WebVR project and DOM solution wasn't an option. I ended up doing the HUD with pure Three.js. I created a separate scene and rendered that on top of my original scene.

You can see the live example here:
http://codepen.io/jaamo/pen/MaOGZV

And blog post about the solution here:
http://www.evermade.fi/pure-three-js-hud/

I am actually working on a HUD tool for webVR.
It's based on the StereoEffect.js that you can find in three.js examples.
It renders the two part of the first scene, then the two part of the HUD scene on overlay all with StereoEffectCamera that are PerspectiveCamera.

There is a demo with a crosshair and interaction with some elements in the scene.
https://github.com/trinketmage/three.js-vr-hud/

I am currently working on a "label" feature within the frustum of the HUD scene, i would appreciate any tips or any help.
Thanks

If someone is still looking for how to render an Ortho scene on top of a perspective one (so you can align objects to top/left/right/bottom borders or have sizes in pixels), I had an example there.

@cecilemuller - your project does not allow me to open issues so I'm commenting here. Does it work? http://jsbin.com/sisutopede/edit?html,js,output (I replaced let const with var) I can only see a blue sphere, I don't seem to see any UI elements?

@trinketmage - thank you for creating fantastic demo / plugin and taking time to explain issue 1, right now I'm trying to figure issue 2: https://github.com/trinketmage/three.js-vr-hud/issues/2 - it works flawlessly when I'm using keyboard, the moment I start using my mobile device / Chrome Dev Tools and simulate orientation it is jumping...


On a sidenote - enough of copy & paste - at some point I should be able to write my own code given all the knowledge in this thread...

@stefek99 It should be showing colored rectangles on top of the blue sphere; just tried the jsbin in chrome and firefox, here's a screenshot:
screenshot

Although yes, there are some es6 features in the code, ,so you can use the Babel REPL to convert to es5 if it's not running.

It's 2020, what is the best way to create 2D HUD overlay inside ThreeJS without using hybrid or weird methods? Ideally to have access to something like PixiJS inside ThreeJS?

@sylwesterdigital You can use the three.js forum if you need help.

Yea... I've been there and my account is on hold, so I can not comment, reply or create new topics. Is ThreeJS community going to nowhere and everyone is coding f* React to have a monthly payment?

After years of mooing around, I guess that there is no absolute ways to do hud in WebGL, it totally depends on project, but my thought are:

  • If you don't need specific effects on HUD, go for HTML, there is a "compositing cost" but as long as you don't have too much overlay (if i use 4 times/ 5 times sizes of screen overlays it get laggy on Chrome with Mac Book Pro Retina mid 2015), example of a HUD in html : demo waysmaze.
  • if you need it to be in the gl for whatever reason, I would put it directly a Group that each frame would be place in front of the camera rendered on top of everything; Calculate the extents of the group from the camera at a specific z distance on resize to place the item on top/right/bottom/left; This ways give flexibility to make use of the perspective (if you need 3D elements in HUD) or not and i guess it should be the lowest cost for performance (please correct me if i'm wrong).
  • The more "logical" way @sylwesterdigital, in my opinion, would be to do a second render (wether Orthographic or Perspective) on top of the scene as a texture inside the same scene; But the huge downside is that it is the less performance wise way cause a second renderer of size of screen multiplied by the pixel ratio, or, if HUD renderer is smaller you lose quality.
  • Pixi.js on top of Three.js is a bad solution @sylwesterdigital, cause I guess you would have 2 WebGL instances and I guess it is heavy ?
  • Good old canvas on top of three.js should work also, one of my amazing coworkers @namide taught me a huge developer lesson: "how would they optimize it for videogame ?", in Unity, common ways to handle HUD is to CanvasRenderer on top of everything.

So in conclusion, in my opinion, the HUD visual components should depend on what cost of performance you can afford.

Was this page helpful?
0 / 5 - 0 ratings