SpriteBatching with Shaders

Anything about development not directly related to libgdx, e.g. OpenGL, Android APIs etc.

SpriteBatching with Shaders

Postby angelus » Sun Jul 22, 2012 10:13 am

I'm trying to do the next (it seems to be done by a partner here):

I want to make a game where i can change color pixels of textures (Arcade retro ... ) , but i have a big stick problem:
I have one big texture ( 256 * 4096 (1024 x 1024 equivalent) and i need to extract from there parts (regions) , and change the color of them with a palette in order to use it in the game.

We have some alternatives :

- We can throw out game color change and make each sprite with its colors (pain and memory headeach)
- We can continues with our idea , then we have this alternatives:

* Use a Pixmap for all the game (256x224 arcade size)
The problem which comes with this is that i must extract region and throw it to a pixmap ,and Pixmaps doesn't work with Pixmaps , then i must copy each texture .
* Use shaders with an uniform var palette (png)
I have tried this way , but spritebatch doesn't goes well when you must atach another shader with vars you must send.
I's ok , but i couldn't make it (i have the shaders done) using spritebatch , the only way is using mesh render to do it.
* Having indexed pngs
I think this is not supported by libgdx , then i can't think going this way.

My problem , i don't know what is the best option , and fighting with shaders , anyone can show me an example of passing uniforms and using spritebatch? (no mesh rendering directly)

Any help? , new ideas are wellcome , and i'll be greated for your time.

Sorry for my bad english
Posts: 9
Joined: Sun Feb 05, 2012 9:16 pm

Re: SpriteBatching with Shaders

Postby kalle_h » Fri Aug 03, 2012 9:59 pm

Make custom shader that can handle normal spriteBatch functionality but on fragment side use texture color as index.
So your color palette is 256x1 texture.
To make batching possible you could use 256x256 texture that can contain 256 different palettes.

Your main texture can be 8-bit alpha channel texture. This is used as index.

For selecting which palette you use you can use per sprite vertex color. Let just pick alpha channel as index there.

Example palette indexing shader.
Code: Select all
"#ifdef GL_ES\n" //
                        + "#define LOWP lowp\n" //
                        + "precision mediump float;\n" //
                        + "#else\n" //
                        + "#define LOWP \n" //
                        + "#endif\n" //
                        + "varying LOWP vec4 v_color;\n" //
                        + "varying vec2 v_texCoords;\n" //
                        + "uniform sampler2D u_texture;\n" //
                        + "void main()\n"//
                        + "{\n" //
                        + "  LOWP float colorIndex = texture2D(u_texture, v_texCoords).a;\n" //
                        + "  LOWP vec2 uv = vec2(colorIndex, v_color.a);\n" //
                        + "  gl_FragColor = texture2D(u_texture1, uv);\n" //
                        + "}";

To make this work just copy the spritebatch normal vertex shader from the source and use this as fragment shader.
After creating this shader send uniformi parameter 1 for sampler u_texture1. Also bind your palette texture to texture unit 1 and remember to bind current unit back to 0.

Then your only problem is how to make that palette texture but that should be breeze.
Posts: 666
Joined: Thu Dec 29, 2011 9:50 pm

Re: SpriteBatching with Shaders

Postby angelus » Wed Aug 08, 2012 7:49 am

Thank you for your efforts , i'll try it and tell you next month (now i have some tests :D)
Posts: 9
Joined: Sun Feb 05, 2012 9:16 pm

Re: SpriteBatching with Shaders

Postby Varriount » Wed Aug 08, 2012 8:44 am

Couldn't you just make some texture regions from that big texture and use the opengl color functions to tint when creating them to the screen?

Alternately, you could use a combination of the stencil buffer and blending. Turn the color buffer off, render the regions you want to the stencil buffer (using alpha blending to filter out unwanted pixels), and then turn color back on and render a color out to the regions, using blending.
Think of the unanswered posters : search.php?search_id=unanswered
If I'm you and you're me, then who's he?
Posts: 249
Joined: Tue Jun 05, 2012 2:48 pm

Re: SpriteBatching with Shaders

Postby hcito » Sun Sep 14, 2014 11:50 pm


I also have been looking and looking for workarounds to do a (simulated) palette swap, and I found some posts that point to Shaders as the best approach.

The main problem is that I know nothing about OpenGL (and that I am not a very brilliant programmer either ^^U) so I have been sweating blood for several days trying to understand how could I make it work, without much success to the day.

Now that I think it, maybe I should have asked here pretty sooner than I did, but well, I already told you that I'm not the brilliantest guy XD

What I've done until now (I created a repository to share it in BitBucket: https://bitbucket.org/hcito/libgdxshadertest):

1) I was able to make work a grayscale shader (but that's all). I save the vertex and fragment shaders as plain text in the folder "assets/shaders" of the Android project. All I show here is on the repository, but I'll also copy it here for your easy viewing:
Code: Select all
// Shadow Fragment Shader
// Thanks to Will Calderwood http://stackoverflow.com/questions/17516177/texture-grayscale-in-libgdx
#ifdef GL_ES
    precision mediump float;

varying vec4 v_color;
varying vec2 v_texCoords;
uniform sampler2D u_texture;

void main() {
  vec4 c = v_color * texture2D(u_texture, v_texCoords);
  float grey = (c.r + c.g + c.b) / 3.0;
  gl_FragColor = vec4(grey, grey, grey, c.a);

Code: Select all
// Default Vertex Shader
// Thanks to NumberOverZero http://stackoverflow.com/questions/10145000/libgdx-shaders-basic-shader-but-screen-is-blank
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec4 v_color;
varying vec2 v_texCoords;

void main() {
    v_color = a_color;
    v_texCoords = a_texCoord0;
    gl_Position = u_projTrans * a_position;

2) I tried some shader I found in gamedev.stackexchange, but not luck at all. I'm not pretty sure but it seems that the only needed was the "fragment" one and the "vertex" was not necessary.
Code: Select all
// Fragment shader
// Thanks to Laurent Couvidou http://gamedev.stackexchange.com/questions/43294/creating-a-retro-style-palette-swapping-effect-in-opengl
#version 110
uniform sampler2D ColorTable;     //256 x 1 pixels
uniform sampler2D MyIndexTexture;
varying vec2 TexCoord0;
void main()
  //What color do we want to index?
  vec4 myindex = texture2D(MyIndexTexture, TexCoord0);
  //Do a dependency texture read
  vec4 texel = texture2D(ColorTable, myindex.xy);
  gl_FragColor = texel;   //Output the color

I made 2 images, one of them is supposed to be a substitute for the palette, and the other one is the one which palette I want to change.
Image to be used as palette (256px x 1px - PNG 16)

Image to be "color indexed" (480px x 320px - PNG 16)

As far as I understand, the images don't need to be true color indexed, so I used PNG16 instead of PNG8. I wasn't pretty sure of where should I put them or how should I call them from the shader, so I'm a bit stuck now :S

I'll continue searching info, but I would really thank a lot any help you could lend me, it's being pretty hard for something that could be so easy as loading an ".pal" or ".act" file ^^U

Many thanks in advance :)

P.S: Sorry for reviving this old post, but it was that or making a new one. Sorry also for my English, I'm not a native speaker so it can be quite strage sometimes.
Posts: 3
Joined: Sun Sep 14, 2014 5:13 pm

Re: SpriteBatching with Shaders

Postby hcito » Thu Oct 02, 2014 9:12 pm

Hi, again :)

I could solve the problem of "swapping palettes" using shaders, and I wanted to share it here :D

Here is the question I asked in StackOverflow:
http://stackoverflow.com/questions/2613 ... -in-libgdx

Here is the bitbucket repository I made to test the palette swap with shaders:

Hope this helps anyone else interested in simulating indexed palettes! ;)
Posts: 3
Joined: Sun Sep 14, 2014 5:13 pm

Return to General Development

Who is online

Users browsing this forum: No registered users and 1 guest