Rendering 3D text


#1

Hello guys,

I’d like to have 3D text objects in my scene similar to simple 3d planes.

I’ve set up a Renderable3DTextComponent in the hello world demo.
Following the instructions I set the BlendMode to use AlphaBlend and DepthMode to ReadWrite.

What I’m experiencing is that if the text object transfrom z coordinate is less than equal to the sphere transfrom z coordnate I get nice glyphs with the expected transparent background, however if the text is closer to the camera I will have opaque frames around the glyphs.
(Please see 2 screenshots with the text “Hello world”)

I’m pretty sure this has to do with z-order or me not using the right combination of modes, but couldn’t figure it out. Any hints and tips would be appreciated.

I did a simple plane as well with a transparent texture just to double check the modes, that’s what I would expect from the texts.
(Please see the screenshot with the text: “Texture”)

Hope it makes sense, and let me know what I messed up :man_facepalming:

Many thanks.

            "Type": "nap::Entity",
            "mID": "Text3d",
            "Components": [
                {
                    "Type": "nap::Renderable3DTextComponent",
                    "mID": "nap::Renderable3DTextComponent",
                    "Text": "hello world",
                    "Font": "Font",
                    "GlyphUniform": "glyph",
                    "MaterialInstance": {
                        "Material": "FontMaterial",
                        "Uniforms": [],
                        "BlendMode": "AlphaBlend",
                        "DepthMode": "ReadWrite"
                    },
                    "Normalize": true
                },
                {
                    "Type": "nap::TransformComponent",
                    "mID": "nap::TransformComponent_5",
                    "Properties": {
                        "Translate": {
                            "x": 0.0,
                            "y": 0.0,
                            "z": 0.2
                        },
                        "Rotate": {
                            "x": 0.0,
                            "y": 0.0,
                            "z": 0.0
                        },
                        "Scale": {
                            "x": 1.0,
                            "y": 1.0,
                            "z": 1.0
                        },
                        "UniformScale": 2.0
                    }
                }
            ],
            "Children": []
        }
        {
            std::vector<nap::RenderableComponentInstance*> components_to_render;
            
            nap::RenderableMeshComponentInstance& renderable_world = mWorldEntity->getComponent<nap::RenderableMeshComponentInstance>();
            components_to_render.emplace_back(&renderable_world);
            
            nap::RenderableMeshComponentInstance& renderable_plane = mPlaneEntity->getComponent<nap::RenderableMeshComponentInstance>();
            components_to_render.emplace_back(&renderable_plane);
            
            nap::RenderableComponentInstance& renderable_text3d = mText3dEntity->getComponent<nap::RenderableComponentInstance>();
            components_to_render.emplace_back(&renderable_text3d);
            
            nap::PerspCameraComponentInstance& persp_camera = mPerspectiveCamEntity->getComponent<nap::PerspCameraComponentInstance>();
            
            mRenderService->renderObjects(mRenderWindow->getBackbuffer(), persp_camera, components_to_render);
        }


#2

Hi!

The glyph that is rendered is in theory just a set of textures. When rendering with alpha you generally don’t want to render them in the same pass as the rest of the objects.

I would recommend rendering the text after the other objects in the scene (sphere) and set the DepthMode to ReadOnly. So you call twice:

mRenderService->renderObjects()

First the sphere, second your text. The renderservice automatically sorts all objects in the render list based on distance, and that is something you probably don’t want when rendering 3D text in combination with actual objects in the scene.

If that doesn’t work can you share your app (source) here? I can take a look for you if you want.

Cheers!


#3

Thanks for taking the time to reply.

Your answer combined with the below article helped me understand why I got the results above and the challenges of rendering transparent objects in general.

http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-10-transparency/

Many thanks.


#4

Getting translucent objects to render properly can be tricky.

In general, you want to render opaque objects first, with depth read+write. In later, draw the translucent objects, with alpha blend + depth read. Make sure to disable depth write for translucent objects, or the artefact in your image (the background leaking through) may appear. Nap will sort opaque objects to the front of the list, and translucent objects will be z-sorted (I’m pretty sure) to be drawn back to front. This will give you decent translucents, similar to what most game engine do. You could take it a step further with bsp tree traversal, breaking up objects into smaller objects (which are sorted separately), making content adjustments, or order independent translucency (which you linked). I’d try setting up blending and depth properly first, and making content changes where needed. Order independent translucency is a huge hassle to set up, and is heavy on the gpu. BSP trees could be interesting for drawing large objects like windows etc, which are difficult to sort properly using a z-sort.


#5

Thanks for the clarification Marcel. NAP will indeed sort opaque objects front to back and translucent objects back to front.