Sprite Batch Changes

Discussions for core devs and contributors. Read only for normal forum members to keep the noise low

Sprite Batch Changes

Postby davedes » Sat Jan 05, 2013 6:07 pm

Unfortunately, Sprite Batch is not very extendable right now. For example, say a user wanted to create a sprite batch that passed specific vertex attributes; i.e. no color attribute for improved performance, or an extra attribute for something more game-specific (imagine this in 2D). There are other things that keen users might want to do, such as using hexagons instead of rectangles (reduced fill rate), geometry shaders and/or texture arrays on desktop/GL3, multiple texture units to improve batching, etc. The other problem is that we can't utilize scene2D and all its GUI glory without a SpriteBatch class.

Right now the only solution is to extend SpriteBatch and pretty much re-write it entirely, copying huge chunks of code as you go.

Here are some ideas:

1. Use "protected" instead of private for many things in SpriteBatch, so that keen users can extend it more readily.
2. Have SpriteBatch extend an abstract class, like AbstractSpriteBatch, which would serve as a better base for those looking to extend it's functionality and make use of their own custom sprite batchers alongside scene2D.
3. Have SpriteBatch implement an interface.
4. Some combination of the above three.
davedes
 
Posts: 434
Joined: Thu Oct 11, 2012 7:51 pm

Re: Sprite Batch Changes

Postby xoppa » Sat Jan 05, 2013 7:33 pm

I agree and would even go a step futher by not restricting it to 2D. What about this:

Create a dynamic mesh. It keeps an array of vertices (and optionally indices). Method begin() clears the array, end() calls setVertices (and setIndices). Between begin/end you can add vertices to the array (and the dynamic mesh remaps indices if needed).

Create a base sprite batch derived from dynamic mesh. It only needs to know the offset to the x, y, u and v values (which can be gathered from the attributes) and have some method to push in a sprite (including rotation etc.), for the unknown verts it can use default values which allows to set the color etc. Next to that it adds i.e. an (abstract) flush(Texture) method which is called when the texture switches and in end().

Update spritebatch to derive from base dynamic sprite and fill in the gaps like the shader and rendering (implement flush).

All of this is mostly just moving existing code.
xoppa
 
Posts: 689
Joined: Thu Aug 23, 2012 11:27 pm

Re: Sprite Batch Changes

Postby bach » Sat Jan 05, 2013 8:39 pm

As much as I like the idea of an extendable SpriteBatch I can't think of a solution that won't pretty much end up being the same amount of work to implement custom solutions.

Unless I'm just completely missing the point here. But I don't see how you will get around re-implementing most of SpriteBatch's methods if you want more custom functionality.

The idea of SpriteBatch implementing an interface.. could be useful. That'd allow to write a render code with one SpriteBatch and simply change it to another without breaking the rest of the code. But again, won't simplify the process of extending.

So - I'm in favour of maybe interfacing SpriteBatch (similar to what we're planning for the 3d API), but not sure about the rest.

Bach
bach
 
Posts: 713
Joined: Mon Mar 07, 2011 1:50 am

Re: Sprite Batch Changes

Postby mzechner » Sat Jan 05, 2013 9:32 pm

SpriteBatch is meant to only render rectangles, composed of two triangles, sharing two vertices, with xy, color and uv. If we made it more generic, we'd lose a lot of the optimizations we added over the years to make sure it doesn't blow a hole in the CPU and only transfers as much data as necessary (e.g. indices aren't resubmitted, ever).

Interfacing SpriteBatch is also problematic. Which methods would be in the interface? All the draw methods assume that a rectangular image is being drawn. I do however see the usefulness of interfacing that.

Whatever we decide, we can't break the current SpriteBatch API, to many things rely on it. I also don't want to impact its performance. If we can come up with a solution that fits those two criteria i'm willing to integrate it.
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Re: Sprite Batch Changes

Postby NateS » Sun Jan 06, 2013 9:54 am

It isn't clear how much could be reused and whether it would be worth it. It might help to build something similar without extending SpriteBatch and then see what could be done to reuse parts.

There isn't a good way for whitespace stripping to be transparent ( :lol: damn that was a wicked pun!). Likely there isn't a good fix for it. One approach might be to have TextureRegion#draw(SpriteBatch), then whitespace stripping could stay in AtlasRegion. This leaks the 2D batching stuff into TextureRegion though, which is nasty. Also it would have to be a dozen methods: TextureRegion#draw(SpriteBatch, <millions of args>).

Related is the difference between sprite.draw(batch) and batch.draw(sprite), which is always fun to explain.
NateS
 
Posts: 1980
Joined: Fri Nov 12, 2010 11:08 am

Re: Sprite Batch Changes

Postby bach » Sun Jan 06, 2013 4:24 pm

NateS brings up a very good point. I remember discussing this when we were working on the PolygonSpriteBatch. As ugly as it is, we thought it was the best solution back then :/

Bach
bach
 
Posts: 713
Joined: Mon Mar 07, 2011 1:50 am

Re: Sprite Batch Changes

Postby davedes » Sat Mar 16, 2013 12:13 am

I am writing my own batch tools to see how feasible abstraction would be.

AbstractQuadBatch - includes common features of a 2D quad-based batch -- like transforming vertices on CPU, setting color, projection matrix, etc. Pretty low-level to use, but better than re-writing it completely.

GenericBatch - a high-level sprite batch that allows for multiple texture units (sampler2Ds) and multiple texture coord attributes. Also can be subclassed to specify custom generic attributes.

Here is a test that demonstrates the GenericBatch in action. It blends two textures in the fragment shader, each with different texCoord vertex attributes. This is not possible with GDX's SpriteBatch.
PuzzleBatchTest

And here is a test that demonstrates how one might subclass it to provide custom attributes. I am still fiddling with this, perhaps there is a cleaner solution.
GenAttribTest

Basically the batch looks like this:
Code: Select all
batch = new GenericBatch(2); //2 available texture units
...

batch.begin(myShader);

batch.setTexture(0, texRegion0); //texture unit 0, custom texcoords
batch.setTexture(1, texRegion1); //texture unit 1, custom texcoords

//draw the quad ... blending occurs in frag shader
batch.draw(x, y, width, height);

batch.end();


This is probably more suitable as a third-party library, rather than merging with core. However, it would still be nice if SpriteBatch was somehow abstracted (into an interface), so that the above generic batches could be used to render BitmapFont, Stage actors, etc. Having an abstract base for users to build on (rather than having to re-write everything) might also be a nice touch; there are lots of commonalities between 2D quad-based batches.
davedes
 
Posts: 434
Joined: Thu Oct 11, 2012 7:51 pm

Re: Sprite Batch Changes

Postby davedes » Fri Oct 25, 2013 2:35 pm

Revisiting the idea of "custom" or advanced batchers...

I found an interesting demo in WebGL that batches up to four textures in a single draw call.
http://webglsamples.googlecode.com/hg/s ... eadme.html

I implemented this technique in a JavaScript WebGL engine, see here (inherits from AbstractBatch). I noticed in my WebGL game the render calls went from ~40 per frame to ~5 per frame.

I wonder how this technique would perform on mobile.
davedes
 
Posts: 434
Joined: Thu Oct 11, 2012 7:51 pm

Re: Sprite Batch Changes

Postby BurningHand » Fri Oct 25, 2013 2:50 pm

The "fast" shader at that link runs at 20-25 fps on my Nexus 4 in Chrome for Android. I suspect that the performance would be a bit better outside of the browser. The "slow" version ran at about 5 fps.
IRC: nexsoftware / mobidevelop; GitHub: MobiDevelop;
BurningHand
 
Posts: 2812
Joined: Mon Oct 25, 2010 4:35 am

Re: Sprite Batch Changes

Postby mzechner » Fri Oct 25, 2013 11:40 pm

The problem with this technique is that it's hard to anticipate which textures to bind. Unless the user did some things manually, there's simply no heuristic that can figure out the best binds. That being said, we use something similar in the new 3D API :)

Abstracting SpriteBatch would indeed be nice though. We need to keep SpriteBatch, add a new interface (e.g. Batch?), then replace all SpriteBatch occurances with that interface. Who wants to do it? :D
mzechner
Site Admin
 
Posts: 4879
Joined: Sat Jul 10, 2010 3:50 pm

Next

Return to Libgdx Development

Who is online

Users browsing this forum: No registered users and 1 guest