Shader not working in JME [SOLVED]

Hi,

This shader is based on SimpleSprite in ShaderBlow to add some more sprite animation functionality. However, no matter how I try, this shader does not seem to work in JME3. It works in RenderMonkey (Shader IDE) but not in JME3. The texture/material does not show up at all. Any help would be appreciated.

Vertex
[java]uniform mat4 g_WorldViewProjectionMatrix;
uniform float g_Time;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
varying vec2 texCoordAni;

uniform int m_tileSizeX; // size in px of tile
uniform int m_tileSizeY;
uniform int m_spriteHeight;
uniform int m_spriteWidth; // size in px of image

uniform int m_Speed;
uniform int m_startTx;
uniform int m_startTy;
uniform int m_totalTW;
uniform int m_totalTH;

void main(){

vec4 pos = vec4(inPosition, 1.0);

gl_Position = g_WorldViewProjectionMatrix * pos;
texCoordAni = gl_MultiTexCoord0;

int iNumTilesU = int( floor(float(m_spriteWidth) / float(m_tileSizeX)) );
int iNumTilesV = int( floor(float(m_spriteHeight) / float(m_tileSizeY)) );

int numTilesTotal = iNumTilesU * iNumTilesV;

    int startTx = int(m_startTx);
    int startTy = int(m_startTy);
    int totalTW = int(m_totalTW);
    int totalTH = int(m_totalTH);

    numTilesTotal = totalTW * totalTH;

    int frameCounter = (int(g_Time*float(m_Speed)) % numTilesTotal);
    int frameCounter_total_W = (int(g_Time*float(m_Speed)) % totalTW);
    int startTile = ((startTy - 1) * iNumTilesU) + (startTx - 1);
    int selectedTile = startTile;   
    selectedTile += (int(floor(frameCounter / totalTW) * iNumTilesU  ) + frameCounter_total_W );
    // the "1 - " bit is because otherwise it goes from right to left
    texCoordAni.x = -(1.0 - float((texCoordAni.x + mod(float(selectedTile),  float(iNumTilesU))) / float(iNumTilesU)));
    texCoordAni.y = (-texCoordAni.y - float(selectedTile / iNumTilesU)) / float(iNumTilesV);

}[/java]

[java]Fragment
varying vec2 texCoordAni;
uniform sampler2D m_AniTexMap;

void main(){
vec4 AniTex = texture2D(m_AniTexMap, vec2(texCoordAni));
gl_FragColor.rgb = AniTex.rgb;
if(AniTex.a < 0.015){
discard;
}
gl_FragColor.a = AniTex.a;
}[/java]

Java snippet:
[java] Quad quadShape = new Quad(10, 10);
Geometry geom = new Geometry(“quad”,quadShape);
geom.setLocalTranslation(0, 1, 0);
Material mat = new Material(assetManager,“Textures/shaders/SimpleSprite.j3md”);
Texture tex = assetManager.loadTexture(“Textures/characters/soldier_bigger.png”);
tex.setMagFilter(Texture.MagFilter.Nearest);
tex.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
mat.setTexture(“AniTexMap”, tex);
mat.setInt(“tileSizeX”, 64);
mat.setInt(“tileSizeY”, 64);
mat.setInt(“spriteWidth”, 1024);
mat.setInt(“spriteHeight”, 1024);
mat.setInt(“startTx”, 2);
mat.setInt(“startTy”, 1);
mat.setInt(“totalTW”, 8);
mat.setInt(“totalTH”, 1);
mat.setInt(“Speed”, 5);
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
geom.setQueueBucket(Bucket.Transparent);
geom.setMaterial(mat);
rootNode.attachChild(geom);[/java]

[java]MaterialDef SimpleSprite {

MaterialParameters {

    Texture2D AniTexMap
	Int tileSizeX
	Int tileSizeY
	Int spriteWidth
	Int spriteHeight
	Int Speed
	Int startTx
	Int startTy
	Int totalTW
	Int totalTH
}

Technique {
      VertexShader GLSL100:   Textures/shaders/SimpleSprite.vert
      FragmentShader GLSL100: Textures/shaders/SimpleSprite.frag

    WorldParameters {
        WorldViewProjectionMatrix
        Time
    }
}

}[/java]

Sprite texture link:
http://i.imgur.com/CCKasHs.png

@Dansas said: However, no matter how I try, this shader does not seem to work in JME3.

Of all of the infinite definitions of “does not seem to work”, I’m going to pick one at random and respond: “Immediately take your computer to the nearest church and have it exorcised.”

…or perhaps you could be more specific about what “not working” means. Nothing shows up. Wrong thing shows up. Satanic symbols appear. Computer melts into slag?

Any information would be helpful.

Hi, as I wrote in my first few sentences, nothing is showing up at all. When I apply a different material (eg. Lighting.jm3d) it works. By not showing up at all, I mean that the you cannot see the quad at all (completely transparent). This same shader works correctly in render monkey .

[java]texCoordAni = gl_MultiTexCoord0;[/java]

should probably be:
[java]texCoordAni = inTexCoord;[/java]

Thank you for the reply. I tried your suggestion, but it still doesn’t show anything :(.

Start from having
gl_FragColor.rgba = vec4(1.0);
in your fragment shader. If you start seeing white rectangle, replace it with vec4(AniTex.a) or vec4(AniTex.rgb,1.0) and see what you get.

also change

VertexShader GLSL100: Textures/shaders/SimpleSprite.vert
FragmentShader GLSL100: Textures/shaders/SimpleSprite.frag

to GLSL110 at minimum when debugging shaders. It generally fails more often and so will contain more useful information about any problems

Hi,

This was very useful advise! I think I am closer to solving the issue. After switching to GLSL110 & vec4(AniTex.rgb,1.0), I think I may have found the culprit and discrepancy between RenderMonkey & JME.

The culprit may be how the texture coordinates are being passed in from JME3 to the shader, but I am not sure exactly why?

If I set vec4(AniTex.rgb,1.0) in the fragment shade and comment out the last two lines, texCoordAni.x=… & texCoordAni.y… in the vertex shader, then the texture shows up correctly. However, if I leave in the last two lines of the vertex shader in, it doesn’t show up.

In RenderMonkey, I use
texCoordAni = vec2(gl_MultiTexCoord0);

but in JME3 it is
texCoordAni = inTexCoord;

Flipping the image doesn’t seem to change the result in JME. Is it possible the texture coordinates being passed in RenderMonkey are different then the coordinates in jme3?

To test, I froze it at frame 1 (hardcoded values):

[java] selectedTile=1;
iNumTilesU=16;
iNumTilesV=16;
// the "1 - " bit is because otherwise it goes from right to left
texCoordAni.x = -(1.0 - float((texCoordAni.x + mod(float(selectedTile), float(iNumTilesU))) / float(iNumTilesU)));
texCoordAni.y = (-texCoordAni.y - float(selectedTile / iNumTilesU)) / float(iNumTilesV);[/java]

In JME3, it is empty, but in render monkey it shows the correct image (static display of the first tile)

[java]
#extension GL_EXT_gpu_shader4 : enable
uniform mat4 g_WorldViewProjectionMatrix;
uniform float g_Time;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
varying vec2 texCoordAni;

uniform int m_tileSizeX; // size in px of tile
uniform int m_tileSizeY;
uniform int m_spriteWidth; // size in px of image
uniform int m_spriteHeight;

uniform int m_Speed;
uniform int m_startTx;
uniform int m_startTy;
uniform int m_totalTW;
uniform int m_totalTH;

void main(){

vec4 pos = vec4(inPosition, 1.0);

gl_Position = g_WorldViewProjectionMatrix * pos;
texCoordAni = inTexCoord;

int iNumTilesU = int( floor(float(m_spriteWidth) / float(m_tileSizeX)) );
int iNumTilesV = int( floor(float(m_spriteHeight) / float(m_tileSizeY)) );

int numTilesTotal = iNumTilesU * iNumTilesV;

    int startTx = int(m_startTx);
    int startTy = int(m_startTy);
    int totalTW = int(m_totalTW);
    int totalTH = int(m_totalTH);

    numTilesTotal = totalTW * totalTH;

    int frameCounter = (int(g_Time*float(m_Speed)) % numTilesTotal);
    int frameCounter_total_W = (int(g_Time*float(m_Speed)) % totalTW);
    int startTile = ((startTy - 1) * iNumTilesU) + (startTx - 1);
    int selectedTile = startTile;   
    selectedTile += (frameCounter / totalTW * iNumTilesU  + frameCounter_total_W );
    
    // the "1 - " bit is because otherwise it goes from right to left
   texCoordAni.x = -(1.0 - float((texCoordAni.x + mod(float(selectedTile),  float(iNumTilesU))) / float(iNumTilesU)));
   texCoordAni.y = (-texCoordAni.y - float(selectedTile / iNumTilesU)) / float(iNumTilesV);

}[/java]

If your texture coordinates are negative you’ll have to set the wrap mode of your texture to “repeat”, by default only values 0.0 to 1.0 are mapped.

Thank you! That fixed it :slight_smile: