noise control from biome definition
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-04-02 16:19:14 -04:00
parent 44c6a667e9
commit 5109eb97a9
5 changed files with 68 additions and 36 deletions

View File

@ -25,6 +25,8 @@
"surfaceGenerationParams": { "surfaceGenerationParams": {
"surfaceGenTag": "plains", "surfaceGenTag": "plains",
"heightOffset": 10, "heightOffset": 10,
"noiseScale" : 0.1,
"warpScale" : 0.1,
"floorVariants": [ "floorVariants": [
{ {
"voxelId": 2, "voxelId": 2,
@ -60,6 +62,8 @@
"surfaceGenerationParams": { "surfaceGenerationParams": {
"surfaceGenTag": "hills", "surfaceGenTag": "hills",
"heightOffset": 10, "heightOffset": 10,
"noiseScale" : 0.1,
"warpScale" : 0.1,
"floorVariants": [ "floorVariants": [
{ {
"voxelId": 2, "voxelId": 2,
@ -97,7 +101,15 @@
"surfaceGenerationParams": { "surfaceGenerationParams": {
"surfaceGenTag": "hills", "surfaceGenTag": "hills",
"heightOffset": 10, "heightOffset": 10,
"noiseScale" : 0.1,
"warpScale" : 0.1,
"floorVariants": [ "floorVariants": [
{
"voxelId": 2,
"frequency": 1.0,
"dispersion": 1.0,
"priority": 1.0
}
], ],
"foliageDescriptions": [ "foliageDescriptions": [
{ {
@ -162,6 +174,8 @@
"surfaceGenerationParams": { "surfaceGenerationParams": {
"surfaceGenTag": "plains", "surfaceGenTag": "plains",
"heightOffset": 10, "heightOffset": 10,
"noiseScale" : 0.1,
"warpScale" : 0.1,
"floorVariants": [ "floorVariants": [
{ {
"voxelId": 7, "voxelId": 7,

View File

@ -1416,6 +1416,7 @@ biome floor elements controlling noise generator's voxel selection
Plains (rock) biome Plains (rock) biome
Lore message resend from client on failure Lore message resend from client on failure
More surface selection work More surface selection work
Noise control from biome definition

View File

@ -41,6 +41,16 @@ public class BiomeSurfaceGenerationParams {
@Exclude @Exclude
NoiseMapper<BiomeFloorElement> floorVariantMapper; NoiseMapper<BiomeFloorElement> floorVariantMapper;
/**
* The scale of the noise
*/
Float noiseScale;
/**
* The scale of the warp applies to the noise
*/
Float warpScale;
/** /**
* Precomputes the surface voxel distribution * Precomputes the surface voxel distribution
*/ */
@ -89,4 +99,22 @@ public class BiomeSurfaceGenerationParams {
return this.floorVariantMapper.lookup(gradientValue); 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;
}
} }

View File

@ -4,7 +4,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.game.terrain.processing.TerrainInterpolator;
import electrosphere.server.terrain.generation.interfaces.ChunkGenerator; import electrosphere.server.terrain.generation.interfaces.ChunkGenerator;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.models.TerrainModel; import electrosphere.server.terrain.models.TerrainModel;

View File

@ -145,10 +145,6 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
BiomeData[][] surfaceBiomeMap = new BiomeData[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE]; BiomeData[][] surfaceBiomeMap = new BiomeData[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
this.populateElevation(heightfield,surfaceBiomeMap,worldX,worldZ,strideValue); 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]; 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 x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ 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); double realX = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkX,finalWorldX);
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ 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 finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION; int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ); double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(finalChunkZ,finalWorldZ);
double surfaceHeight = heightfield[x][z]; double surfaceHeight = heightfield[x][z];
double gradient = gradientField[x][z]; double gradient = gradientField[x][z];
double surfaceSelection = surfaceSelectionField[x][z]; double surfaceSelection = this.calculateSurfaceNoise(surfaceParams, finalWorldX, finalWorldZ, finalChunkX, finalChunkZ, strideValue, this.terrainModel.getSeed());
BiomeData surfaceBiome = surfaceBiomeMap[x][z];
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){ for(int y = 0; y < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; y++){
int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); int finalWorldY = worldY + ((y * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION);
@ -291,37 +289,29 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
} }
/** /**
* Populates the surface selection noise field * Calculates the surface noise of the surface at the provided position
* @param surfaceNoiseField The surface selection noise field * @param worldX
* @param worldX The world x position * @param worldZ
* @param worldZ The world z position * @param chunkX
* @param strideValue The stride value * @param chunkZ
* @param strideValue
* @param seed
* @return
*/ */
private void surfaceSelectionNoise(double[][] surfaceNoiseField, int worldX, int worldZ, int strideValue, long seed){ private double calculateSurfaceNoise(BiomeSurfaceGenerationParams surfaceParams, int worldX, int worldZ, int chunkX, int chunkZ, int strideValue, long seed){
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){ double realX = serverWorldData.convertVoxelToRealSpace(chunkX, worldX);
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){ double realZ = serverWorldData.convertVoxelToRealSpace(chunkZ, worldZ);
int finalWorldX = worldX + ((x * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); float noiseScale = surfaceParams.getNoiseScale();
int finalWorldZ = worldZ + ((z * strideValue) / ServerTerrainChunk.CHUNK_DIMENSION); float warpScale = surfaceParams.getWarpScale();
int finalChunkX = (x * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
int finalChunkZ = (z * strideValue) % ServerTerrainChunk.CHUNK_DIMENSION;
if(finalWorldX > this.serverWorldData.getWorldSizeDiscrete() || finalWorldZ > this.serverWorldData.getWorldSizeDiscrete()){ double warpX = OpenSimplex2S.noise3_ImproveXY(seed, realX, realZ, 0);
throw new Error("Invalid world dim! " + finalWorldX + " " + finalWorldZ); 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;
double realX = serverWorldData.convertVoxelToRealSpace(finalChunkX, finalWorldX); if(fixed < 0){
double realZ = serverWorldData.convertVoxelToRealSpace(finalChunkZ, finalWorldZ); throw new Error("Failed to clamp value properly! " + valueRaw + " " + 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 + 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;
}
} }
return fixed;
} }
/** /**