Hello!
I’ve been chasing my tail for hours, maybe even more than a day at this point, with a passing variables to a custom shader. The weirdness that I can’t explain is that when I hardcode the values that should be passed into the shader, it works as expected. However, when I change it to use variables that should be passed from the main program to the shader, it chokes and gives me the wrong result (usually just maps the entire quad with the 0,0 pixel of the texture). I bet I’m doing something stupid, but I can’t put my finger on where I fouled it up. Also, should the variables that I pass from the program to the shader be uniforms or attributes? I read the documentation on this, from here and other sites, and it still isn’t clear to me. I used uniforms only because it seemed like everything else being passed in was as well I get some complaints from the shader when it’s loaded, but I don’t understand if this is just the shader looking for prefixed m_ variables as well as the ones in the shader, because when I add m_ to my variables, it adds ANOTHER m_, so you end up with m_m_variable.
[java]
Mar 3, 2011 9:33:31 AM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_Sprite_X is not declared in shader.
Mar 3, 2011 9:33:31 AM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_Sprite_Y is not declared in shader.
Mar 3, 2011 9:33:31 AM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_FrameDimensions is not declared in shader.
Mar 3, 2011 9:33:31 AM com.jme3.renderer.lwjgl.LwjglRenderer updateUniformLocation
INFO: Uniform m_VertexColor is not declared in shader.
[/java]
I just tried some things with keeping everything a float, read somewhere that integers aren’t generally welcomed by shaders, but still no dice. It just breaks differently.
If someone could take a quick look at this to see if there’s any glaring issues, that would be great. All it is, is a modification to the Lighting.j3md and Lighting.vert shader files to allow for only displaying a portion of a texture and to be able to modify this position to allow for animated textures/spriting. My only modifications are to the j3md in adding the variables, a renderstate, and some modification to the main method in the vert.
Thanks!
EDIT: Fixed a typo in part of the shader that was preventing it from working 100%. Using X’s Dimensions to process Y’s size is inaccurate!
My test file:
[java]
public class TestSpriteShader extends SimpleApplication {
private static AppSettings settings;
public static void main(String[] args) {
TestSpriteShader app = new TestSpriteShader();
settings = new AppSettings(true);
settings.setFrameRate(150);
settings.setTitle(“Test Sprite Shader”);
app.setSettings(settings);
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(30f);
Quad q = new Quad(4, 4);
Geometry g = new Geometry(“Quad”, q);
Material m = new Material(assetManager, “resources/sprite/SpriteLighting.j3md”);
Texture texture = assetManager.loadTexture(“resources/sprite/sprite_dummy.png”);
texture.setMagFilter(MagFilter.Nearest);
texture.setMinFilter(MinFilter.Trilinear);
m.setTexture(“DiffuseMap”, texture);
m.setFloat(“Shininess”, 1000f);
m.setInt(“Sprite_X”, 64);
m.setInt(“Sprite_Y”, 64);
m.setVector2(“FrameDimensions”, new Vector2f(64, 64));
g.setMaterial(m);
g.setQueueBucket(Bucket.Transparent);
rootNode.attachChild(g);
PointLight pl = new PointLight();
pl.setPosition(new Vector3f(1,1,1));
pl.setRadius(30f);
pl.setColor(ColorRGBA.White.clone());
rootNode.addLight(pl);
}
}
[/java]
The SpriteLighting.j3md:
[java]
MaterialDef Phong SpriteLighting {
MaterialParameters {
// Compute vertex lighting in the shader
// For better performance
Boolean VertexLighting
// Use more efficent algorithms to improve performance
Boolean LowQuality
// Improve quality at the cost of performance
Boolean HighQuality
// Output alpha from the diffuse map
Boolean UseAlpha
// Apha threshold for fragment discarding
Float AlphaDiscardThreshold
// Normal map is in BC5/ATI2n/LATC/3Dc compression format
Boolean LATC
// Use the provided ambient, diffuse, and specular colors
Boolean UseMaterialColors
// Activate shading along the tangent, instead of the normal
// Requires tangent data to be available on the model.
Boolean VTangent
// Use minnaert diffuse instead of lambert
Boolean Minnaert
// Use ward specular instead of phong
Boolean WardIso
// Use vertex color as an additional diffuse color.
Boolean UseVertexColor
// Ambient color
Color Ambient
// Diffuse color
Color Diffuse
// Specular color
Color Specular
// Specular power/shininess
Float Shininess
// Diffuse map
Texture2D DiffuseMap
// Normal map
Texture2D NormalMap
// Specular/gloss map
Texture2D SpecularMap
// Parallax/height map
Texture2D ParallaxMap
// Texture that specifies alpha values
Texture2D AlphaMap
// Color ramp, will map diffuse and specular values through it.
Texture2D ColorRamp
// Texture of the glowing parts of the material
Texture2D GlowMap
// The glow color of the object
Color GlowColor
// The X value of the upper left pixel of the DiffuseMap
Int Sprite_X
// The Y value of the upper left pixel of the DiffuseMap
Int Sprite_Y
// The Dimensions of the Sprite’s frame
Vector2 FrameDimensions
}
Technique {
LightMode MultiPass
VertexShader GLSL100: resources/sprite/SpriteLighting.vert
FragmentShader GLSL100: Common/MatDefs/Light/Lighting.frag
WorldParameters {
WorldViewProjectionMatrix
NormalMatrix
WorldViewMatrix
ViewMatrix
}
RenderState {
Blend Alpha
}
Defines {
LATC : LATC
VERTEX_COLOR : UseVertexColor
VERTEX_LIGHTING : VertexLighting
ATTENUATION : Attenuation
MATERIAL_COLORS : UseMaterialColors
V_TANGENT : VTangent
MINNAERT : Minnaert
WARDISO : WardIso
LOW_QUALITY : LowQuality
HQ_ATTENUATION : HighQuality
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
PARALLAXMAP : ParallaxMap
ALPHAMAP : AlphaMap
COLORRAMP : ColorRamp
}
}
Technique PreShadow {
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
FragmentShader GLSL100 : Common/MatDefs/Shadow/PreShadow.frag
WorldParameters {
WorldViewProjectionMatrix
WorldViewMatrix
}
Defines {
DIFFUSEMAP_ALPHA : DiffuseMap
}
RenderState {
FaceCull Off
DepthTest On
DepthWrite On
PolyOffset 5 0
ColorWrite Off
}
}
Technique PreNormalPass {
VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert
FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag
WorldParameters {
WorldViewProjectionMatrix
WorldViewMatrix
NormalMatrix
}
Defines {
DIFFUSEMAP_ALPHA : DiffuseMap
}
RenderState {
}
}
Technique GBuf {
VertexShader GLSL100: Common/MatDefs/Light/GBuf.vert
FragmentShader GLSL100: Common/MatDefs/Light/GBuf.frag
WorldParameters {
WorldViewProjectionMatrix
WorldMatrix
}
Defines {
VERTEX_COLOR : UseVertexColor
MATERIAL_COLORS : UseMaterialColors
V_TANGENT : VTangent
MINNAERT : Minnaert
WARDISO : WardIso
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
PARALLAXMAP : ParallaxMap
}
}
Technique FixedFunc {
LightMode FixedPipeline
}
Technique Glow {
VertexShader GLSL100: Common/MatDefs/Misc/SimpleTextured.vert
FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag
WorldParameters {
WorldViewProjectionMatrix
}
Defines {
HAS_GLOWMAP : GlowMap
HAS_GLOWCOLOR : GlowColor
}
}
}
[/java]
The SpriteLighting.vert:
[java]
#define ATTENUATION
//#define HQ_ATTENUATION
uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform mat3 g_NormalMatrix;
uniform mat4 g_ViewMatrix;
uniform vec4 m_Ambient;
uniform vec4 m_Diffuse;
uniform vec4 m_Specular;
uniform float m_Shininess;
uniform vec4 g_LightColor;
uniform vec4 g_LightPosition;
uniform vec4 g_AmbientLightColor;
uniform int Sprite_X;
uniform int Sprite_Y;
uniform vec2 FrameDimensions;
varying vec2 texCoord;
varying vec4 AmbientSum;
varying vec4 DiffuseSum;
varying vec4 SpecularSum;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
attribute vec3 inNormal;
#ifdef HQ_ATTENUATION
varying vec3 lightVec;
#endif
#ifdef VERTEX_COLOR
attribute vec4 inColor;
#endif
#ifndef VERTEX_LIGHTING
attribute vec4 inTangent;
#ifndef NORMALMAP
varying vec3 vNormal;
#endif
varying vec3 vPosition;
varying vec3 vViewDir;
varying vec4 vLightDir;
#endif
// JME3 lights in world space
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
float posLight = step(0.5, color.w);
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
#ifdef ATTENUATION
float dist = length(tempVec);
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
lightDir.xyz = tempVec / vec3(dist);
#ifdef HQ_ATTENUATION
lightVec = tempVec;
#endif
#else
lightDir = vec4(normalize(tempVec), 1.0);
#endif
}
#ifdef VERTEX_LIGHTING
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
return max(0.0, dot(norm, lightdir));
}
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
#ifndef LOW_QUALITY
vec3 H = (viewdir + lightdir) * vec3(0.5);
return pow(max(dot(H, norm), 0.0), shiny);
#else
return 0.0;
#endif
}
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightPos){
vec4 lightDir;
lightComputeDir(wvPos, g_LightColor, wvLightPos, lightDir);
float diffuseFactor = lightComputeDiffuse(wvNorm, lightDir.xyz);
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, lightDir.xyz, m_Shininess);
//specularFactor *= step(0.01, diffuseFactor);
return vec2(diffuseFactor, specularFactor) * vec2(lightDir.w);
}
#endif
void main(){
vec4 pos = vec4(inPosition, 1.0);
gl_Position = g_WorldViewProjectionMatrix * pos;
// texCoord = inTexCoord;
float uv_XDim = FrameDimensions[0] / 2048.0;
float uv_YDim = FrameDimensions[1] / 2048.0;
float possibleColumns = floor(1.0 / uv_XDim);
float possibleRows = floor(1.0 / uv_YDim);
float currCol = Sprite_X / FrameDimensions[0];
float currRow = Sprite_Y / FrameDimensions[1];
// I don’t think my variables are getting passed in or something.
// However, the 0.03125 would be uv_XDim and uv_YDim
// The 32 is possibleCols and possibleRows
// And the 0 is currCol, 1 is currRow
texCoord = vec2((inTexCoord[0] / possibleColumns)
- (uv_XDim * currCol),
(inTexCoord[1] / possibleRows)
- ((1.0 - uv_YDim) - (uv_YDim * currRow)));
vec3 wvPosition = (g_WorldViewMatrix * pos).xyz;
vec3 wvNormal = normalize(g_NormalMatrix * inNormal);
vec3 viewDir = normalize(-wvPosition);
//vec4 lightColor = g_LightColor[gl_InstanceID];
//vec4 lightPos = g_LightPosition[gl_InstanceID];
//vec4 wvLightPos = (g_ViewMatrix * vec4(lightPos.xyz, lightColor.w));
//wvLightPos.w = lightPos.w;
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz, g_LightColor.w));
wvLightPos.w = g_LightPosition.w;
vec4 lightColor = g_LightColor;
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
vec3 wvBinormal = cross(wvNormal, wvTangent);
mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
vPosition = wvPosition * tbnMat;
vViewDir = viewDir * tbnMat;
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
#elif !defined(VERTEX_LIGHTING)
vNormal = wvNormal;
vPosition = wvPosition;
vViewDir = viewDir;
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
#ifdef V_TANGENT
vNormal = normalize(g_NormalMatrix * inTangent.xyz);
vNormal = -cross(cross(vLightDir.xyz, vNormal), vNormal);
#endif
#endif
lightColor.w = 1.0;
#ifdef MATERIAL_COLORS
AmbientSum = m_Ambient * g_AmbientLightColor;
DiffuseSum = m_Diffuse * lightColor;
SpecularSum = m_Specular * lightColor;
#else
AmbientSum = vec4(0.2, 0.2, 0.2, 1.0) * g_AmbientLightColor; // Default: ambient color is dark gray
DiffuseSum = lightColor;
SpecularSum = lightColor;
#endif
#ifdef VERTEX_COLOR
AmbientSum *= inColor;
DiffuseSum *= inColor;
#endif
#ifdef VERTEX_LIGHTING
vec2 light = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);
AmbientSum.a = light.x;
SpecularSum.a = light.y;
#endif
}
[/java]