Basic Shader question

Hello, i wanted to give shaders a try, but i can’t even make a simplest solid color working.

What is wrong here?



.jm3d

[java]

MaterialDef PlanetMaterial {



MaterialParameters {

Color m_Color1

}



Technique {

VertexShader GLSL120: Shaders/PlanetMaterial/PlanetMaterial.vert

FragmentShader GLSL120: Shaders/PlanetMaterial/PlanetMaterial.frag



WorldParameters {

WorldViewProjectionMatrix

}

}



}

[/java]



.frag

[java]

/*

  • fragment shader template

    /

    uniform vec4 m_Color1;



    void main() {

    // Set the fragment color for example to gray, alpha 1.0

    gl_FragColor=m_Color1;

    }

    [/java]



    .vert

    [java]/

  • vertex shader template

    /



    uniform mat4 g_WorldViewProjectionMatrix;

    attribute vec3 inPosition;



    void main() {

    // Vertex transformation

    gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

    }

    [/java]



    TestMateriial.j3m

    [java]/

  • vertex shader template

    */



    uniform mat4 g_WorldViewProjectionMatrix;

    attribute vec3 inPosition;



    void main() {

    // Vertex transformation

    gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

    }

    [/java]



    Test.java

    [java]package mygame;



    import com.jme3.app.SimpleApplication;

    import com.jme3.light.AmbientLight;

    import com.jme3.material.Material;

    import com.jme3.math.ColorRGBA;

    import com.jme3.math.Vector3f;

    import com.jme3.renderer.RenderManager;

    import com.jme3.scene.Geometry;

    import com.jme3.scene.shape.Box;

    import com.jme3.scene.shape.Sphere;



    /**
  • test
  • @author normenhansen

    /

    public class Main extends SimpleApplication {



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {

    Sphere b = new Sphere(100,100,1f);

    Geometry geom = new Geometry("Sphere", b);



    Material mat = this.assetManager.loadMaterial("Materials/TestMaterial.j3m");

    geom.setMaterial(mat);

    this.flyCam.setMoveSpeed(100f);

    rootNode.attachChild(geom);



    /
    * A white ambient light source. */

    AmbientLight ambient = new AmbientLight();

    ambient.setColor(ColorRGBA.White);

    rootNode.addLight(ambient);





    }



    @Override

    public void simpleUpdate(float tpf) {

    //TODO: add update code

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    }

    [/java]

For starter, this is wrong.



[java]

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

[/java]



You don’t need to use a vec4.



[java]

gl_Position = g_WorldViewProjectionMatrix * inPosition;

[/java]



inPosition should be defined as:



in vec4 inPosition;



What it means is that inPosition should be a vec4 as it comes in. Thus no “casting” should be done. Of course if you’re certain the “alpha” or w is wrong that might be the best way.

1 Like
  1. remove the m_ prefix of the Color1 variable in the j3md file. Keep them in the shader files, jME will add them when parsing the j3md file since the m_ stands for material parameter.
  2. your .j3m file is wrong, (same as .vert file…). Please post it… :slight_smile:

@madjack, sure the inPosition is a vec4? I always do it like it’s done by zzuregg…

@kwando said:
1. remove the m_ prefix of the Color1 variable in the j3md file. Keep them in the shader files, jME will add them when parsing the j3md file since the m_ stands for material parameter.


Yeah. Definitively that. In the case above, the shader, for it to work, should use m_m_Color1... ;)
1 Like
@kwando said:
@madjack, sure the inPosition is a vec4? I always do it like it's done by zzuregg..


Here's my sun .vert shader... :)

[java]

/*
* 4D animated noise texture GLSL vert shader.
*/
uniform float g_Time;

uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform mat4 g_ProjectionMatrix;

in vec4 inPosition;
in float m_Radius;

out vec4 texCoord4D;

void main( void )
{
gl_Position = g_ProjectionMatrix * g_WorldViewMatrix * inPosition;
texCoord4D = inPosition / (16 + m_Radius);
}
[/java]
1 Like

just as a simple help

m_ is added for material variables/uniforsm

a_ is added for mesh attributes

→ to prevent name collisions

@madjack said:
For starter, this is wrong.

[java]
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
[/java]

You don't need to use a vec4.

[java]
gl_Position = g_WorldViewProjectionMatrix * inPosition;
[/java]

inPosition should be defined as:

in vec4 inPosition;

What it means is that inPosition should be a vec4 as it comes in. Thus no "casting" should be done. Of course if you're certain the "alpha" or w is wrong that might be the best way.

Not necessarily, the value passed from JME is a vector3f which would correspond to a vec3, so it's ok getting it as a vec3 and adding 1.0 for the w value in the constructor.
Also it works if you use directly a vec4 and by some magic that i don't know a 1.0 is automatically fed into the w value....but since i don't know what does it, i prefer doing it with a vec3, because if on some drivers the w value is 0, the result would be unexpected...



@EmpirePhoenix said:
just as a simple help
m_ is added for material variables/uniforsm

right and that might be your problem @zzuegg. You define your color as m_Color1 in your j3md file, it should be Color1.
However the name of the uniform in the shader is fine (m_Color1) don't change it.

@EmpirePhoenix said:
a_ is added for mesh attributes

nope it's "in" not "a_"

Thank you all, removing the a_ did the trick.



This is the result up to now, my first generated planet :smiley: It allows to select 4 colors, as well as the ratio each layer should take from previous one, and of course setting a seed.



http://i.imgur.com/Avxhx.png





Some more questions, as you can see, the colors switch the ‘hard way’, I had to do that because adding the color simply with a plus (Color1.xyzstrengt + Color2.xyzstrenght) leads of course to weired results,



Add, for making animation stuff, i would need to access to something like a counter variable, does something like that exist?

you can have a global uniform called float g_Time that is the time since the app started.



in your j3md add Time in the world parameters section of the technique

[java]

MaterialDef PlanetMaterial {



MaterialParameters {

Color m_Color1

}



Technique {

VertexShader GLSL120: Shaders/PlanetMaterial/PlanetMaterial.vert

FragmentShader GLSL120: Shaders/PlanetMaterial/PlanetMaterial.frag



WorldParameters {

WorldViewProjectionMatrix

Time

}

}



}

[/java]



then in your shader decalre



[java]

uniform float g_Time;

[/java]