Skip to content

Add TilemapChunk rendering #18866

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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

ConnerPetzold
Copy link

@ConnerPetzold ConnerPetzold commented Apr 17, 2025

Objective

An attempt to start building a base for first-party tilemaps (#13782).

The objective is to create a very simple tilemap chunk rendering plugin that can be used as a building block for 3rd-party tilemap crates, and eventually a first-party tilemap implementation.

Solution

  • Introduces two user-facing components, TilemapChunk and TilemapChunkIndices, and a new material TilemapChunkMaterial.
  • TilemapChunk holds the chunk and tile sizes, and the tileset image
    • The tileset image is expected to be a layered image for use with texture_2d_array, with the assumption that atlases or multiple images would go through an asset loader/processor. Not sure if that should be part of this PR or not..
  • TilemapChunkIndices holds a 1d representation of all of the tile's Option index into the tileset image.
    • Indices are fixed to the size of tiles in a chunk (though maybe this should just be an assertion instead?)
    • Indices are cloned and sent to the shader through a u32 texture.

Testing

  • Initial testing done with the tilemap_chunk example, though I need to include some way to update indices as part of it.
  • Tested wasm with webgl2 and webgpu
  • I'm thinking it would probably be good to do some basic perf testing.

Showcase

let chunk_size = UVec2::splat(64);
let tile_size = UVec2::splat(16);
let indices: Vec<Option<u32>> = (0..chunk_size.x * chunk_size.y)
    .map(|_| rng.gen_range(0..5))
    .map(|i| if i == 0 { None } else { Some(i - 1) })
    .collect();

commands.spawn((
    TilemapChunk {
        chunk_size,
        tile_size,
        tileset,
    },
    TilemapChunkIndices(indices),
));

Screenshot 2025-04-17 at 11 54 56 PM

Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@tychedelia tychedelia added C-Feature A new feature, making something new possible A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Apr 17, 2025
@StarArawn
Copy link
Contributor

Correct me if I'm wrong but I don't think ShaderStorageBuffer's work on webGL.

@ConnerPetzold
Copy link
Author

@StarArawn good call -- updated to use a u32 texture instead. I think it may be better to use vertex attributes like you do with ecs_tilemap, but I'm not sure of the tradeoffs. I suspect using the vertex attributes and shader are necessary for making non-square tiles work?

@ConnerPetzold
Copy link
Author

Here's a prototype 3rd-party crate that utilizes the changes here: https://github.com/ConnerPetzold/bevy_tilemap/tree/main/src

Copy link
Contributor

@IceSentry IceSentry left a comment

Choose a reason for hiding this comment

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

I added a few comments, once those are fixed I think it will be good to merge.

Thank you for working on this!

@ConnerPetzold ConnerPetzold requested a review from IceSentry April 22, 2025 23:26
@ConnerPetzold ConnerPetzold force-pushed the tilemap-chunk-rendering branch from 867d3ce to fe7fc55 Compare April 22, 2025 23:28
@ConnerPetzold ConnerPetzold requested a review from IceSentry April 23, 2025 23:47

/// A resource storing the meshes for each tilemap chunk size.
#[derive(Resource, Default, Deref, DerefMut)]
pub struct TilemapChunkMeshMap(HashMap<UVec2, Handle<Mesh>>);
Copy link
Author

Choose a reason for hiding this comment

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

Should this be TilemapChunkMeshCache to align better with other names in Bevy?

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 C-Feature A new feature, making something new possible S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

5 participants