Normal Mapping With SceneWorker

This is a tutorial to show how to get normal mapping working with Scene Worker. NOTE : this normal map example does not include Specular Hilights.

Normal mapping requires 3 things;

  1. A Texture Map and a Normal Map

  2. A Normal Mapping Shader

  3. Per vertex tangent and binormal values

    In this example I’m going to use the following Textures;

    Texture Map


    Normal Map


    So Open Scene Worker. Select rootNode, right click and select New Primitive -> Add Box.

    Now Select the newly created box, right click and select New Renderstate. Select TextureState and click add, select GLSLShaderObjectsState and click add.

    Now select the newly create TextureState, right click and select Load Texture. Navigate to the texture map and add it as a texture. Now do the same again and this time select the normal map image.

    Now your scene should look like this, ie a multitextured box;

    [caption id=“attachment_11” align=“alignnone” width=“150” caption=“MultiTexturedBox”]MultiTexturedBox[/caption]

    Ok now we need to create the shader that will texture this box using the normal map. Select the GLSLShaderObject State for the box. In the properties of the shader Click on the entry that has the text “Click to Edit Shader”.

    You are now in the GLSL shader editor. In the snippets menu select “Normal Map No Specular”. This will create a simple normal mapping shader for you. Note that the uniforms baseMap and normalMap have also been created via the snippet macro. We need to edit these uniforms to “point” at which texture is which. Select the baseMap uniform. Note the value is 0 which is correct, i.e. the first texture in the objects TextureState. Now select normalMap. You can see that this value is also 0. This needs to be edited to be the index of the normal map texture. Click edit, enter 1 and select update. Now compile both the vertex and the fragment shader. Now select Update Shader State and click done. Your object should now look like this.

    [caption id=“attachment_14” align=“alignnone” width=“150” caption=“Incorrectly NormalMapped Object”]Incorrectly NormalMapped Object[/caption]

    Now select rootNode, right click and select New Controller, select BeanShellController, select the controller and click in Click To Edit box of the Script property. Paste the following code into the text area;

    // the update method is called on every update of the controller

    // the object parameter is the spatial that the controller is attached to

    import com.jme.scene.state.;

    import com.jme.light.

    boolean up = false;

    update(object) {

    LightState ls = object.getRenderState(RenderState.StateType.Light);

    PointLight pl = ls.get(0);

    if(up) {

    if(pl.getLocation().y > 110) {

    up = false;


    } else {

    if(pl.getLocation().y < 0) {

    up = true;



    pl.getLocation().y += (up ? 0.1f : -0.1f);


    This code will simply animate the light in the scene. Reselect the box. Note that the texture of the box is incorrectly lit, ie it is no changing with regards to the lights position. We must generate per vertex tangents and binormals for the normal mapping shader to work correctly. This data correctly defines the normals in texture space. A more detailed description can be found at;

    Explanation of Tangent Space

    So select the box object. Right click and select Utils -> Execute BeanShellScript On Object. Select Tangent and Binormal Calculator from the Snippets menu. Select Execute. Once the script has executed you should now see the box being lit correctly. The following video shows the end result of the tutorial;


    Normal Mapped Box Video

    Read the original article

I'm not up to date at all cause I just took cognizance of Scene Worker which seems to be a great tool ! Thanks for the tutorial by the way !

I wonder if it is possible to use the normalmap with wrapping and repeat it several times? For that the shader have to be modified, right!? Or is it already possible?

i've applied the change in the shader to use the texture matrix on the texture coord…

so in the next version you will be able to do wrapping…