Possibly wring specular position in GUI node 3D object

Hello, i have a 3D spehere in my GUI node. It shoud have diffuse normal and specular textures, but i noticed that specularity does not work for some reason. After a lot of playing and tweaking i noticed that the specular effect appears at wrong position. It should appear in the direction of the light source, shouldn’t it?

The following is a very simple example demonstrating the issue:

import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Sphere;
import com.jme3.util.TangentBinormalGenerator;

public class Test extends SimpleApplication {

    public static void main(final String[] args) {
        final Test app = new Test();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        final DirectionalLight directionalLight = new DirectionalLight();
        directionalLight.setDirection(new Vector3f(0f, -1f, -1f));
        directionalLight.setColor(ColorRGBA.White);
        guiNode.addLight(directionalLight);

        final Sphere planetMesh = new Sphere(128, 128, 1f);
        final Geometry planetGeometry = new Geometry("Planet", planetMesh);

        final float size = Math.min(settings.getWidth(), settings.getHeight());
        planetGeometry.setLocalScale(size * .3f);

        TangentBinormalGenerator.generate(planetGeometry);

        final Material planetMaterial = new Material(assetManager,
                "Common/MatDefs/Light/Lighting.j3md");

        planetMaterial.setBoolean("UseMaterialColors", true);
        planetMaterial.setColor("Diffuse", ColorRGBA.White);
        planetMaterial.setColor("Specular", ColorRGBA.Red.mult(20));
        planetMaterial.setFloat("Shininess", 128f);

        planetGeometry.setMaterial(planetMaterial);

        final Node planetNode = new Node();
        planetNode.setLocalTranslation(settings.getWidth() / 2, settings.getHeight() / 2, 0);
        planetNode.attachChild(planetGeometry);

        guiNode.attachChild(planetNode);
    }
}

I would expect the red shining at the upper-middle part of the sphere.

Am i right about this, or am i doing something improperly?

(there are reasons why i’m attachign the sphere to the GUI node)

Thanks in advance.

And what are those reasons? The guiNode will give you lots of trouble for 3D objects. It’s almost always better to configure your own viewport instead.

Because i need to attach a background image, and psoitioning/sizing is much simpler in the GUI node, etc… but sure it would be possible to use the root node, i just wanted to know if i’m doing something wrong or the GUI node is buggy…

The gui node is for 2D things… so it’s hard to say if it’s “buggy” when you try to render 3D things and they don’t turn out right. By that standard, my car is a very bad airplane.

Put your background image in the guiNode then create another viewport for your 3D stuff in front of it… position it such that things are just as “easy to position”… but at least it will be 3D for real and you won’t encounter all of the other issues you’re bound to hit.

As to your issue, it may have something to do with the non-position of the non-camera in a 2D view relative to the position of your object. See, 3D stuff gets a little weird in 2D ortho mode.

Thanks for your suggestionts.

If i got it correctly:

  • set up a viewport with the background image on it’s GUI node
  • set up another transparent and overlapping viewport with the 3D elements on it’s rootnode and the “always on top” 2D elements on it’s gui node

Additional viewports will not have a “guiNode” unless you set one up. Viewport only has what you put in it.

You could continue to use the existing guiNode for your background and create an additional viewport on top of it. Or you could simply set your 3D viewport up such that it is easier to put a background image in it. (There is a distance at which 1 unit = 1 pixel.) Or at that point you can use the rootNode for it.

At any rate, 2 new viewports (a new 3D one and a new 2D one) are a valid approach.