-
-
Notifications
You must be signed in to change notification settings - Fork 21k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Label3D node. #60386
Implement Label3D node. #60386
Conversation
|
All should be fixed now. |
And it's possible to control a "depth" (volume on z axis) for the symbols in that label? If not, that would be interesting to add. |
No, with this approach, each glyph is a flat quad with a character texture, so there's no depth. There's a way to get Bézier shapes from the font (if it's a dynamic font), but they should be converted to polygons, triangulated and "extruded" to form a mesh. And last time I have checked, the triangulation algorithm included in the Godot wasn't working well on polygons with holes, so it might need much more work. Also, intersections of the chars probably will need some care to seamlessly connect. I was thinking about implementing this as well, but probably as a separate |
I did a quick test, it works great so far! With custom fonts generated using tools such as Fontello, it's possible to use arbitrary monochrome vector graphics: Using the generated mesh AABBs, it's possible to position Label3Ds relative to each other via code. Make sure to use simplescreenrecorder-2022-04-20_15.51.25.mp4Example with MSDF fonts (Godot icon is broken here, but font is OK): MSDF fonts look better when up close, but also when far away as they don't get grainy like DynamicFonts do. Testing project: test_label_3d_1.zip With the latest revision of this PR, creating a Label3D for the first time results in the following error message:
Some more feedback:
Edit: Disregard the accidental assignment below. |
@bruvzg You are just too awesome. |
Screen.Recording.2022-04-21.at.15.54.39.mov |
That's a common issue most SVG to font / MSDF tools have, and related to the multiple overlapping color layers in the source icon. Converting source SVG to the single monochrome path usually helps: <svg width="1024" height="1024" xmlns="http://www.w3.org/2000/svg"><path style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.33333" d="M417.615 76.875c-42.392 9.424-84.326 22.545-123.642 42.334.899 34.716 3.143 67.98 7.693 101.768-15.268 9.782-31.315 18.177-45.576 29.628-14.49 11.148-29.29 21.813-42.41 34.85-26.212-17.337-53.955-33.63-82.535-48.012C100.337 270.6 71.53 306.383 48 346.428c18.493 29.029 38.33 58.205 56.7 80.959v245.765c.449.004.898.021 1.343.063l150.67 14.527a16.223 16.223 0 0 1 14.627 15.024l4.646 66.51 131.43 9.376 9.055-61.384a16.222 16.222 0 0 1 16.05-13.858h158.961c8.047 0 14.873 5.899 16.047 13.858l9.055 61.384 131.434-9.377 4.642-66.51a16.23 16.23 0 0 1 14.627-15.023l150.611-14.527c.446-.042.89-.059 1.34-.063v-19.611l.063-.02V427.387c21.216-26.71 41.307-56.172 56.699-80.96-23.523-40.044-52.345-75.828-83.152-108.984-28.573 14.382-56.325 30.675-82.537 48.012-13.117-13.037-27.89-23.702-42.4-34.85-14.258-11.45-30.324-19.846-45.563-29.628 4.537-33.788 6.78-67.052 7.683-101.768-39.32-19.79-81.249-32.91-123.662-42.334-16.933 28.46-32.42 59.28-45.906 89.408-15.993-2.672-32.06-3.662-48.149-3.853v-.026c-.112 0-.216.026-.312.026-.1 0-.205-.026-.305-.026v.026c-16.117.191-32.17 1.18-48.168 3.853-13.478-30.129-28.955-60.948-45.914-89.408zM298.416 436.398c50.151 0 90.799 40.618 90.799 90.752 0 50.168-40.648 90.809-90.799 90.809-50.126 0-90.787-40.64-90.787-90.809 0-50.134 40.66-90.752 90.787-90.752zm427.178 0c50.122 0 90.779 40.618 90.779 90.752 0 50.168-40.657 90.809-90.78 90.809-50.159 0-90.806-40.64-90.806-90.809 0-50.134 40.647-90.752 90.807-90.752zm-418.498 35.87c-33.285 0-60.27 26.993-60.27 60.27 0 33.275 26.985 60.245 60.27 60.245 33.3 0 60.271-26.97 60.271-60.246s-26.97-60.27-60.271-60.27zm409.78 0c-33.275 0-60.235 26.993-60.235 60.27 0 33.275 26.96 60.245 60.236 60.245 33.31 0 60.271-26.97 60.271-60.246s-26.962-60.27-60.271-60.27zm-204.882 17.24c16.143 0 29.254 11.908 29.254 26.56v83.59c0 14.665-13.111 26.563-29.254 26.563-16.142 0-29.226-11.898-29.226-26.563v-83.59c0-14.652 13.084-26.56 29.226-26.56zM104.451 705.66c.063 14.561.248 30.514.248 33.69 0 143.085 181.512 211.86 407.026 212.65h.553c225.513-.79 406.962-69.565 406.962-212.65 0-3.235.195-19.12.262-33.69l-135.43 13.063-4.668 66.865c-.562 8.059-6.972 14.472-15.03 15.05l-160.49 11.452c-.39.029-.782.043-1.17.043-7.975 0-14.856-5.853-16.034-13.862l-9.203-62.416H446.525l-9.203 62.416c-1.236 8.4-8.746 14.44-17.205 13.819L259.63 800.639c-8.059-.579-14.47-6.992-15.031-15.051l-4.666-66.865-135.48-13.063z"/></svg> |
Awesome 🙂 Would it be possible to expose the texture filtering mode as is done in BaseMaterial3D? This would make it possible to enable mipmaps, preventing DynamicFonts from looking grainy at a distance when they're not using a fixed size. This would also allow for enabling anisotropic filtering to improve text appearance at oblique angles (when billboarding is disabled). Of course, the above isn't a concern when using MSDF, but I assume some people will still favor DynamicFonts in Label3D for various reasons. (The filter mode property should probably be ignored when a MSDF font is in use, unless there's a good reason not to.) This texture filtering property is also a change that could be done for Sprite3D: #50592 |
@@ -2479,6 +2558,7 @@ void BaseMaterial3D::_bind_methods() { | |||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo"); | |||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO); | |||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB); | |||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "albedo_tex_msdf"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_MSDF); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should those properties be hidden from the BaseMaterial3D inspector, as this will be mainly used by Label3D? I'm not sure if people will actually be specifying MSDF textures to use directly in a BaseMaterial3D. Same for msdf_pixel_range
and msdf_outline_size
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if there are any real use cases for it, but it's possible to generate MSDF texture using an external tool like msdfgen
and apply it to anything.
I'll check it tomorrow. In addition to exposing the material settings, this probably will require mipmap generation to be enabled in the |
Looks awsome! I'd perhaps suggest a bill board option to always show the text towards you but to stay in place. It would be useful for waypoints, area markers, signs etc? If I recall correctly it can be done through the transformation matrix somehow... did it ages ago for a particle system i think. |
Fun fact: overlapping Label3Ds with slight offset and color changes for each layer can be used for a pseudo-3D effect 🙂
There's already a Billboard enum property available in Label3D. Am I missing a difference with the current billboard modes (Billboard and Y-Billboard)? Are you asking for a billboard mode relative to the camera camera instead of the view plane? This could be added in the future, but it's not the best fit for text. I took some time to test the latest revision of this PR.
In comparison, here it is with alpha scissor set to 0.5:
The wireframe view seems to confirm this: To resolve this issue, could the outline vertices be slightly offset from the main font when the Alpha Cut property is Discard? The outline would then be drawn behind the main font. Using an offset of
label3d-normals.mp4
(This is the reason for the text on the screenshot below being cut off.)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a label and aside from not having a default font, the Label3D worked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested the latest revision of this PR, everything seems to be working great 🙂
Testing project: test_label_3d_2.zip
I think I got glyph outlines convex decomposition / triangulation working (at least with the proper fonts, without self-intersection), so the most complex part is done. Still needs a bit of work to get rid of glyph-to-glyph intersections, but from this point, mesh generation should be simple. Probably will make a second PR for the |
Text mesh generation PR draft - #60507 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, and amazing feature!
Thanks! |
Wow, this is really an incredible new feature! I just gave it a quick test and there is really nothing I could think of left desired! Huge thanks to @bruvzg (also to @Calinou for the continuous testing) May I ask what the reason was for limiting the font size to 127? I'm not sure where to ask for this, because this seems like too small of a request to open a proposal for, but would it be possible to have the |
The limit is copy-pasted from the importer settings, probably should be changed to
It's separate properties in the |
For rasterized DynamicFonts, this might cause a freeze if the user enters a very large value like |
Because Godot has to render (rasterize) each Glyph of the font? |
Yes.
The issue is that this can cause stuttering during gameplay, especially on slower CPUs (font rasterization is done by FreeType on the CPU). This is especially noticeable on mobile devices, and it can result in difficult-to-diagnose slowdowns for people who aren't aware of this. Enabling prerendering of the ASCII range by default for all fonts would alleviate this issue in most situations, at the cost of increased startup times. I'm personally in favor of it, as I feel the benefits outweigh the downsides. |
I don't think this is an issue at all. Setting font size is typically an editor usecase. All it needs is proper documentation which mentions something like: "If you set the fontsize during runtime, Godot needs to render (rasterize) the every glyph of the font. For large font sizes, this will lead to a freeze until the work is done. Consider using separate threads when you want to set large font sized during gameplay. -> links to the background loading and threads docs" |
What I mean is that if you use a rasterized DynamicFont, each glyph will be rasterized the first time it is used. During gameplay, if a string changes and requires many new glyphs to be rasterized in a single frame, this can take a long time with large font sizes. To make things worse, if the strings displayed depend on user input, the developer may never notice this issue during playtesting. For instance, a player entering a long chat message in a multiplayer game could trigger this issue for all other players. This stuttering would only occur once per gameplay session, but it's still something we should try to eliminate. This problem has already been encountered by numerous users, especially on mobile platforms. This is why Note that due to how FreeType works, font rasterization performance largely depends on the power of 2 of the font size. Font sizes between 16 and 31 are fast to render, 32 to 63 is average, 64 to 127 is slow. Sizes between 128 and 255 will be very slow, and sizes above 256 should probably not be used in a game. Even if you prerendered such a font, it'd probably take several seconds, so it's not viable unless a font disk caching system is implemented. |
Is it possible to use BBcode formatting? I guess that'd require a separate node - RichLabel3D? |
No, and implementing something like RichTextLabel3D would be a lot of work. I don't think it's on the cards for 4.0. You can use the workaround I mentioned above if you need text with multiple colors within. As for the depth test issue, please open a new issue with a minimal reproduction project attached. |
Implements godotengine/godot-proposals#3219
Label3D
node, with most of theLabel
features (except overrun, and visible characters).generate_mipmap
font import option.Sprite3D
.A minor convenience for normal fonts, but required to properly render MSDF fonts at arbitrary scale without 2D-in-3D viewport resolution restrictions.
MSDF font zoom - click to expand
Screen.Recording.2022-04-20.at.10.24.46.mov