From 5109eb97a9cbf0b9c91ecc370a68d4e88d9d6946 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 2 Apr 2025 16:19:14 -0400 Subject: [PATCH] noise control from biome definition --- assets/Data/game/biomes.json | 14 +++++ docs/src/progress/renderertodo.md | 1 + .../biome/BiomeSurfaceGenerationParams.java | 28 +++++++++ .../generation/OverworldChunkGenerator.java | 1 - .../TestGenerationChunkGenerator.java | 60 ++++++++----------- 5 files changed, 68 insertions(+), 36 deletions(-) diff --git a/assets/Data/game/biomes.json b/assets/Data/game/biomes.json index 1a7470c9..ac39c8d0 100644 --- a/assets/Data/game/biomes.json +++ b/assets/Data/game/biomes.json @@ -25,6 +25,8 @@ "surfaceGenerationParams": { "surfaceGenTag": "plains", "heightOffset": 10, + "noiseScale" : 0.1, + "warpScale" : 0.1, "floorVariants": [ { "voxelId": 2, @@ -60,6 +62,8 @@ "surfaceGenerationParams": { "surfaceGenTag": "hills", "heightOffset": 10, + "noiseScale" : 0.1, + "warpScale" : 0.1, "floorVariants": [ { "voxelId": 2, @@ -97,7 +101,15 @@ "surfaceGenerationParams": { "surfaceGenTag": "hills", "heightOffset": 10, + "noiseScale" : 0.1, + "warpScale" : 0.1, "floorVariants": [ + { + "voxelId": 2, + "frequency": 1.0, + "dispersion": 1.0, + "priority": 1.0 + } ], "foliageDescriptions": [ { @@ -162,6 +174,8 @@ "surfaceGenerationParams": { "surfaceGenTag": "plains", "heightOffset": 10, + "noiseScale" : 0.1, + "warpScale" : 0.1, "floorVariants": [ { "voxelId": 7, diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 4e3b79ca..d9fa29f8 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1416,6 +1416,7 @@ biome floor elements controlling noise generator's voxel selection Plains (rock) biome Lore message resend from client on failure More surface selection work +Noise control from biome definition diff --git a/src/main/java/electrosphere/game/data/biome/BiomeSurfaceGenerationParams.java b/src/main/java/electrosphere/game/data/biome/BiomeSurfaceGenerationParams.java index faf8898c..626fe4dd 100644 --- a/src/main/java/electrosphere/game/data/biome/BiomeSurfaceGenerationParams.java +++ b/src/main/java/electrosphere/game/data/biome/BiomeSurfaceGenerationParams.java @@ -41,6 +41,16 @@ public class BiomeSurfaceGenerationParams { @Exclude NoiseMapper floorVariantMapper; + /** + * The scale of the noise + */ + Float noiseScale; + + /** + * The scale of the warp applies to the noise + */ + Float warpScale; + /** * Precomputes the surface voxel distribution */ @@ -89,4 +99,22 @@ public class BiomeSurfaceGenerationParams { return this.floorVariantMapper.lookup(gradientValue); } + /** + * Gets the scale of the noise + * @return The scale of the noise + */ + public Float getNoiseScale() { + return noiseScale; + } + + /** + * Gets the scale of the warp applies to the noise + * @return The scale of the warp applies to the noise + */ + public Float getWarpScale() { + return warpScale; + } + + + } diff --git a/src/main/java/electrosphere/server/terrain/generation/OverworldChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/OverworldChunkGenerator.java index c434d306..a6d8c4e4 100644 --- a/src/main/java/electrosphere/server/terrain/generation/OverworldChunkGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/OverworldChunkGenerator.java @@ -4,7 +4,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import electrosphere.client.terrain.cache.ChunkData; -import electrosphere.game.terrain.processing.TerrainInterpolator; import electrosphere.server.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.models.TerrainModel; diff --git a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java index fd05a38b..58f392e7 100644 --- a/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java +++ b/src/main/java/electrosphere/server/terrain/generation/TestGenerationChunkGenerator.java @@ -145,10 +145,6 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { BiomeData[][] surfaceBiomeMap = new BiomeData[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; this.populateElevation(heightfield,surfaceBiomeMap,worldX,worldZ,strideValue); - //presolve surface selection noise - double[][] surfaceSelectionField = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; - this.surfaceSelectionNoise(surfaceSelectionField,worldX,worldZ,strideValue,this.terrainModel.getSeed()); - double[][] gradientField = new double[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ @@ -182,14 +178,16 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { double realX = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkX,finalWorldX); for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ + BiomeData surfaceBiome = surfaceBiomeMap[x][z]; + BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); + + int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ); double surfaceHeight = heightfield[x][z]; double gradient = gradientField[x][z]; - double surfaceSelection = surfaceSelectionField[x][z]; - BiomeData surfaceBiome = surfaceBiomeMap[x][z]; - BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); + double surfaceSelection = this.calculateSurfaceNoise(surfaceParams, finalWorldX, finalWorldZ, finalChunkX, finalChunkZ, strideValue, this.terrainModel.getSeed()); for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){ int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); @@ -291,37 +289,29 @@ public class TestGenerationChunkGenerator implements ChunkGenerator { } /** - * Populates the surface selection noise field - * @param surfaceNoiseField The surface selection noise field - * @param worldX The world x position - * @param worldZ The world z position - * @param strideValue The stride value + * Calculates the surface noise of the surface at the provided position + * @param worldX + * @param worldZ + * @param chunkX + * @param chunkZ + * @param strideValue + * @param seed + * @return */ - private void surfaceSelectionNoise(double[][] surfaceNoiseField, int worldX, int worldZ, int strideValue, long seed){ - for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ - for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ - int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); - int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); - int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; - int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; + private double calculateSurfaceNoise(BiomeSurfaceGenerationParams surfaceParams, int worldX, int worldZ, int chunkX, int chunkZ, int strideValue, long seed){ + double realX = serverWorldData.convertVoxelToRealSpace(chunkX, worldX); + double realZ = serverWorldData.convertVoxelToRealSpace(chunkZ, worldZ); + float noiseScale = surfaceParams.getNoiseScale(); + float warpScale = surfaceParams.getWarpScale(); - if(finalWorldX > this.serverWorldData.getWorldSizeDiscrete() || finalWorldZ > this.serverWorldData.getWorldSizeDiscrete()){ - throw new Error("Invalid world dim! " + finalWorldX + " " + finalWorldZ); - } - - double realX = serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX); - double realZ = serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ); - - double warpX = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 0); - double warpZ = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 1); - double valueRaw = OpenSimplex2S.noise2(seed, realX + warpX, realZ + warpZ); - double fixed = (MathUtils.clamp(valueRaw, -1, 1) + 1) / 2.0; - if(fixed < 0){ - throw new Error("Failed to clamp value properly! " + valueRaw + " " + fixed); - } - surfaceNoiseField[x][z] = fixed; - } + double warpX = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 0); + double warpZ = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 1); + double valueRaw = OpenSimplex2S.noise2(seed, realX * noiseScale + warpX * warpScale, realZ * noiseScale + warpZ * warpScale); + double fixed = (MathUtils.clamp(valueRaw, -1, 1) + 1) / 2.0; + if(fixed < 0){ + throw new Error("Failed to clamp value properly! " + valueRaw + " " + fixed); } + return fixed; } /**