Sprites

Hello, i want to use 2d images as sprites for my characters, lets say 300 sprites on screen.

  1. using billboards with them, each one using a separate new material, i get 90 fps.
  2. using billboards, all using the same material (texture atlas), i get 86 fps.
  3. using GeometryBatchOptimize i get 2000 fps, but they don’t face the screen = thin paper.
  4. using point sprites i get 2000 fps but :

    a) I cannot define the u-v coordinates of each sprite. My sprites don’t have the same width / height so the method setImagesX, setImagesY don’t give the desired effect. Each sprite now contains the whole atlas sprite sheet.

    b) I cannot set where the position of each sprite will be. I am forced to use emitter shapes which have a predefined position. Since the sprites will be characters on screen, they can be anywhere in the world, and their position will change depending their movement, actions, goal each frame.



    a) How do i solve 4a) 4b) for point sprites ?

    b) It seems that the “node” system in jme is inefficient, in jogl i could render 4000 sprites at 600 fps. Anyway to bypass it so that solution 1, 2 work ?
  1. another idea: each frame reconstruct a mesh that contains all 300 sprites from the beginning depending on camera position. Will it be faster?

For animated sprites:

Can you try SimpleSprite shader? Taken from here: http://code.google.com/p/jme-glsl-shaders/

possibly your fps will be much better.



For static images with alpha:

try to use a plane mesh. Fps should be ok.

1 Like

Also, in every game there is not so much animated sprites. about 10-20 animated sprites should be on a screen.

  1. i tried running SimpleSprite.java but it didn’t work. I get the following error :

    WARNING: Bad compile of:

    blablabla



    com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/SimpleSprite/SimpleSprite.vert, defines, type=Vertex] error:Vertex shader failed to compile with the following errors:

    ERROR: 0:37: error(#160) Cannot convert from ‘float’ to ‘highp int’

    ERROR: error(#273) 1 compilation errors. No code generated


  2. plane mesh : i searched in the forum but i didn’t find anything relevant.

    You mean to use just a plane ? i used quad before and it suffered from being “2d paper”, I.e it will be a “2d” plane and the viewer will be able to see it normally in one view (from front) but if he rotates 90 degrees it will be invisible.


  3. depends on goal, in kingdom hearts 2 there are 10.000 animated sprites (that are the enemies).

what about rts games? 10-20 animated units seems a rather low limit

@tralala: I use sprote atm in my rts, and i use quads for them. You have to correctly rotate tham though, using current camera direction.



I first pu them with their upper left corner at origin and facing positive Y, then rotate aroud Z to face the camera (fixed direction in my case), then translate to origin. Then i translate the node they are attached to to move them, it works great except when 2 quads are overlapping, then only 1 of the 2 is drawn, i didn’t figure out how to avoid that yet.

1 Like

@cghislai 10-20 animated units on a screen. Not in a scene.





@tralala i suppose you have ATI card. I’ll fix it in some hours and post here.

@tralala i think i fixed it… can you change your SimpleSprite.vert to this one:

http://code.google.com/p/jme-glsl-shaders/source/browse/assets/Shaders/SimpleSprite/SimpleSprite.vert

Plane is just an mesh with 2 triangles. like in SimpleSprite shader example.

i replaced it, here is the error:



SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/SimpleSprite/SimpleSprite.vert, defines, type=Vertex] error:Vertex shader failed to compile with the following errors:

ERROR: 0:40: error(#162) Wrong operand types no operation ‘%’ exists that takes a left-hand operand of type ‘highp float’ and a right operand of type ‘highp int’ (or there is no acceptable conversion)

ERROR: error(#273) 1 compilation errors. No code generated

@tralala , ok, now try this one:

http://code.google.com/p/jme-glsl-shaders/source/browse/assets/Shaders/SimpleSprite/SimpleSprite.vert

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/SimpleSprite/SimpleSprite.vert, defines, type=Vertex] error:Vertex shader failed to compile with the following errors:

ERROR: 0:38: error(#162) Wrong operand types no operation ‘%’ exists that takes a left-hand operand of type ‘highp float’ and a right operand of type ‘highp float’ (or there is no acceptable conversion)

ERROR: error(#273) 1 compilation errors. No code generated

ok i did the following change at line 38 :



texCoordAni.x = -(1 - ((texCoordAni.x + mod( selectedTile, iNumTilesU) ) / iNumTilesU)); ///selectedTile;



It seems that % is called mod in glsl



it now works correctly !!!

man, i’ll try to fix it at home. What is you videocard? ATI or Intel?

it is ati

although it compiles, it doesn’t display the correct result.



a) it is a quad, not billboard (it is not aligned to camera).

b) the texture coordinates change linearly :

b1) i would expect sprite 1, 2, 3, 4, 5. (instant switch from 1 - 2).

b2) but instead i get sprite 1, 1.01, 1.02, 1.03. ( it takes all possible values from 1 until 2)



This may have to do with the ati issues with int vs float, at line 32 i did the following change but it didnt improve it.

float selectedTileF = 1.0 + g_Time*m_Speed;

int selectedTile = int(selectedTileF);

wow i found the bug, i had to convert selectedTile / iNumTilesU into integer.



texCoordAni.y = ((-texCoordAni.y - int(selectedTile / iNumTilesU)) / iNumTilesV); ///selectedTile;



Now it works perfectly. Here is full file :



[java]

uniform mat4 g_WorldViewProjectionMatrix;

uniform float g_Time;



attribute vec3 inPosition;

attribute vec2 inTexCoord;

varying vec2 texCoordAni;



// if these are passed as ints, then it doesn’t work for some reason

uniform int m_numTilesU;

uniform int m_numTilesV;

uniform int m_Speed;



#ifdef FOG

varying float fog_z;

#endif



#if defined(FOG_SKY)

varying vec3 I;

uniform vec3 g_CameraPosition;

uniform mat4 g_WorldMatrix;

#endif



void main(){



gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

texCoordAni = inTexCoord;



float iNumTilesU = float(m_numTilesU);

float iNumTilesV = float(m_numTilesV);



float numTilesTotal = iNumTilesU * iNumTilesV;

float selectedTileF = 1.0 + g_Time*m_Speed;

int selectedTile = int(selectedTileF);



// the "1 - " bit is because otherwise it goes from right to left

texCoordAni.x = -(1 - ((texCoordAni.x + mod(selectedTile , iNumTilesU) ) / iNumTilesU)); ///selectedTile;

texCoordAni.y = ((-texCoordAni.y - int(selectedTile / iNumTilesU)) / iNumTilesV); ///selectedTile;











// if (index = 8) index = 3;



//texCoordAni.x = texCoordAni.x / numTilesTotal + float(index) / numTilesTotal;







#if defined(FOG_SKY)

vec3 worldPos = (g_WorldMatrix * pos).xyz;

I = normalize( g_CameraPosition - worldPos ).xyz;

#endif



#ifdef FOG

fog_z = gl_Position.z;

#endif



}

[/java]



ps. the particles are cool can i use them in my project ?

i get 260 fps with your shader for 300 sprites, but they are not camera aligned.

now when i attach billboard to them they face the camera but the fps drops to 74.

GeometryBatchFactory doesn’t improve the fps.



I will try to combine “particle.j3md” and your shader to see if that improves the fps.

i look at both shaders, none of the acts as a billboard. So the fps issue will never be solved.


  1. what do i do ? i don’t have the experience to align the quad in the .vert shader.
  2. what about point sprites ? how do i set their position.
  3. Should i create a subclass of geometry ? or ParticleEmitter ?