32

I made a scene using the webgl renderer where I put multiple 3D objects that I can select and move. However when an object is selected, I'd like to draw its axes. No problem with drawing the lines to the center of the object but I'd like them to appear in front of anything else on the scene so that they are visible even if other objects are in front - Like in Blender.

I tried to play with the renderDepth param but I don't think I understood how to use it and I didn't get any result.

Thank you for your help.

gman
  • 100,619
  • 31
  • 269
  • 393
Scrubs
  • 373
  • 1
  • 5
  • 8

2 Answers2

87

If you want some objects to render "on top", or "in front", one trick is to create two scenes -- the first scene is your regular scene, and the second scene contains the objects that you want to have on top.

First, set

renderer.autoClear = false;

Then create two scenes

var scene = new THREE.Scene();
var scene2 = new THREE.Scene();

Add your objects to the first scene as usual, and add the objects you want to have "on top" to the second scene.

Then, in your render() function, do this:

renderer.clear();
renderer.render( scene, camera );
renderer.clearDepth();
renderer.render( scene2, camera );

This will render the first scene, clear the depth buffer, and then render the second scene on top.

three.js r.142

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • 2
    Thank you very much for your answer and your example. It answers exactly to my question. Cheers. – Scrubs Oct 01 '12 at 03:22
  • I really want to thank WestLangley too, This problem troubled me for a long time. – jasonjifly Dec 20 '12 at 06:28
  • Does this work if the renderer has a clear color set? When I try this, only the second scene appears, presumably because it's clearing when the render function is called a second time. – Justin Nov 14 '14 at 22:39
  • @Justin It does for me. Please make a new post if you need help. – WestLangley Nov 15 '14 at 03:30
  • @WestLangley Looks like I forgot the renderer.autoClear = false part. I got it working. Thanks. – Justin Nov 15 '14 at 15:37
  • @WestLangley Is there any way to have the second scene appear translucent, such that the first scene can still be seen through it? – Ben Jenkinson Mar 15 '16 at 14:03
  • @BenJenkinson Yes, depending on your use case and your requirements. – WestLangley Mar 15 '16 at 15:46
  • @WestLangley I've got a fairly standard use case. One scene. The 'main' camera renders to the whole canvas, and I want to render a second camera's viewpoint as a translucent ghost image in the corner. Something like this: http://jsfiddle.net/tnt8fvx7/1/ Now, I can achieve something like I want by looping through every object in the scene and briefly making the material translucent before the render of the second camera, but I'd rather just set one `.renderOpacity` property or something. – Ben Jenkinson Mar 16 '16 at 10:26
  • @WestLangley I am trying to render using StereoEffect -- effect = new THREE.StereoEffect(renderer); but when i subsequently do effect.render(scene, camera); followed by effect.render(scene2, camera); my scene2 overrides scene (i can't see scene) . Any idea what's the right way to doing this? – stackoverflowN Mar 30 '16 at 20:18
  • @stackoverflown Please ask the community in a new post. – WestLangley Mar 30 '16 at 20:34
  • @WestLangley Sure. Asked a new question http://stackoverflow.com/questions/36319340/overlay-objects-in-three-js-using-stereoeffect – stackoverflowN Mar 30 '16 at 20:45
  • @WestLangley this doesn't seem to work in the iOS Safari WebGL implementation. I am using this to render multiple non-depthtest single (at a time, changing on interaction...) material meshes and it doesnt seem to have an effect on iphone X Safari, but on android devices, Vive (Win10 chrome/firefox) and Oculus GO it works... – Manuel Graf Jul 20 '18 at 11:23
  • @WestLangley Does changing the render order like this affect the results of ray casting? In my testing it is not, though I prefer it would. – Scotty H Jul 26 '19 at 20:26
  • @WestLangley It's worth noting the second method will not work with opqua objects on top and other transparent objects in the scene as they are rendered in a second pass after opaque objects. With the first method my camera is child of the scene and I had some unexplained glitches while moving (camera position divergences) that I could only fix by using a second camera as child of the second scene (and copying position/quaternion values from the first camera). r127 – Florent Aug 31 '21 at 21:08
0

According to the answer mentioned here, you can use:

mesh.renderOrder = 999;
mesh.onBeforeRender = function( renderer ) { renderer.clearDepth(); };

If the mesh has a single material, it will render "on top".

Gangula
  • 5,193
  • 4
  • 30
  • 59