Sprites

replace all “1” with “1.0” and all “0” with “0.0”

It’s not a bug, review your matrix math :slight_smile:

@normen : done.

@cqhislai : glsl says that i should place them in column order.



mat4(float, float, float, float, // first column

float, float, float, float, // second column

float, float, float, float, // third column

float, float, float, float); // fourth column



i cant find what’s wrong.



[java]

uniform mat4 g_WorldViewProjectionMatrix;

uniform float g_Time ;



attribute vec3 inPosition;

const float PI = 3.14159265358979323846264;



void main()

{

vec4 pos = vec4(inPosition, 1.0);



float angle = g_Time0.1;

float x = 1.0;

float y = 0.0;

float z = 0.0;

float c = cos(angle);

float s = sin(angle);



mat4 rotationMatrix = mat4( x
x*(1-c)+c , yx(1-c)+zs, xz*(1-c)-ys, 0.0,

x
y*(1-c)-zs, yy*(1-c)+c , yz(1-c)+xs, 0.0,

x
z*(1-c)+ys, yz*(1-c)-xs, zz*(1-c)+c , 0.0,

0.0 , 0.0 , 0.0 , 1.0);



pos = pos * rotationMatrix;

gl_Position = g_WorldViewProjectionMatrix * pos;

}

[/java]

@tralala said:
@cqhislai : glsl says that i should place them in column order.

I meant when you multiply matrixes, order matter. It is not a bug.
There are so many posts per minute here that its hard to follow . Guess i should use quote more often :)

1.0-c !!

@tralala , and this please:

http://code.google.com/p/jme-glsl-shaders/source/browse/assets/Shaders/SimpleSprite/SimpleSprite.vert?spec=svn651ccc1bf5785d9636aa0b3ae1baa0b9eb3004f5&r=651ccc1bf5785d9636aa0b3ae1baa0b9eb3004f5

i tried :

pos = rotationMatrix * pos;



didn’t see any change.



I am starting to think that maybe jme isn’t compatable with opengl math formulas since it is another engine.

@tralala said:
i tried :
pos = rotationMatrix * pos;

didn't see any change.

I am starting to think that maybe jme isn't compatable with opengl math formulas since it is another engine.


Because that is more logical than perhaps any other possibility? :)

At some level, open GL is open GL and GLSL is GLSL. If something worked in some other shader then it should be possible to work in this shader... given all of the same inputs and correct transcription.

@tralala , now you can use it if you find it useful. THANKS FOR TESTING AND FIXING!!!

@mifth your shader now works !!!



@my code : i did normen’s fixes but it didn’t improve. do i have to normalise something ?



[java]

uniform mat4 g_WorldViewProjectionMatrix;

uniform float g_Time ;



attribute vec3 inPosition;

const float PI = 3.14159265358979323846264;



void main()

{

vec4 pos = vec4(inPosition, 1.0);



float angle = g_Time0.1;

float x = 1.0;

float y = 0.0;

float z = 0.0;

float c = cos(angle);

float s = sin(angle);



mat4 rotationMatrix = mat4( x
x*(1.0-c)+c , yx(1.0-c)+zs, xz*(1.0-c)-ys, 0.0,

x
y*(1.0-c)-zs, yy*(1.0-c)+c , yz(1.0-c)+xs, 0.0,

x
z*(1.0-c)+ys, yz*(1.0-c)-xs, zz*(1.0-c)+c , 0.0,

0.0 , 0.0 , 0.0 , 1.0);



pos = rotationMatrix * pos ;

gl_Position = g_WorldViewProjectionMatrix * pos;

}

[/java]

thank you guys for your patience, my code is now correct.

  1. opengl functions were correct.
  2. shader code was correct.



    Imagine who was to blame ?

    node.scale

    node.move

    node.rotate



    they messed with my shader, for no reason?

    do they run “per frame” all from the beginning ?

    cant i somehow batch them to permanently effect the mesh ?

It all depends on how you are using them. But we can no more guess that than a length of string you are holding in your hand. :slight_smile:

300 quads on screen. = 330 fps

300 billboards,sprites. = 80 fps

300 “shader” billboards = 280 fps



The only overhead is the jme node system, how can i convert all nodes / quads into 1 node.

GeometryBatchFactory works but “combines” vertices = only 4 verts = wrong shader.



i finished the billboard shader and it works (meh), at same angles (too high or too small) it goes crazy due to precision issues.



sprite.vert

[java]

uniform mat4 g_WorldViewProjectionMatrix;

uniform vec3 g_CameraPosition;

attribute vec3 inPosition;

attribute vec2 inTexCoord;

const float PI = 3.14159265358979323846264;



varying vec2 texCoord;



// gets the rotation matrix(glRotatef).

mat4 getRotateMatrix(in float angle, in float x, in float y, in float z)

{

float c = cos(angle);

float s = sin(angle);



mat4 rotationMatrix = mat4( xx(1.0-c)+c , yx(1.0-c)+zs, xz*(1.0-c)-ys, 0.0,

x
y*(1.0-c)-zs, yy*(1.0-c)+c , yz(1.0-c)+xs, 0.0,

x
z*(1.0-c)+ys, yz*(1.0-c)-xs, zz*(1.0-c)+c , 0.0,

0.0 , 0.0 , 0.0 , 1.0);



return rotationMatrix;

}



/** Aligns the quad to look towards camera*/

mat4 getBillboardTransformation(in vec3 positionIn, in vec3 cameraIn)

{

vec3 lookAt = vec3(0.0, 0.0, 1.0);

vec3 objToCamProj = normalize( vec3( cameraIn.x - positionIn.x, 0.0, cameraIn.z - positionIn.z));



vec3 upAux = normalize( cross( lookAt, objToCamProj ) );

float angleCosine = dot(lookAt, objToCamProj);

mat4 transformationMatrix = getRotateMatrix(acos(angleCosine), upAux.z, upAux.y, upAux.z);



vec3 objToCam = normalize( cameraIn - positionIn );

angleCosine = dot( objToCamProj, objToCam );

transformationMatrix = transformationMatrix * getRotateMatrix(acos(angleCosine), -sign(objToCam.y), 0.0, 0.0);



return transformationMatrix ;

}



void main()

{

vec4 pos = vec4(inPosition, 1.0);

mat4 billboardTranformation = getBillboardTransformation(inPosition, g_CameraPosition);

gl_Position = (g_WorldViewProjectionMatrix * billboardTranformation) * pos;

texCoord = inTexCoord;

}

[/java]



sprite.frag

[java]

varying vec2 texCoord;



uniform sampler2D m_ColorMap;



#ifdef HAS_COLOR

uniform vec4 m_Color;

#endif



void main()

{

vec4 texColor = texture2D(m_ColorMap, texCoord);



#ifdef HAS_COLOR

texColor.rgb = m_Color.rgb * texColor.rgb;

#endif



gl_FragColor = texColor ;

}

[/java]



sprite.j3md

[java]

MaterialDef Sprite

{

MaterialParameters

{

Color Color

Texture2D ColorMap

}

Technique

{

VertexShader GLSL100: 3d/shaders/sprite.vert

FragmentShader GLSL100: 3d/shaders/sprite.frag

WorldParameters

{

WorldViewProjectionMatrix

CameraPosition

}

Defines

{

HAS_COLOR : Color

}

}

Technique FixedFunc

{

}

}

[/java]

1 Like
@tralala said:
The only overhead is the jme node system, how can i convert all nodes / quads into 1 node.
GeometryBatchFactory works but "combines" vertices = only 4 verts = wrong shader.


This shouldn't be true. If your objects are in different locations then GeometryBatchFactory will not combine the vertexes into 4. But it _will_ flatten all of the transforms so that the vertexes have world position instead of their nice local positions.

This is why I said you have to embed the projection information as part of the vertex attributes... like texture coordinate. Then you have all of the quad corners at the same location and push them out based on their texture coordinate.

Ultimately, all of the sines and redundant cosines will end up being your performance bottleneck. Trig functions can be pretty expensive in comparison to everything else.

If you could describe the effect you are going for then I might be able to offer more clues. I'm not sure if you are trying to duplicate what a point sprite does or have the bottom pegged in some way... or have it rotate around a particular axis.

i am trying to do what a point sprite does, since you cant specify the location of jme point sprite and their uv-coordinates.

It seems you are right when you said that GeometryBatchFactory works correctly, i tried my own method and it has the same effect.

I created 1 mesh with all sprites(quads), with my own uv’s for each sprite.

It works fine as long as i don’t “translate” them. E.g everything is at (0,0). If i translate them my shader goes crazy (the sprites form something like a “tie” that goes in circles).

i am trying to do “translation” on shader but it doesn’t work.

It displays as it should at start but if you start move the camera they become invisible. i tried disabling culling but it had no effect.



[java]

uniform mat4 g_WorldViewProjectionMatrix;

uniform vec3 g_CameraPosition;

attribute vec3 inPosition;

attribute vec2 inTexCoord;

const float PI = 3.14159265358979323846264;



varying vec2 texCoord;

#ifdef HAS_POSITION

uniform vec3 m_Position;

#endif



// get the translation matrix(glTranslatef)

mat4 getTranslationMatrix(vec3 pos)

{

return mat4( 1.0, 0.0, 0.0, 0.0,

0.0, 1.0, 0.0, 0.0,

0.0, 0.0, 1.0, 0.0,

pos , 1.0);

}



void main()

{

vec4 pos = vec4(inPosition, 1.0);

mat4 transformation = getTranslationMatrix(m_Position);

gl_Position = g_WorldViewProjectionMatrix * (transformation * pos);

texCoord = inTexCoord;

}

[/java]

maybe its a bug with how jme calculates model bounds, which means you cant translate in shader.

Yes, if you’re translating in the shader then the bound jME3 calculates will be off. You will need to adjust the bound so it contains all possible locations of the model or not do the translation in the shader

1 Like
@tralala said:
i am trying to do what a point sprite does, since you cant specify the location of jme point sprite and their uv-coordinates.


I'm not sure what you are talking about here. The point sprites are drawn where the vertexes are... and you can definitely pick where in the texture they are rendering. I do this all the time in Mythruna for the stars, the flowers, etc..