Skip to content
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

Text rendering #152

Closed
asny opened this issue Oct 19, 2021 · 6 comments · Fixed by #491
Closed

Text rendering #152

asny opened this issue Oct 19, 2021 · 6 comments · Fixed by #491
Labels
enhancement New feature or request renderer In the renderer module

Comments

@asny
Copy link
Owner

asny commented Oct 19, 2021

Idea:

  • Create a texture atlas with all the letters (eg using fontdue)
  • Add a TextEffect that renders a given string (or single letters?) using uvs to index into the texture atlas
  • Use the effect to render the text into a Texture2D using a ColorTarget.
  • Use the Texture2D in some material, for example a ColorMaterial.
@Nevsden
Copy link

Nevsden commented Jan 22, 2023

Added text rendering in the most simple way using fontdue to create a text bitmap on request. Also added a simple example to render text on a sprite. Link #312

  • Added a text module under crate::renderer. Not sure, if this is the correct level.
  • Added a Font class, which reads in a ttf font using fontdue and can rasterize characters.
  • Added a TextEffect holding information on the text and text size to be rendered.

Issues so far with this solution:

  • Text is created by accessing Font::rasterize, which could be expensive. An interim struct to hold all possible characters in a texture atlas is probably the more efficient way.
  • Not sure, on which level in the crate to implement the text functionality.
  • Don't yet know, how to render text on a transparent background, such that the text is the only colorized object in its own visual scope.

@asny Could you direct me towards your solution? Then I can hopefully implement it on my own.

@asny
Copy link
Owner Author

asny commented Jan 23, 2023

Thanks for starting this 💪 I think it's a good idea to keep it simple, text rendering is a huge topic and not something I envision three-d to excel at. There are plenty of crates that specifically handles text and they can all be combined with three-d relatively easily. First option is to use a crate to render the text into an image which can then be converted into a Texture2D and rendered with three-d. The other option is to use a crate to convert the text into triangle data and then use three-d to render that triangle data.

Then there's the topic of dynamic text vs static text. If we want to handle dynamic text, ie. text that potentially changes every frame, then we'll have to worry a lot about performance. That's why I only want to support static text, at least for now.

So I envisioned this to be a simple integration with fontdue to render static text to a Texture2D which is also very much what you have done 👍 But I still wanted to hear your use-case, if you have one?

Text is created by accessing Font::rasterize, which could be expensive. An interim struct to hold all possible characters in a texture atlas is probably the more efficient way.

As long as we want to handle static text or text that changes rarely, I don't think it's a problem.

Not sure, on which level in the crate to implement the text functionality.

Just keep it were it is, it's fine for now 🙂

Don't yet know, how to render text on a transparent background, such that the text is the only colorized object in its own visual scope.

Use TextureData::RgbaU8 instead of TextureData::RU8 and set the rgb part to some color (for example black) and the alpha value to the output from fontdue. The ColorMaterial that uses the texture needs to be transparent (ColorMaterial::new_transparent).

Also:

  • I think it makes sense that it is a functionality on Texture2D so instead of Font::rasterize, we'll have Texture2D::new_with_text(text: &str, font: &fontdue::Font, size: f32, min_filter: Interpolation, ...).
  • Remove the TextEffect.
  • Note that Texture2D::new_with_text takes a whole string as input, not a single letter.
  • We should also be able to set the color of the text, just another input parameter?
  • How do we handle layout? Both meaning layout between letters and layout on the texture.
  • Please make the text example similar to the other examples so that it works on web.
  • Use three-d-asset::io::load_async to load the custom font so that it works on web.
  • Use include_bytes! to load the default font so that it works on web.
  • Make fontdue an optional dependency.

@Nevsden
Copy link

Nevsden commented Jan 23, 2023

Changed the struct TextEffect to hold a string instead of a single char. Further changed function rasterize to turn string instead of a char into a CpuTexture. Computation of the correct permutation from bitmap of each char to the unified TextureData::RgbaU8 brought a little confusion but I kinda solved it.

Further investigation needed on how to render the text with a CpuTexture without using Sprites.
Also need to look how to stretch text appropriately on the three-d::Texture2D level, once the CpuTexture has been consumed by the ColorMaterial::new_transparent function.

Also, todos from @asny still ongoing.

See #312

@serzhiio
Copy link

serzhiio commented Oct 4, 2023

Any updates here? It would be nice to have some examples.

@asny
Copy link
Owner Author

asny commented Oct 7, 2023

Yeah, I think it's abandoned by @Nevsden, but if anybody else wants to do it, feel free to continue from his work. However, since then, @BonsaiDen started a separate crate for rendering text with three-d which I think might be what you're looking for. See #376 for details 🙂

@asny asny mentioned this issue Oct 1, 2024
@asny asny closed this as completed in #491 Oct 1, 2024
@asny
Copy link
Owner Author

asny commented Oct 1, 2024

Added geometric text rendering support in #491

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request renderer In the renderer module
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants