vsg-dev / VulkanSceneGraph

Vulkan & C++17 based Scene Graph Project
http://www.vulkanscenegraph.org
MIT License
1.32k stars 212 forks source link

vsg::Text - rendering issues / questions #1311

Open Jersey-Girl opened 3 weeks ago

Jersey-Girl commented 3 weeks ago

I'm having 2 issues with vsg::Text, both of which can be seen with the vsgtext example:

1. Can't turn off outlines?

We don't want outlines on our text.

Setting layout->outlineWidth to 0. did not make the outline disappear.
Is this a bug?

As a work-around, I set layout->outlineColor to layout->color.

2. Glyph "remnant" and inaccurate bounding box

I am porting code written for osg::Text.
The code relies on the ability to get an accurate, exact bounding box of
the rendered text.

After porting to vsg::Text, what I first observed was that the bounding
box of the vsg::Text object was "padded".

That led ultimately to observing what I call the glyph "remnant" in
the rendered text.

The padded bounding box includes this remnant.
(And possibly the width of an outline that's not supposed to be there?)

The glyph "remnant" can be seen in the vsgText example by making these
small changes in vsgText.cpp:

    - Set 'clearColor' to vsg::vec4(1.0f, 1.0f, 01.0f, 1.0f)

    - In the "if (render_all_glyphs)" clause, set
         layout->color = vsg::vec4(1.0f, 0.0f, 1.0f, 1.0f);

      (this clause is triggered by the CLI --all)

For my application, I have to solve both of these issues.
I need clean rendered text and an exact bounding box of that rendered
text.

Is this possible?

Thank you

robertosfield commented 3 weeks ago

vsgtext has text that has outlines as well as without outlines, zooming into the text on the top left that doesn't have outlines:

image

Is this not what you see? I'm using Kunbuntu 24.04 with Geforce 1650 on this system.

When you say ruminant could you provide an example of what you mean.

As for bounding boxes, vsg::Text was not written to be a drop in replacement for osg::Text, the public API and back-end implementations are very different. I can't comment on what you believe to be bounding padding, it's just written to render text and provide enough of bound for culling purposes.

Without knowing specifically what you having an issue with and track it back to associated code I can't provide guidance on whether it's a bug that can be fixed or just a different behavior that will require you to work a little bit different with.

Jersey-Girl commented 3 weeks ago

vsgText-glyph-remnant

This is the vsgtext example with a white clear color and magenta text color.
Can you see the grayish lines? that's what I am calling glyph remnants. With lighter backgrounds, they are very evident. Also, with these colors, if you play with outline width, it appears to me that you never "lose" it entirely.

And in my application, where I was able to draw the bounding box computed on my vsg::Text, it was very clear the glyph remnants were part of it.

robertosfield commented 3 weeks ago

I had a bash at reproducing the issue by running 'vsgtext --clear 1 1 1 1 --all' and modifying the example. It would be helpful for you to explain what tests you are doing so we can recreate it without guess.

Zoomed into the text everything looks correct: image

When I zoom out and the text starts getting minified I start seeing an outline image

What this looks like is bleed from neighbouring glyphs in the SDF texture atlas. Increasing the margin of the SDF texture alas would be one way of dealing with this. It might be possible to adjust shader code to better avoid this. I do wonder if some graphics cards/drivers have slightly different filter implementations so for some it's more obvious.

As for the "glyph remnants" you haven't explained what you mean by "remnants", it's not a term of art, so could you explain what you mean, using the same words a second time won't help me when the first time I asked for clarification I didn't understand what you meant.

Jersey-Girl commented 3 weeks ago

I would say my "glyph remnants" are your "bleed from neighbouring glyphs in the SDF texture atlas". The only "testing" I did was to change the colors in vsgtext.cpp to more clearly see the bleed.
I saw the "bleed" as soon as the application ran. I did see that if I zoomed in, the bleed stopped, but differently for each string?

robertosfield commented 3 weeks ago

You were using the glyph remnants in the context of the bounding box, which doesn't change whether you're zoomed in or zoomed out. Could you be you're mixing terms?

The bounding box encompasses the quads that are used to render each glyph, the quad size is larger than the glyph so that any additional outline and blending can be rendered. Could this be why you aren't see exactly the bounding box you are expecting? The bounding box can be used for culling so needs to encompass the whole quads not inner glyph part that I'm guessing you are assuming is the bounds of the text.

The texture edges you seeing is seeing when the glyph is being minimized is a filter issue, which should be solvable by increasing the margin between the glyphs when the vsgXchange::freetype loader generates the SDF for a font. You can list the controls that you can pass in via vsg::Options when loading fonts by using vsgconv --features:


$ vsgconv --features vsgXchange::freetype
vsgXchange::freetype provides support for 11 extensions, and 0 protocols.
    Extensions      Supported ReaderWriter methods
    ----------      ------------------------------
    .cef            read(vsg::Path, ..) 
    .cff            read(vsg::Path, ..) 
    .cid            read(vsg::Path, ..) 
    .fnt            read(vsg::Path, ..) 
    .fon            read(vsg::Path, ..) 
    .otf            read(vsg::Path, ..) 
    .pfa            read(vsg::Path, ..) 
    .pfb            read(vsg::Path, ..) 
    .ttc            read(vsg::Path, ..) 
    .ttf            read(vsg::Path, ..) 
    .woff           read(vsg::Path, ..) 

    vsg::Options::Value  type
    -------------------  ----
    quad_margin_ratio    float
    texel_margin_ratio   float
~~~ sh

Perhaps tweaks to the shaders might help as well.
Jersey-Girl commented 3 weeks ago

Robert, I am sure I am mixing terms!
I am coming at this from the point of view of porting our existing code based on OSG to VSG.
As you have pointed out, osg::Text and vsg::Text are vastly different, so it's been a challenge. The ported code is more or less working except for the "texture edges" and bounding box issues. In OSG, it was possible to get what I call an exact bounding box of the rendered text.
There is code using those exact bounding boxes to compute positions of other objects relative to the text object. Since the VSG bounds are not exact, it's been hard to make the OSG and VSG "renderings" match. Also, in OSG, we never saw any "texture edges". I will attempt to set those options and see what happens.

Jersey-Girl commented 3 weeks ago

Robert, I did play with those 2 options, and while I could get a bounding box that was way more exact than I got with the default values of these 2 options, I never hit on a combination of values that got rid of the texture edges completely. So for now, I've settled on values that minimize the bounding box. When you said tweaks to the shaders, did you mean vsg::Text's shaderSet?

robertosfield commented 2 weeks ago

Unfountantely I'm too stretch with DIY work rebuilding my office and other development to look into refining the vsg::Text at this point.

On the bounding box front it may be appropriate to compute a tight bound box around just the core glyph geometry as well as the one that encompasses the whole quad used for rendering.

The filtering issues will require work on shaders to better clip out samples from adjacent glphs during minificiation.

You are welcome to tinker to come up with changes that work for you and post them as PR and I can review and amend or advice how to get them in a ready for merging with VSG master.

The whole VSG codebase is under this type of refinement, big chunks of functionality do get added/amended but most of the work is refinements/improvements of existing codebase to better fit for how users are utilizing the VSG in their applications. As the VSG user base grows so does the envelope that developers require from it.