Skip to content

feat: include the voxel material in generated mesh#11

Draft
terrence2 wants to merge 1 commit into
WildPixelGames:masterfrom
terrence2:just-material
Draft

feat: include the voxel material in generated mesh#11
terrence2 wants to merge 1 commit into
WildPixelGames:masterfrom
terrence2:just-material

Conversation

@terrence2

Copy link
Copy Markdown
Contributor

This third patch I'm not entirely sure how to get over the finish line and am looking for some feedback. While it works well enough for my own uses, it is currently a pretty significant performance regression to meshing in the general case.

What

In order to render a textured surface, we need to know what the voxel material is in the renderer somehow. There are two approaches one can take (at least that I've though of so far).

  1. Have each voxel emit a collection of meshes, one for each material. e.g. this fork.

This works well with Bevy because you can slap a Material3d onto each of those Mesh3d and you're good to go. you can probably even do some tex-coord tricks to allow each face to have a different texture, at the cost of some flexibility. The downside is that you might be generating dozens of meshes per chunk and you'll need to either turn each of them into physics objects independently, or also generate a unified mesh for physics.

  1. The approach taken here: put the material into the vertex data and let it be a renderer problem.

This takes quite a bit more effort with Bevy because you need either a custom material to deal with dense texture arrays, or lots of extra complexity to juggle texture atlases (assuming that would even work with 4k textures). The positive side is that you have a 1:1 relationship between chunks, meshes, and physics data that makes managing the ECS lifecycle much easier.

How

This adds a material field to MeshData and populates it during meshing.

Performance

This takes about a 10% performance hit (highly variable) on long tests and a random amount (up to 100%) for trivial tests. I suspect this is because we're allocating for a third vector, but haven't yet dug into the specifics.

Questions

  1. Did I miss some subtle way to get textured voxels that already exists? Like, I figured out that you can use the position as an implicit texture coordinate for a voxel grid. Is there something similar I should be doing for the voxel data itself?

  2. Is being able to render a textured voxelis chunk even a project goal at all? It seems like something that's going to be pretty commonly necessary, given that there are already two separate implementations, but I don't want to presume.

  3. If you do want to support one of the strategies above, how big a performance hit is acceptable on the non-material-returning path? I'm pretty sure we should be able to put some traits in place to specialize both new with-material and unchanged without-material instruction streams from the same Rust code, but I haven't put in the work yet.

Have a great holiday! I'm not in a rush; we can discuss in more depth whenever you have some time to give it a think.

@aljen

aljen commented Dec 23, 2025

Copy link
Copy Markdown
Member

Ah, good catch, and let me back to it after holidays! :)

Short version:
In my project, I'm focusing on purely procedural colors - per-voxel. The color offset is calculated based on x/y/z, so it's deterministic (sand is a 'color', position is a variant of that colour, gives a natural 'texture'/random like feel). That's why I'm aiming for smaller/tiny voxels, so that the "texture" results from the color, not from an external texture. Does it make sense?

Here are some old screenshots from the WIP Godot branch of my game :)

image image

Have a great holiday too! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants