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

Text2d visibility fix #9708

Closed
wants to merge 6 commits into from

Conversation

ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Sep 6, 2023

Objective

Text drawn with Text2d isn't visible in main.

fixes #9676

Solution

Add an ExtractedSpriteBatches resource that allows the extraction of sprites in batches that all share the same entity for visibility checks.

In extract_text2d_sprite extract to ExtractedSpriteBatches rather than ExtractedSprites.

This is a bit of a hack but it's harmless and minimal.

My first attempt had three buffers:

  1. Set of all Text2d entities with their Entity, Transform, and a range into buffer 2.
  2. Vec of ExtractedGlyphSections. Each ExtractedGlyphSection has a handle for the font's atlas texture, color, and a range of indices into buffer 3.
  3. Vec of ExtractedGlyphs. Each ExtractedGlyph has a position (relative to the transform) and a Rect containing coords of the glyph in the font's atlas texture.

I struggled to get it to work though. It was almost there but there were some weird texturing issues I couldn't work out even after spending half a day on it:

Capture-text2d ---

I still don't understand Bevy's rendering internals very well, so it could be anything.

Anyway, I decided to switch approach. This PR is deliberately as simple as I could make it. It fixes Text2d rendering and shouldn't introduce any new problems or have any significant performance costs. The implementations of ExtractedSpriteBatches and extract_text2d_sprites aren't super efficient, but naive benchmarks suggest this Text2d is faster than 0.11.2's Text2d by about 5-10% (probably entirely due to the improvements in bevy_sprites).

cargo run --profile stress-test --features trace_tracy --example many_sprites
Capture-many-sprites

(yellow is this PR, red is main)

The main drawback is that ExtractedSpriteBatches is exposed as public, I'd rather have kept it private as it's not really suitable for much else except text rendering.


Changelog

  • Added ExtractedSpriteBatches.
  • Modified queue_sprites and prepare_sprites so they also add the sprites from ExtractedSpriteBatches.
  • extract_text2d_sprite extracts to ExtractedSpriteBatches instead of ExtractedSprites.

…that all share the same entity for visibility checks.

Then `extracted_text2d_sprite` extracts into `ExtractedSpriteBatches` instead of `ExtractedSprites` and text drawn with `Text2d` is visible again.
@alice-i-cecile alice-i-cecile added C-Bug An unexpected or incorrect behavior A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets P-High This is particularly urgent, and deserves immediate attention labels Sep 6, 2023
@alice-i-cecile alice-i-cecile added this to the 0.12 milestone Sep 6, 2023
@@ -590,6 +597,38 @@ pub fn queue_sprites(
});
}
}

for (batch_entity, sprite_entities) in extracted_batches.batches.iter() {
if !view_entities.contains(batch_entity.index() as usize) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use a bit of a comment: it's really quite unusual to care about the index of an Entity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code wasn't commented either, I'm confident these changes work and don't mess anything up but I don't know enough about the rendering internals to be explaining anything to anyone I think.

@JMS55 JMS55 requested a review from superdump September 6, 2023 00:30
@@ -333,6 +333,27 @@ pub struct ExtractedSprites {
pub sprites: SparseSet<Entity, ExtractedSprite>,
}

/// Allows extraction of multiply sprites for a single entity that all share that entity's id for visibility resolution.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Allows extraction of multiply sprites for a single entity that all share that entity's id for visibility resolution.
/// Allows the extraction of multiple sprites sharing the same entity id for visibility resolution.

I think there's a typo here (multiply -> multiple). I'm also leaving a suggestion to rephrase the comment, hopefully it still conveys the same meaning.

@rparrett
Copy link
Contributor

I'm assuming that this needs a major rework after #9685 and #9903?

@superdump
Copy link
Contributor

I prefer #10100 if it fixes the same problem.

@superdump
Copy link
Contributor

Closing due to merging #10100 If that PR doesn’t address the problem, you’re welcome to come shout at me. 💜

@superdump superdump closed this Oct 13, 2023
github-merge-queue bot pushed a commit that referenced this pull request Oct 13, 2023
# Objective

Fixes #9676
Possible alternative to #9708

`Text2dBundles` are not currently drawn because the render-world-only
entities for glyphs that are created in `extract_text2d_sprite` are not
tracked by the per-view `VisibleEntities`.

## Solution

Add an `Option<Entity>` to `ExtractedSprite` that keeps track of the
original entity that caused a "glyph entity" to be created.

Use that in `queue_sprites` if it exists when checking view visibility.

## Benchmarks

Quick benchmarks. Average FPS over 1500 frames.

| bench | before fps | after fps | diff |
|-|-|-|-|
|many_sprites|884.93|879.00|🟡 -0.7%|
|bevymark -- --benchmark --waves 100 --per-wave 1000 --mode
sprite|75.99|75.93|🟡 -0.1%|
|bevymark -- --benchmark --waves 50 --per-wave 1000 --mode
mesh2d|32.85|32.58|🟡 -0.8%|
ameknite pushed a commit to ameknite/bevy that referenced this pull request Nov 6, 2023
# Objective

Fixes bevyengine#9676
Possible alternative to bevyengine#9708

`Text2dBundles` are not currently drawn because the render-world-only
entities for glyphs that are created in `extract_text2d_sprite` are not
tracked by the per-view `VisibleEntities`.

## Solution

Add an `Option<Entity>` to `ExtractedSprite` that keeps track of the
original entity that caused a "glyph entity" to be created.

Use that in `queue_sprites` if it exists when checking view visibility.

## Benchmarks

Quick benchmarks. Average FPS over 1500 frames.

| bench | before fps | after fps | diff |
|-|-|-|-|
|many_sprites|884.93|879.00|🟡 -0.7%|
|bevymark -- --benchmark --waves 100 --per-wave 1000 --mode
sprite|75.99|75.93|🟡 -0.1%|
|bevymark -- --benchmark --waves 50 --per-wave 1000 --mode
mesh2d|32.85|32.58|🟡 -0.8%|
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
# Objective

Fixes bevyengine#9676
Possible alternative to bevyengine#9708

`Text2dBundles` are not currently drawn because the render-world-only
entities for glyphs that are created in `extract_text2d_sprite` are not
tracked by the per-view `VisibleEntities`.

## Solution

Add an `Option<Entity>` to `ExtractedSprite` that keeps track of the
original entity that caused a "glyph entity" to be created.

Use that in `queue_sprites` if it exists when checking view visibility.

## Benchmarks

Quick benchmarks. Average FPS over 1500 frames.

| bench | before fps | after fps | diff |
|-|-|-|-|
|many_sprites|884.93|879.00|🟡 -0.7%|
|bevymark -- --benchmark --waves 100 --per-wave 1000 --mode
sprite|75.99|75.93|🟡 -0.1%|
|bevymark -- --benchmark --waves 50 --per-wave 1000 --mode
mesh2d|32.85|32.58|🟡 -0.8%|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen A-UI Graphical user interfaces, styles, layouts, and widgets C-Bug An unexpected or incorrect behavior P-High This is particularly urgent, and deserves immediate attention
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Text2d is broken
6 participants