User provided mesh binding / per-instance mesh data #13373
Labels
A-Rendering
Drawing game state to the screen
C-Feature
A new feature, making something new possible
D-Complex
Quite challenging from either a design or technical perspective. Ask for help!
S-Ready-For-Implementation
This issue is ready for an implementation PR. Go for it!
What problem does this solve or what need does it fill?
A common pattern in creative coding is to use the instance index in a shader in order to sample from something like a texture or read from a SSBO. For example, the shader might use one texture in order to offset the position of the mesh and a second texture in order to determine the vertex color.
Currently, batch rendered entities (i.e. entities that share the same mesh and material) are instanced in a random order relative to how they were spawned. This is due a variety of causes:
Consequently, because the instance index is "random", it's not possible in a custom shader to know where to sample from an input texture.
See the following pseudo UV maps to see what this looks like with different rendering features enabled:
![](https://private-user-images.githubusercontent.com/10366310/330599072-01e09e9c-3d85-4ba8-8603-f779a46c14d9.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MzkyODMsIm5iZiI6MTczODgzODk4MywicGF0aCI6Ii8xMDM2NjMxMC8zMzA1OTkwNzItMDFlMDllOWMtM2Q4NS00YmE4LTg2MDMtZjc3OWE0NmMxNGQ5LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDEwNDk0M1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWQyOTVhZTM4ZjAwYTBkNTFjYmYxMmYxMWM3ODhlNTdiODcyYjM3MjdkYmY2YzIwNzkwMWM1NDRlNjQ3N2RjYTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.R84uXp10fMRli7WKSM3jus_xoSNbpF8x69wGDJo-5uY)
![](https://private-user-images.githubusercontent.com/10366310/330599078-d679f4af-f151-4c9c-ad6d-aee7f959828d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4MzkyODMsIm5iZiI6MTczODgzODk4MywicGF0aCI6Ii8xMDM2NjMxMC8zMzA1OTkwNzgtZDY3OWY0YWYtZjE1MS00YzljLWFkNmQtYWVlN2Y5NTk4MjhkLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDEwNDk0M1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTMxYmVkM2E4ODYyNmUwYzA5ZWU4Y2YxZTY2NjdhN2ExMWVkZDViNDkyNGU4MTNmZmFjY2M1ZWUwYjIyZTJlYTMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.a-757ZG81AFcO5j2PYF9hojK5gXXSj5Q3t0HJimgAmo)
What solution would you like?
The user should be able to provide a custom binding representing per-instance mesh data, i.e. a SSBO that they can index into with the instance index to retrieve additional data required for their vertex shader.
The difficult part here is that in order to write into the user data buffer, it needs to be plumbed everywhere the
MeshUniform
is created, including our new preprocessing compute shader. In order not to pollute all our rendering code, this means we need some kind of generic plugin for instance data that gets type erased in our rendering code so that it can optionally injected everywhere it needs to go.What alternative(s) have you considered?
We could, alternatively, track some kind of total "spawn order" and add this as a new index to
MeshUniform
. The user could then bind their buffer to their material and index into that instead. This has a few disadvantages:u32
to every mesh uniform that is likely unnecessary for most users.Additional context
There's prior art here I'm happy to reference in terms of how this typically works in creative coding applications.
The text was updated successfully, but these errors were encountered: