Unshaded Terrain with Multiple Texture Layers [solved]

Hi There,

I’m currently making android applications and I’ve found that lighted materials are quite heavy on the device. So I’ve stuck to using unshaded materials.

This has worked great but there are some issues I’ve experienced.

The material for the terrain seems to be it’s own material, as a result I am unsure how to make the terrain appear without requiring lighting, and maintaining the multiple texture layers as added in the terrain editor.

How do I make a terrain not require lighting, yet maintain its texture layers?

you use terrain.j3md instead of terrainlighting.j3md

@normen

Can this be done directly in the scene/terrain editor?

No it cannot be done in the editor yet. I planned on adding in the ability to change terrain materials but I haven’t had enough time lately. If you are eager I can walk you through the code and how to get that feature into the SDK.

@Sploreg

I’m not super good with programming in general and that stuff may be completely over my head.

Is it possible to get the scene at run time and convert the terrains lighted material to an unlit material.

I use a similar method to change the rest of the scene over but this doesn’t work correctly with terrain, as it grabs only the bottom layer and stretches it across the entire terrain.

[java] public void makeUnshaded(Node node) {
SceneGraphVisitor sgv = new SceneGraphVisitor() {
public void visit(Spatial spatial) {
if (spatial instanceof Geometry) {
Geometry geom = (Geometry) spatial;
Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
if (geom.getMaterial().getTextureParam(“DiffuseMap”) != null) {
mat.setTexture(“ColorMap”, geom.getMaterial().getTextureParam(“DiffuseMap”).getTextureValue());
geom.setMaterial(mat);
}
}
}
};
node.depthFirstTraversal(sgv);
}[/java]

edit:

Okay going a little bit further I managed to convert it mostly to a regular terrain.j3md. But I’m still experiencing some strange behavior.

I convert the AlphaMap to the Alpha param for the new material I create, then the DiffuseMaps to the “Tex1” “Tex2” params.

It seems to be reading the alpha map correctly and the layers are correct, but I seem to lose all definition.

Am I forgetting a texture param or an option to do this possibly?

[java] Material tat = new Material(assetManager, “Common/MatDefs/Terrain/Terrain.j3md”);

    if (geom.getMaterial().getTextureParam("DiffuseMap_1") != null) {
        
      tat.setTexture("Alpha", geom.getMaterial().getTextureParam("AlphaMap").getTextureValue());
      
      if (geom.getMaterial().getTextureParam("DiffuseMap") != null) {
      tat.setTexture("Tex1", geom.getMaterial().getTextureParam("DiffuseMap").getTextureValue());   
      }
    
      if (geom.getMaterial().getTextureParam("DiffuseMap_1") != null) {
      tat.setTexture("Tex2", geom.getMaterial().getTextureParam("DiffuseMap_1").getTextureValue());      
      }
    
      if (geom.getMaterial().getTextureParam("DiffuseMap_2") != null) {
      tat.setTexture("Tex3", geom.getMaterial().getTextureParam("DiffuseMap_2").getTextureValue());
      }
      
      geom.setMaterial(tat);
      
      }[/java]

Check that you don’t have strange texture scaling. When I mess that up it looks like that, basically the texture is scaled super high so the color is from a single texel :slight_smile:

@jmaasing

How would I tell if my textures are scaled properly.

I’m going at this almost completely blind trying to transfer a lit terrain material to a regular terrain material and as you can see the alpha map and texture maps are in the right spot.

How can I check if my textures are scaled properly?

You may have the final piece I need :stuck_out_tongue:

Could it not be the repeat setting on the texture?

@ndebruyn

My current method sets the texture to repeat. It makes no difference

This is my current method… Any suggestions would be helpful

[java] Material tat = new Material(assetManager, “Common/MatDefs/Terrain/Terrain.j3md”);

    if (geom.getMaterial().getTextureParam("DiffuseMap_1") != null) {
        
      tat.setTexture("Alpha", geom.getMaterial().getTextureParam("AlphaMap").getTextureValue());
      
      if (geom.getMaterial().getTextureParam("DiffuseMap") != null) {
      tat.setTexture("Tex1", geom.getMaterial().getTextureParam("DiffuseMap").getTextureValue());
      tat.getTextureParam("Tex1").getTextureValue().setWrap(Texture.WrapMode.Repeat);
      }
    
      if (geom.getMaterial().getTextureParam("DiffuseMap_1") != null) {
      tat.setTexture("Tex2", geom.getMaterial().getTextureParam("DiffuseMap_1").getTextureValue());
      tat.getTextureParam("Tex2").getTextureValue().setWrap(Texture.WrapMode.Repeat);
      }
    
      if (geom.getMaterial().getTextureParam("DiffuseMap_2") != null) {
      tat.setTexture("Tex3", geom.getMaterial().getTextureParam("DiffuseMap_2").getTextureValue());
      tat.getTextureParam("Tex3").getTextureValue().setWrap(Texture.WrapMode.Repeat);
      }

      geom.setMaterial(tat);
      
      }[/java]

did you apply the different scale Parameters “DiffuseMap_scale” to “Tex1Scale” for each texture layer? (if you open your terrain in the SDK you can also select it’s mesh and click the create j3m file in the property panel, this material will help you find the necessary parameters, and you could probably create your unshaded material in the SDK)

Each layer has its own scale parameter that you need to set: Tex1Scale, Tex2Scale…

@Sploreg

What method would I use to retrieve and set these Scales?

I cannot seem to find how to retrieve or set these texture scales.

They are material parameters so depending on the material they have different names, here is an example:

[java]
Material mat_terrain = new Material(assetManager, “Common/MatDefs/Terrain/TerrainLighting.j3md”);
mat_terrain.setFloat(“DiffuseMap_0_scale”, 1f / 8f);
[/java]

@jmaasing

Thank you!

I’m one step closer, unfortunately being as dense as I am I can’t seem to find out how to get just the float value out of the material

mat.getParam(“DiffuseMap_0_scale”);

returns “Float DiffuseMap_0_scale : 16.0625”

I need to transfer just that float value in my setFloat() method, but unfortunately I am unable to, I sure hope this isn’t going to be a regex situation.

It most certainly does not return a String

http://hub.jmonkeyengine.org/javadoc/com/jme3/material/Material.html#getParam(java.lang.String)

@jmaasing

I’ve got it solved with

tat.setFloat(“Tex1Scale”, Float.valueOf(geom.getMaterial().getParam(“DiffuseMap_0_scale”).getValueAsString()));

Etc.

Thank you!