I’m trying to generate a terrain, it works well, but when I’m above the terrain it becomes partly transparent, I have tried many things but nothing worked out, any ideas?
P.S Looks like I’ve found out what’s wrong with that, it generates upside down, but I have no idea why and how to fix that
import com.jme3.asset.AssetManager;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;
import com.sudoplay.joise.module.ModuleBasisFunction;
import com.sudoplay.joise.module.ModuleFractal;
public class TerrainGenerator {
private final AssetManager assetManager;
public TerrainGenerator(AssetManager assetManager) {
this.assetManager = assetManager;
}
public TerrainAndMaterial generateTerrain(int gridSize, float stepSize, float frequency, int numOctaves) {
// Create geometry for the terrain
Mesh terrainMesh = generateTerrainMesh(gridSize, stepSize, frequency, numOctaves);
Geometry terrainGeometry = new Geometry("Terrain", terrainMesh);
// Create material for the terrain
Material terrainMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
Texture diffuseTexture = assetManager.loadTexture("assets/textures/grass.jpg"); // Replace with your texture file
diffuseTexture.setWrap(Texture.WrapMode.Repeat);
terrainMaterial.setTexture("DiffuseMap", diffuseTexture);
terrainMaterial.setBoolean("UseMaterialColors", true);
terrainMaterial.setColor("Ambient", ColorRGBA.Gray);
terrainMaterial.setColor("Diffuse", ColorRGBA.White);
terrainGeometry.setMaterial(terrainMaterial);
// Add directional light
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
sun.setColor(ColorRGBA.White);
terrainGeometry.addLight(sun);
return new TerrainAndMaterial(terrainGeometry, terrainMaterial);
}
private Mesh generateTerrainMesh(int gridSize, float stepSize, float frequency, int numOctaves) {
// Create mesh and configure its vertices and triangle indices
Mesh terrainMesh = new Mesh();
Vector3f[] vertices = new Vector3f[(gridSize + 1) * (gridSize + 1)];
Vector2f[] texCoord = new Vector2f[(gridSize + 1) * (gridSize + 1)]; // Add array for texture coordinates
// Create noise module for height generation
ModuleFractal fractal = new ModuleFractal();
fractal.setAllSourceTypes(ModuleBasisFunction.BasisType.GRADIENT, ModuleBasisFunction.InterpolationType.LINEAR);
fractal.setNumOctaves(numOctaves);
fractal.setFrequency(frequency);
for (int i = 0; i <= gridSize; i++) {
for (int j = 0; j <= gridSize; j++) {
float x = -gridSize * stepSize * 0.5f + i * stepSize;
float z = -gridSize * stepSize * 0.5f + j * stepSize;
// Generate noise for current position (x, z)
float noiseValue = (float) fractal.get(x, 0, z);
// Create additional noise module for hill generation
ModuleFractal hillFractal = new ModuleFractal();
hillFractal.setAllSourceTypes(ModuleBasisFunction.BasisType.GRADIENT, ModuleBasisFunction.InterpolationType.LINEAR);
hillFractal.setNumOctaves(4);
hillFractal.setFrequency(0.1f);
// Generate hill height for current position (x, z)
float hillHeight = (float) hillFractal.get(x * 0.2, 0, z * 0.2) * 10;
float y = noiseValue * 15 + hillHeight;
vertices[i * (gridSize + 1) + j] = new Vector3f(x, y, z);
// Generate texture coordinates in range [0, 1]
float u = (float) i / gridSize;
float v = (float) j / gridSize;
texCoord[i * (gridSize + 1) + j] = new Vector2f(u, v);
}
}
// Create triangle indices
int[] indices = new int[gridSize * gridSize * 6];
int idx = 0;
for (int i = 0; i < gridSize; i++) {
for (int j = 0; j < gridSize; j++) {
int topLeft = i * (gridSize + 1) + j;
int bottomLeft = (i + 1) * (gridSize + 1) + j;
// Triangle 1 vertices
indices[idx++] = topLeft;
indices[idx++] = bottomLeft;
indices[idx++] = topLeft + 1;
// Triangle 2 vertices
indices[idx++] = topLeft + 1;
indices[idx++] = bottomLeft;
indices[idx++] = bottomLeft + 1;
}
}
// Set vertices, texture coordinates, and indices to the mesh
terrainMesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
terrainMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
terrainMesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(indices));
// Calculate normals for lighting
terrainMesh.updateBound();
terrainMesh.updateCounts();
return terrainMesh;
}
public class TerrainAndMaterial {
public final Geometry terrainGeometry;
public final Material terrainMaterial;
public TerrainAndMaterial(Geometry terrainGeometry, Material terrainMaterial) {
this.terrainGeometry = terrainGeometry;
this.terrainMaterial = terrainMaterial;
}
}
}