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": {
"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,

View File

@ -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

View File

@ -41,6 +41,16 @@ public class BiomeSurfaceGenerationParams {
@Exclude
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
*/
@ -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;
}
}

View File

@ -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;

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];
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;
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);
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();
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 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);
}
surfaceNoiseField[x][z] = fixed;
}
}
return fixed;
}
/**