Problems understanding light

Hello all,



I’m trying to setup the sun in my world which should be a matter of coding:

[java]DirectionalLight sun = new DirectionalLight();

sun.setColor(ColorRGBA.White);

sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());

rootNode.addLight(sun);[/java]



But I’m getting this:





I don’t understand what the problem is.



P.S.: The texture I’m using is a plain color blue square saved in png.

Make sure you are using the TerrainLighting material.

The light init code looks ok, could you provide your terrain init code please?

Thanks for the reply.

I am using TerrainLighting.j3md



Here is the terrain init code:



[java]private void initTerrain(Application app) {

// HEIGHTMAP image (for the terrain heightmap)

float[] greyScaleValues = convertBufferedImageToArray(heightMap);

TerrainQuad terrain = new TerrainQuad(TERRAIN_NAME, PATCH_SIZE, MAP_SIZE + 1, greyScaleValues);

TerrainLodControl control = new TerrainLodControl(terrain, app.getCamera());

control.setLodCalculator(new DistanceLodCalculator(65, 2.7f)); // patch size, and a multiplier

terrain.addControl(control);

setTextureTerrain(terrain);

terrain.setModelBound(new BoundingBox());

terrain.updateModelBound();

terrain.setLocalTranslation(0, -300, 0);

terrain.setLocalScale(1f, 1f, 1f);

this.app.getRootNode().attachChild(terrain);

}



private void setTextureTerrain(TerrainQuad terrain) {

Material matTerrain = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");

matTerrain.setBoolean("useTriPlanarMapping", true);

matTerrain.setFloat("Shininess", 0.0f);

matTerrain.setTexture("AlphaMap",

assetManager.loadTexture(PATH_ASSETS_TEXTURES_TERRAIN + "/mapas/alphaBathymetry.jpg"));



setTexture(matTerrain, "/texturas/water_723-diffuse.jpg", "/texturas/water_723-normal.jpg",

TEXTURE_MAP.ALPHA_GREEN, 16);



setTexture(matTerrain, "/texturas/simpleTextureLight.png", "",

TEXTURE_MAP.ALPHA_RED, 16);



terrain.setMaterial(matTerrain);

}



private void setTexture(Material material, String diffuseImagePath, String normalMapPath, TEXTURE_MAP channel,

int textureScale) {

// load diffuse texture image

Texture diffuseTexture = assetManager.loadTexture(PATH_ASSETS_TEXTURES_TERRAIN + diffuseImagePath);

diffuseTexture.setWrap(WrapMode.Repeat);

// associate with one channel in alpha

material.setTexture(channel.getDiffuse(), diffuseTexture);

// define texture scale

material.setFloat(channel.getDiffuseScale(), textureScale);

if (normalMapPath.length() > 0) {

// setup normalMap of texture

Texture normalMapTexture = assetManager.loadTexture(PATH_ASSETS_TEXTURES_TERRAIN + normalMapPath);

normalMapTexture.setWrap(WrapMode.Repeat);

// add to the material

material.setTexture(channel.getNormal(), normalMapTexture);

}

}[/java]



The alphaBathymetry.jpg is a 1024*1024 image completely red.

Are you sure using negative numbers is what you want? From my understanding of things, this would put the light source from beneath you… Maybe try setting your Y vector to some positive value.

When you where talking about negative you meant the direction on the light vector, right?



When I use

  • (-0.5, 0.5, -0.5) I just get black
  • (0.5, 0.5, 0.5) I get this


  • (1.5, 0.5, 0.5) I get this





    I think my problem is that I don’t understand the reference points. Is the light’s reference point the same as the translation’s?

    How can I check for the orientation of the xyz unit vector for light, models and camera?

It all depends on where the light is attached.



Usually you attach a light to either a node or a spatial (which is the same since node extends spatial). So, depending on where that spatial is located, the light will be emitted from that point.



I imagine the spatial to which your light is attached to is below ground level, thus the result you were getting. Y is the elevation.

Ok, I see.



But I still don’t understand the black lines.

If I start moving around they even get more blurry.





I would expect something smooth. More like a surface graph.

Is it that the polygons are to big and they make one consistent line of shadow hence the black line?

I imagine you’re using PSSM? If that’s the case then I would imagine some parameter is wrong. I’ve haven’t used that so, that’s all the help I can give on the subject.



If not, then I’m not sure at all what could cause that.

I’m getting the points out of a buffered image, if that counts as PSSM then yes.



But I’m pretty sure something is really wrong, if I add another texture with a real image and normal map then I can only see anything with negative vector for light direction and even then it appears all brown when it’s almost black.

After some research I realizes I misinterpreted PSSM as Position-specific scoring matrix (as in instead of a image I give an array) and not Parallel-Split Shadow Map technique.



I’m not using the technique.

What version of jme are you using? If not the latest stable beta, upgrade to that.

I’m using in eclipse so that would mean downloading + removing all the jars + adding them again?



I’m using jME3_2012-05-29.zip

That version seems recent enough to be fine, I just wanted to make sure you weren’t using alpha 4.

So I am seeing several problems in the images you posted. One issue is the terrain is not smooth. After you import your heightmap run heightmap.smooth() to get rid of the ledges. Or in your photo editing program you can use a blur to correct those levels. That might correct some of this, but I think there are still some other things going on.

There is one thing going on but I’m not sure how big the impact really is.



I’m using a generated image and it turns out that the calculations to greyscale generate a BufferedImage that has only integer values.

So adjacent values are something like

85.0 85.0 85.0 83.0 83.0 83.0

84.0 84.0 84.0 84.0 83.0 83.0

83.0 83.0 82.0 82.0 81.0 81.0



Could this be the problem?



I can’t use smooth for a BufferedImage/array.

Ya that would cause levels. Take a look at AbstractHeightmap.smooth() and see what the code does there to smooth out the array of height values, then apply it to your height array.

Thanks for the tip!



It turns out that I can pretty much copy+paste the whole method just changing where the array variable is coming from.

Maybe it would be cool to add a method that takes in an array and then applies smooth to that array. I guess to put it in the AbstractHeightMap is not very good organization but if there is an utility class the method could go there and then AbstractHeightMap would call it.