Added a terrain material that uses height and slope information to map textures instead of alphamap.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7530 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
ant..om 14 years ago
parent 58ede837c6
commit 4fa5522c8e
  1. 76
      engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.frag
  2. 41
      engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.j3md
  3. 22
      engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.vert
  4. BIN
      engine/src/test-data/Textures/Terrain/grid/rock.jpg
  5. 41
      engine/src/test/jme3test/terrain/TerrainGridTest.java

@ -0,0 +1,76 @@
uniform vec3 m_region1;
uniform vec3 m_region2;
uniform vec3 m_region3;
uniform vec3 m_region4;
uniform sampler2D m_region1ColorMap;
uniform sampler2D m_region2ColorMap;
uniform sampler2D m_region3ColorMap;
uniform sampler2D m_region4ColorMap;
uniform sampler2D m_slopeColorMap;
uniform float m_slopeTileFactor;
uniform float m_terrainSize;
varying vec3 normal;
varying vec4 position;
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, 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);
}
void main() {
vec4 color = GenerateTerrainColor();
gl_FragColor = color;
}

@ -0,0 +1,41 @@
MaterialDef Terrain {
// Parameters to material:
// regionXColorMap: X = 1..4 the texture that should be appliad to state X
// regionX: a Vector3f containing the following information:
// regionX.x: the start height of the region
// regionX.y: the end height of the region
// regionX.z: the texture scale for the region
// it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
// slopeColorMap: the texture to be used for cliffs, and steep mountain sites
// slopeTileFactor: the texture scale for slopes
// terrainSize: the total size of the terrain (used for scaling the texture)
MaterialParameters {
Texture2D region1ColorMap
Texture2D region2ColorMap
Texture2D region3ColorMap
Texture2D region4ColorMap
Texture2D slopeColorMap
Float slopeTileFactor
Float terrainSize
Vector3 region1
Vector3 region2
Vector3 region3
Vector3 region4
}
Technique {
VertexShader GLSL130: Common/MatDefs/Terrain/HeightBasedTerrain.vert
FragmentShader GLSL130: Common/MatDefs/Terrain/HeightBasedTerrain.frag
WorldParameters {
WorldViewProjectionMatrix
WorldMatrix
NormalMatrix
}
}
Technique FixedFunc {
}
}

@ -0,0 +1,22 @@
uniform float m_tilingFactor;
uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldMatrix;
uniform mat3 g_NormalMatrix;
uniform float m_terrainSize;
attribute vec4 inTexCoord;
attribute vec3 inNormal;
attribute vec3 inPosition;
varying vec3 normal;
varying vec4 position;
void main()
{
normal = normalize(inNormal);
position = g_WorldMatrix * vec4(inPosition, 0.0);
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

@ -60,29 +60,40 @@ public class TerrainGridTest extends SimpleApplication {
this.stateManager.attach(state);
// TERRAIN TEXTURE material
mat_terrain = new Material(assetManager, "Common/MatDefs/Terrain/Terrain.j3md");
mat_terrain.setBoolean("useTriPlanarMapping", false);
// ALPHA map (for splat textures)
mat_terrain.setTexture("Alpha", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
// Parameters to material:
// regionXColorMap: X = 1..4 the texture that should be appliad to state X
// regionX: a Vector3f containing the following information:
// regionX.x: the start height of the region
// regionX.y: the end height of the region
// regionX.z: the texture scale for the region
// it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)
// slopeColorMap: the texture to be used for cliffs, and steep mountain sites
// slopeTileFactor: the texture scale for slopes
// terrainSize: the total size of the terrain (used for scaling the texture)
// GRASS texture
Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
Texture grass = this.assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
grass.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex1", grass);
mat_terrain.setFloat("Tex1Scale", grassScale);
this.mat_terrain.setTexture("region1ColorMap", grass);
this.mat_terrain.setVector3("region1", new Vector3f(88, 200, this.grassScale));
// DIRT texture
Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
Texture dirt = this.assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
dirt.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex2", dirt);
mat_terrain.setFloat("Tex2Scale", dirtScale);
this.mat_terrain.setTexture("region2ColorMap", dirt);
this.mat_terrain.setVector3("region2", new Vector3f(0, 90, this.dirtScale));
// ROCK texture
Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
Texture rock = this.assetManager.loadTexture("Textures/Terrain/grid/rock.jpg");
rock.setWrap(WrapMode.Repeat);
mat_terrain.setTexture("Tex3", rock);
mat_terrain.setFloat("Tex3Scale", rockScale);
this.mat_terrain.setTexture("region3ColorMap", rock);
this.mat_terrain.setVector3("region3", new Vector3f(198, 260, this.rockScale));
this.mat_terrain.setTexture("slopeColorMap", rock);
this.mat_terrain.setFloat("slopeTileFactor", 32);
this.mat_terrain.setFloat("terrainSize", 513);
this.base = new FractalSum();
this.base.setRoughness(0.7f);

Loading…
Cancel
Save