--- /dev/null
+uniform vec3 m_region1;\r
+uniform vec3 m_region2;\r
+uniform vec3 m_region3;\r
+uniform vec3 m_region4;\r
+\r
+uniform sampler2D m_region1ColorMap;\r
+uniform sampler2D m_region2ColorMap;\r
+uniform sampler2D m_region3ColorMap;\r
+uniform sampler2D m_region4ColorMap;\r
+uniform sampler2D m_slopeColorMap;\r
+\r
+uniform float m_slopeTileFactor;\r
+uniform float m_terrainSize;\r
+\r
+varying vec3 normal;\r
+varying vec4 position;\r
+\r
+vec4 GenerateTerrainColor() {\r
+ float height = position.y;\r
+ vec4 p = position / m_terrainSize;\r
+ \r
+ vec3 blend = abs( normal );\r
+ blend = (blend -0.2) * 0.7;\r
+ blend = normalize(max(blend, 0.00001)); // Force weights to sum to 1.0 (very important!)\r
+ float b = (blend.x + blend.y + blend.z);\r
+ blend /= vec3(b, b, b);\r
+\r
+ vec4 terrainColor = vec4(0, 0, 0, 1.0);\r
+\r
+ float m_regionMin = 0.0;\r
+ float m_regionMax = 0.0;\r
+ float m_regionRange = 0.0;\r
+ float m_regionWeight = 0.0;\r
+ \r
+ vec4 slopeCol1 = texture2D(m_slopeColorMap, p.yz * m_slopeTileFactor);\r
+ vec4 slopeCol2 = texture2D(m_slopeColorMap, p.xy * m_slopeTileFactor);\r
+\r
+ // Terrain m_region 1.\r
+ m_regionMin = m_region1.x;\r
+ m_regionMax = m_region1.y;\r
+ m_regionRange = m_regionMax - m_regionMin;\r
+ m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;\r
+ m_regionWeight = max(0.0, m_regionWeight);\r
+ terrainColor += m_regionWeight * texture2D(m_region1ColorMap, p.xz * m_region1.z);\r
+\r
+ // Terrain m_region 2.\r
+ m_regionMin = m_region2.x;\r
+ m_regionMax = m_region2.y;\r
+ m_regionRange = m_regionMax - m_regionMin;\r
+ m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;\r
+ m_regionWeight = max(0.0, m_regionWeight);\r
+ terrainColor += m_regionWeight * (texture2D(m_region2ColorMap, p.xz * m_region2.z));\r
+\r
+ // Terrain m_region 3.\r
+ m_regionMin = m_region3.x;\r
+ m_regionMax = m_region3.y;\r
+ m_regionRange = m_regionMax - m_regionMin;\r
+ m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;\r
+ m_regionWeight = max(0.0, m_regionWeight);\r
+ terrainColor += m_regionWeight * texture2D(m_region3ColorMap, p.xz * m_region3.z);\r
+\r
+ // Terrain m_region 4.\r
+ m_regionMin = m_region4.x;\r
+ m_regionMax = m_region4.y;\r
+ m_regionRange = m_regionMax - m_regionMin;\r
+ m_regionWeight = (m_regionRange - abs(height - m_regionMax)) / m_regionRange;\r
+ m_regionWeight = max(0.0, m_regionWeight);\r
+ terrainColor += m_regionWeight * texture2D(m_region4ColorMap, p.xz * m_region4.z);\r
+\r
+ return (blend.y * terrainColor + blend.x * slopeCol1 + blend.z * slopeCol2);\r
+}\r
+\r
+void main() { \r
+ vec4 color = GenerateTerrainColor();\r
+ gl_FragColor = color;\r
+}\r
--- /dev/null
+MaterialDef Terrain {\r
+\r
+ // Parameters to material:\r
+ // regionXColorMap: X = 1..4 the texture that should be appliad to state X\r
+ // regionX: a Vector3f containing the following information:\r
+ // regionX.x: the start height of the region\r
+ // regionX.y: the end height of the region\r
+ // regionX.z: the texture scale for the region\r
+ // it might not be the most elegant way for storing these 3 values, but it packs the data nicely :)\r
+ // slopeColorMap: the texture to be used for cliffs, and steep mountain sites\r
+ // slopeTileFactor: the texture scale for slopes\r
+ // terrainSize: the total size of the terrain (used for scaling the texture)\r
+ MaterialParameters {\r
+ Texture2D region1ColorMap\r
+ Texture2D region2ColorMap\r
+ Texture2D region3ColorMap\r
+ Texture2D region4ColorMap\r
+ Texture2D slopeColorMap\r
+ Float slopeTileFactor\r
+ Float terrainSize\r
+ Vector3 region1\r
+ Vector3 region2\r
+ Vector3 region3\r
+ Vector3 region4\r
+ }\r
+\r
+ Technique {\r
+ VertexShader GLSL130: Common/MatDefs/Terrain/HeightBasedTerrain.vert\r
+ FragmentShader GLSL130: Common/MatDefs/Terrain/HeightBasedTerrain.frag\r
+\r
+ WorldParameters {\r
+ WorldViewProjectionMatrix\r
+ WorldMatrix\r
+ NormalMatrix\r
+ }\r
+ }\r
+\r
+ Technique FixedFunc {\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+uniform float m_tilingFactor;\r
+uniform mat4 g_WorldViewProjectionMatrix;\r
+uniform mat4 g_WorldMatrix;\r
+uniform mat3 g_NormalMatrix;\r
+\r
+uniform float m_terrainSize;\r
+\r
+attribute vec4 inTexCoord;\r
+attribute vec3 inNormal;\r
+attribute vec3 inPosition;\r
+\r
+varying vec3 normal;\r
+varying vec4 position;\r
+\r
+void main()\r
+{\r
+ normal = normalize(inNormal);\r
+ position = g_WorldMatrix * vec4(inPosition, 0.0);\r
+ gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1);\r
+}\r
+\r
+\r
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);