OSDN Git Service

Added a terrain material that uses height and slope information to map textures inste...
authoranthyon@gmail.com <anthyon@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sun, 29 May 2011 09:30:47 +0000 (09:30 +0000)
committeranthyon@gmail.com <anthyon@gmail.com@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sun, 29 May 2011 09:30:47 +0000 (09:30 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@7530 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.frag [new file with mode: 0644]
engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.j3md [new file with mode: 0644]
engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.vert [new file with mode: 0644]
engine/src/test-data/Textures/Terrain/grid/rock.jpg [new file with mode: 0644]
engine/src/test/jme3test/terrain/TerrainGridTest.java

diff --git a/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.frag b/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.frag
new file mode 100644 (file)
index 0000000..91dacd2
--- /dev/null
@@ -0,0 +1,76 @@
+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
diff --git a/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.j3md b/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.j3md
new file mode 100644 (file)
index 0000000..856a09e
--- /dev/null
@@ -0,0 +1,41 @@
+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
diff --git a/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.vert b/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.vert
new file mode 100644 (file)
index 0000000..8260d8f
--- /dev/null
@@ -0,0 +1,22 @@
+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
diff --git a/engine/src/test-data/Textures/Terrain/grid/rock.jpg b/engine/src/test-data/Textures/Terrain/grid/rock.jpg
new file mode 100644 (file)
index 0000000..343dc1c
Binary files /dev/null and b/engine/src/test-data/Textures/Terrain/grid/rock.jpg differ
index edfca2f..352e14e 100644 (file)
@@ -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);