Confused with GLSL Shader

Today Morning I found the ConeStepMapDemo.

I like it, and I wanted to use the GLSL SHader in Jmonkey, but I am confused, noting works :frowning:

My TestCode:

package parallax;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Box;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;

public class Test extends SimpleGame {
    private static final Logger logger = Logger.getLogger(Test.class
    private Vector3f lightDir = new Vector3f();
    private GLSLShaderObjectsState so;
    private String vertexString = "resources/csm/shared.vert";
    private String fragmentString = "resources/csm/relief.frag";
     public static void main(String[] args) {
       Test app = new Test();

    protected void simpleUpdate() {
        if (KeyBindingManager.getKeyBindingManager().isValidCommand(
                "reloadShader", false)) {

        float spinValX = FastMath.sin(timer.getTimeInSeconds() * 2.0f);
        float spinValY = FastMath.cos(timer.getTimeInSeconds() * 2.0f);
        lightDir.set(spinValX, spinValY, -1.0f).normalizeLocal();

    public void reloadShader() {
        GLSLShaderObjectsState testShader = DisplaySystem.getDisplaySystem()
        try {
        } catch (JmeException e) {
            logger.log(Level.WARNING, "Failed to reload shader", e);

              vertexString), Test.class
        so.setUniform("reliefmap", 0);
        so.setUniform("texmap", 1);       
      "Shader reloaded...");

    protected void simpleInitGame() {

        // Our model is Z up so orient the camera properly.
        cam.setAxes(new Vector3f(-1, 0, 0), new Vector3f(0, 0, 1),
                new Vector3f(0, 1, 0));
        cam.setLocation(new Vector3f(0, -100, 0));

        // Create a directional light
        DirectionalLight dr = new DirectionalLight();
        dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        dr.setAmbient(new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f));
        dr.setSpecular(new ColorRGBA(0.7f, 0.7f, 0.7f, 1.0f));


        Box box = new Box("box", new Vector3f(), 25, 25, 25);

        try {
                    new SimpleResourceLocator(getClass().getResource("../resources/csm/")));
        } catch (URISyntaxException e1) {
            logger.warning("Unable to add texture directory to RLT: "
                    + e1.toString());
        so = display.getRenderer().createGLSLShaderObjectsState();

        // Check is GLSL is supported on current hardware.
        if (!so.isSupported()) {
            logger.severe("Your graphics card does not support GLSL programs, and thus cannot run this test.");


        TextureState ts = display.getRenderer().createTextureState();       
        Texture heightMap = TextureManager.loadTexture(Test.class
                Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR,
                Image.GUESS_FORMAT_NO_S3TC, 0.0f, true);
        ts.setTexture(heightMap, 0);

        Texture baseMap = TextureManager.loadTexture(Test.class
                Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
        ts.setTexture(baseMap, 1);   
        MaterialState ms = display.getRenderer().createMaterialState();
        ms.setAmbient(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        ms.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        ms.setSpecular(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));

        // Set all states on model

        rootNode.updateGeometricState(0, true);

         input = new FirstPersonHandler( cam, 80, 1 );

and the original Shaders:


//  input from the user
uniform float csm_gain;
uniform float csm_offset;
uniform float texsize;

//  interpolate these and pass
//  them into the fragment shader
varying vec2 texCoord;
varying vec3 vertex_pos;
varying vec3 light_pos;
varying float vertex_dist;
varying float light_dist;

//  distance to the point
varying float dist_val;

void main(void)
   // location of the vertex in eye space
   vec3 eyeSpaceVert = (gl_ModelViewMatrix * gl_Vertex).xyz;
   // convert to eyeSpace for programs other than Irrlicht
   //eyeSpaceLight = (gl_ModelViewMatrix * vec4(gl_LightSource[0],1.0)).xyz;
   // gl_LightSource[n].position is already in eyeSpace from Irrlicht!
   vec3 eyeSpaceLight = gl_LightSource[0];
   //  the matrix needed to convert to eye space
   //  (this is local, and should already be normalized, I think)
   vec3 eyeSpaceTangent  = normalize(gl_NormalMatrix *;   //tangent;
   vec3 eyeSpaceBinormal = normalize(gl_NormalMatrix * (;   //binormal;
   vec3 eyeSpaceNormal   = normalize(gl_NormalMatrix * gl_Normal); //normal
   // now convert the light and position, and pass in the texture coordinate
   vertex_pos = vec3 (
        dot (eyeSpaceTangent, eyeSpaceVert),
        dot (eyeSpaceBinormal, eyeSpaceVert),
        dot (eyeSpaceNormal, eyeSpaceVert));
   light_pos = vec3 (
        dot (eyeSpaceTangent, eyeSpaceLight),
        dot (eyeSpaceBinormal, eyeSpaceLight),
        dot (eyeSpaceNormal, eyeSpaceLight))
        - vertex_pos;
   vertex_dist = length (eyeSpaceVert);
   light_dist = length (light_pos);
   //light_pos /= light_dist;
   texCoord   = gl_MultiTexCoord0.xy;
   //  for the LOD
   dist_val = (0.00333 * vertex_dist * csm_gain + csm_offset)
      / texsize;
   // done
   gl_Position = ftransform();


uniform float depth;
uniform float texsize;
uniform int linear_search_steps;
uniform int binary_search_steps;

varying vec2 texCoord;
varying vec3 vertex_pos;
varying vec3 light_pos;
varying float vertex_dist;
varying float light_dist;
varying float dist_val;

uniform sampler2D reliefmap;
uniform sampler2D texmap;

void ray_intersect_rm (inout vec3 dp, in vec3 ds);

void main(void)
   vec4 t,c;
   vec3 l,s;
   vec3 pt_eye, pt_light;
   float a;

   // ray intersect in view direction
   a  = -depth / vertex_pos.z;
   s = vertex_pos * a;
   s.z = 1.0;
   //   find the distance to the actualy heightfield
   pt_eye = vec3 (texCoord, 0.0);
   ray_intersect_rm (pt_eye, s);
   gl_FragColor = vec4(pt_eye.z, 0, 0, 0);
   // get rm and color texture points

   // expand normal from normal map in local polygon space
   // blue = df/dx
   // alpha = df/dy (image coords are no longer backward!)
   // note: I _need_ the texture size to scale the normal properly!
   t=texture2D(reliefmap, pt_eye.xy);
   t = vec4 (( * (-depth * texsize), 1.0, 0.0);

   // adjust the hit-position
   // (only useful if the light is near relative
   // to the depth)
   //p -= v*d*a;
   // compute attenuation
   float att = gl_LightSource[0].linearAttenuation;
   att = min (1.0, 1.0 / (light_dist*att));
   // rescale the light vector
   l = att * normalize(light_pos);

   // compute the final color
   gl_FragColor = vec4(

//  vanilla Relief Mapping
void ray_intersect_rm (inout vec3 dp, in vec3 ds)
  float depth_step=1.0/float(linear_search_steps);
  //  linear steps
  for (int i = 0; i < linear_search_steps; ++i)
    vec4 t=texture2D(reliefmap,dp.xy);
    dp += ds * depth_step * step (dp.z, t.r);
  //  binary search
  for (int i = 0; i < binary_search_steps; ++i)
    vec4 t=texture2D(reliefmap,dp.xy);
    dp += ds * depth_step * (step (dp.z, t.r) - 0.5);
    depth_step *= 0.5;
  // all done

Now I always get the Error:

23.04.2008 18:56:02 com.jme.scene.state.lwjgl.shader.LWJGLShaderUtil updateUniformLocation
SCHWERWIEGEND: Shader uniform [csm_offset] could not be located in shader
23.04.2008 18:56:02 com.jme.scene.state.lwjgl.shader.LWJGLShaderUtil updateUniformLocation
SCHWERWIEGEND: Shader uniform [csm_gain] could not be located in shader

I dont understand this, these both values are needed in the Vertex Shader. Also when I copy them in the FragmentShader, nothing else comes.

Can SomeBody look at this? the Shaders are realy nice and the Monkey would be also happy :)

I'd guess that your shader URLs are null.

No the shaders are found. I can out of the this fragmentshader a color on the Cube, if I outcomment one Line (perhabs for debugging). But more not :frowning:

I guess you need to put the variables in the fragment shader as well?

uniform float csm_gain;
uniform float csm_offset;

You should properly debug your shaders in a shader IDE like RenderMonkey before using them in jME, that way you would have to waste less time trying to get them to work in-game.

P.S: I am tired of those monkeys being everywhere..

Jeah, Tanks, I will test it out again