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

SpriteBatch With Custom Effects and Per-Sprite Data #8295

Open
Tommy-Hu opened this issue May 3, 2024 · 0 comments
Open

SpriteBatch With Custom Effects and Per-Sprite Data #8295

Tommy-Hu opened this issue May 3, 2024 · 0 comments

Comments

@Tommy-Hu
Copy link

Tommy-Hu commented May 3, 2024

Intent

Allow per-sprite data (that are passed with each Draw() call) to be easily passed into effects -- without beginning new batches or needing to use DrawUserIndexedPrimitive(). The user will be able to access the per-sprite data in the Vertex Shader of the effect, and can therefore easily perform different sub-effects per-sprite. Having extra data per vertex will increase batch item size, but the user will be able to choose whether or not they need to use this new functionality (by using an old overload or setting the new overload's parameter to its default value).

Possible Solution

Create an overload SpriteBatch.Draw(OTHER_OLD_PARAMS, params float[] customFloats). The framework throws an error if customFloats.Length exceeds some threshold (so that the user cannot put in a float[] of length 100000 for fun) or if the given customFloats array is null.

A possible implementation of the new SpriteBatch.Draw overload might be one of the following (I only dug around the MonoGame code a little bit, so these may be impossible):

  1. There would be a few new MonoGame internal structs created, each representing a custom vertex of a set number of floats (e.g., a VertexPositionColorTextureF1, VertexPositionColorTextureF2, VertexPositionColorTextureF3,... that supports 1, 2, and 3 extra floating-point data on vertices respectively). The new structs would extend IVertexType. The new Draw overload adds one of these into the batch depending on the length of customFloats.

  2. A new MonoGame internal struct VertexPositionColorTextureSingles : IVertexType can be created that dynamically changes its VertexDeclaration size based on the number of extra floating parameters to the Draw overload.

  3. If the SpriteBatch must send batches of vertices of the same struct size, then the batcher could either send the batch of vertices based on the maximum Length of customFloats stored in the batch or instead, add a new optional parameter to SpriteBatch.Begin() that specifies the number of extra floats to carry per vertex/Draw call.

Either way, this solution would achieve the goal of easily sending custom data to each effect per sprite, essentially allowing different effect parameters in a single batch.

Motivation

2D games that need to use multiple effects may find beginning a new sprite batch for each effect very slow (this is what happened in my game). A way to achieve multiple effects with fewer sprite batches is to write a master effect that is a collection of all effects in one single effect file. A custom vertex (that extends IVertexType) can then be used to send an extra per-vertex floating-point identifier variable to the vertex shader, which can then choose to apply one or more of the sub-effects of the master effect based on the received identifier. Right now, there is no way that I know of that allows custom vertices in SpriteBatch. To achieve the sub-effect selection described above, GraphicsDevice.DrawUserIndexedPrimitives() would be used, meaning that the user would need to remake the SpriteBatch's sorting functionality, matrix calculations, etc.

The user may also wish to send other per-sprite data to the vertex shader. Beginning a new SpriteBatch to set uniform shader variables for each sprite that has a different shader data or manually drawing the object vertices with DrawUserIndexedPrimitives() are both unattractive options, as mentioned above.

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

No branches or pull requests

1 participant