Using HeightBasedTerrain Material with Custom Mesh problem

Hi,



I have a problem using the HeightBasedTerrain.j3md Material with my custom Mesh (Is it even possible?)

First, I am creating a Grid of vertices and connecting the dots. In the end I am setting the following material to the Geometry(Mesh):

[java]

mat = new Material(this.assetManager, “Common/MatDefs/Terrain/HeightBasedTerrain.j3md”);

Texture grass = this.assetManager.loadTexture(“Textures/grass.jpg”);

grass.setWrap(WrapMode.Repeat);

mat.setTexture(“region1ColorMap”, grass);

mat.setVector3(“region1”, new Vector3f(0, 5, 32f));



[/java]



But my Mesh is only normal green, no Texture like it should be as in the grass.jpg file.

Furthermore, when I try to add normals and run “TangentBinormalGenerator.generate(mesh);” the Mesh is only black as if there isn’t any texture or material applied.

And what is the relation between the Texture Coordinates of the Mesh and the different textures defined within the material (grass, dirt, rock…)?



Thank you!

I’m not sure on the exact implementation of that shader, but you will probably need texture coordinates on your mesh. If you are getting a flat green then that is a sure sign of bad texture coordinates (a single texture pixel being stretched across the mesh).

That shader does not use lighting, so there is no need to run TangentBinormalGenerator. However you still need normals.

I thought the same as you:

@Sploreg said:
that is a sure sign of bad texture coordinates (a single texture pixel being stretched across the mesh).


I have the normal texture coordinates for the mesh:
+ + +
+ + +
+ + +
Bottom left: 0,0
Top left: 0,1
Top right: 1,1
and the appropriate vectors for the vertices inbetween.
With normal texturing it is working correctly.

So, how to set the texture coordinates, when I am using this material with many textures?

Have you specified the terrainSize for the material parameter? TerrainGridTest.java has a bunch of comments about that material in it that might help narrow down the cause.



I took a quick look at the material and it appears to not be using texture coordinates, just straight elevation and slope values of the terrain, and then applying the scales.

I have specified the terrainSize.

For example with the value 100 if the size of my Terrain is 100x100.



Can you explain me the “scales” and “scaling” with a good example?

I didn’t write that shader and don’t know it too well.

But the scales describe how stretched each texture is, and how many times it should repeat over the the mesh, given by the terrainSize parameter.



This is the shader code (which you can check out in HeightBasedTerrain.frag):

[java]

vec4 GenerateTerrainColor() {

float height = position.y;

vec4 p = position / m_terrainSize;



vec3 blend = abs( normal );

blend = (blend -0.2) * 0.7;

blend = normalize(max(blend, 0.00001)); // Force weights to sum to 1.0 (very important!)

float b = (blend.x + blend.y + blend.z);

blend /= vec3(b, b, b);



vec4 terrainColor = vec4(0.0, 0.0, 0.0, 1.0);



float m_regionMin = 0.0;

float m_regionMax = 0.0;

float m_regionRange = 0.0;

float m_regionWeight = 0.0;



vec4 slopeCol1 = texture2D(m_slopeColorMap, p.yz * m_slopeTileFactor);

vec4 slopeCol2 = texture2D(m_slopeColorMap, p.xy * m_slopeTileFactor);



// Terrain m_region 1.

m_regionMin = m_region1.x;

m_regionMax = m_region1.y;

m_regionRange = m_regionMax - m_regionMin;

m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;

m_regionWeight = max(0.0, m_regionWeight);

terrainColor += m_regionWeight * texture2D(m_region1ColorMap, p.xz * m_region1.z);



// Terrain m_region 2.

m_regionMin = m_region2.x;

m_regionMax = m_region2.y;

m_regionRange = m_regionMax - m_regionMin;

m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;

m_regionWeight = max(0.0, m_regionWeight);

terrainColor += m_regionWeight * (texture2D(m_region2ColorMap, p.xz * m_region2.z));



// Terrain m_region 3.

m_regionMin = m_region3.x;

m_regionMax = m_region3.y;

m_regionRange = m_regionMax - m_regionMin;

m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;

m_regionWeight = max(0.0, m_regionWeight);

terrainColor += m_regionWeight * texture2D(m_region3ColorMap, p.xz * m_region3.z);



// Terrain m_region 4.

m_regionMin = m_region4.x;

m_regionMax = m_region4.y;

m_regionRange = m_regionMax - m_regionMin;

m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;

m_regionWeight = max(0.0, m_regionWeight);

terrainColor += m_regionWeight * texture2D(m_region4ColorMap, p.xz * m_region4.z);



return (blend.y * terrainColor + blend.x * slopeCol1 + blend.z * slopeCol2);

}[/java]

Okay, it is working now! :slight_smile:



I wasn’t using or defining all regionColorMaps (1,2,3,4). I have activated all of them and now it runs perfectly!



Thanks for your help!

1 Like

ah yea that material should really check if they are set

1 Like