• 3D
  • Unconditionally draw object over rest of scene

Hi there,

I wonder if it was somehow possible to ensure that a certain 3D object gets always drawn over the rest of the scene, regardless of its actual distance. Background is, I'm trying to implement a VR reticle which will be displayed as a circle drawn onto a 3D sprite and which will always be located so that its center matches the intersection point of a ray cast from the camera's origin towards the (local) -z direction with any object which happens to be in the ray's way. However, if the target object's surface is not exactly perpendicular to the ray, the reticle's drawing will be partially hidden by the object. In 2D, it can be ensured that HUD elements are always visible (i.e. drawn last) by using canvas layers, but there seems to be no such option for 3D scenes. Are there any alternatives?

Cheers -- Torsten

Godot is new for me, but maybe you can just render this object to a viewport and layer this on top of the rest of your scene.

Yes, that is certainly one(probably best?) way to go, I'd just add that the viewport should be rendered on the UI/2D layer for intended effect, at the very top so other UI elements don't draw over it either.

Hi,

I'm not quire sure if the viewport approach can be of help regarding the issue at stake. In order to be visible, the scene rendered inside the additional viewport must be "projected" onto some object contained in the main viewport's space, e.g. by applying a viewport texture to a sprite or a mesh which has a fixed location relative to the main camera in order to appear as HUD. This projector object would then again be subject to the possibility of being occluded by other objects if they happen to be closer to the camera than the projector. What I'm actually after is a Godot equivalent to the UIOverlay.shader mentioned in https://unity3d.com/learn/tutorials/topics/virtual-reality/interaction-vr#reticle

Cheers -- Torsten

Have you tried disabling the depth test in the SpatialMaterial of the elements you want visible?

If I recall correctly, by disabling the depth test the mesh with the material should always be drawn on top of everything regardless of whether it would normally be occluded by another object.

TwistedTwigleg,

@TwistedTwigleg said: Have you tried disabling the depth test in the SpatialMaterial of the elements you want visible?

If I recall correctly, by disabling the depth test the mesh with the material should always be drawn on top of everything regardless of whether it would normally be occluded by another object.

thanks for the hint, but unfortunately it didn't work out. I'm using a 3D sprite with a transparent viewport texture, but when I add a material (a material override, actually; I have to tick the "Transparent" and "Unshaded" checkboxes to retain the original look) and disable the depth test, nothing changes -- it didn't help keeping the sprite in front of all other objects.

Cheers -- Torsten

Hmm, I suppose one way you could get around the issue is by using two Viewport nodes. I've done it before, for this tutorial, but I didn't really go over the topic of setting up the Viewport nodes because it is kinda confusing and fiddly, and I didn't want to add extra complexity to what was already going to be a somewhat complicated tutorial subject.

I don't remember exactly what I did to make the two Viewport nodes work, but perhaps downloading and poking around the project you'll be able to find out. I do remember that getting physics to work on both Viewport nodes was interesting and took a lot of trial and error. I also remember that keeping the camera's in sync required writing some GDScript, as the RemoteTransform node had issues.

Other than that, I'm not sure.

I'm not too experienced with shaders, but it is also possible that you could write a shader that performs similarly to the UIOverlay shader in Unity. If you want to go the shader route, I would look and see if you can find a GLSL shader that works like the UIOverlay shader, and then see if you can port the GLSL code to Godot's Shader code.

Hopefully this helps!

TwistedTwigleg,

@TwistedTwigleg said: Hmm, I suppose one way you could get around the issue is by using two Viewport nodes. I've done it before, for this tutorial

just downloaded the project and had a brief look into the node tree's structure -- interesting! If I understand correctly, the outer viewport/camera contains the bottom UI part as well as a second viewport/camera combination which renders the actual 3D scene, right? That's the opposite approach of what I've always been thinking of -- I could only imaging positioning the UI viewport somewhere inside the 3D scene... So maybe your's is the way to go, at least for HUD elements!

For the reticle, I'll further investigate the shader route since it should really appear as living in (stereoscopic) 3D space, with the only additional requirement that it should never be occluded by any other object.

Thanks, I'll mark this thread as answered!

Cheers -- Torsten

Heureka! I think I found it! "No depth test" in combination with an increased render priority (also in the SpatialMaterial's properties) did the trick!

Great! I’m glad you were able to get it working :smile: