terrain gen: store noise values into a LUT

generation times went from 135uS to 35uS
treemaps-chunkstates-spacefilling
EmaMaker 2022-08-28 17:49:47 +02:00
parent a3e9786fcb
commit e3dd39f21a
1 changed files with 16 additions and 3 deletions

View File

@ -52,6 +52,13 @@ public class ChunkGenerator {
OpenSimplexNoise noiseGen1 = new OpenSimplexNoise(new Random().nextInt()); OpenSimplexNoise noiseGen1 = new OpenSimplexNoise(new Random().nextInt());
OpenSimplexNoise noiseGen2 = new OpenSimplexNoise(new Random().nextInt()); OpenSimplexNoise noiseGen2 = new OpenSimplexNoise(new Random().nextInt());
// Generates smooth terrain using 2 layers of noise. This method takes advantage of how the interval map works and doesn't need a preliminary step to store data in an array
// TODO (?): This can be optimizied for speed by only calculating noise levels at x-z coordinates once, and storing them in a 2d array
// No LUT: about 135 ms
// LUT: about 35 ms
int[] grassNoiseLUT = new int[Config.CHUNK_SIZE*Config.CHUNK_SIZE];
int[] dirtNoiseLUT = new int[Config.CHUNK_SIZE*Config.CHUNK_SIZE];
public void generateNoise(Chunk c) { public void generateNoise(Chunk c) {
short coords[]; short coords[];
int x, y, z; int x, y, z;
@ -60,14 +67,21 @@ public class ChunkGenerator {
Blocks prevBlock = null, block = Blocks.AIR; Blocks prevBlock = null, block = Blocks.AIR;
c.setState(Chunk.CHUNK_STATE_EMPTY, true); c.setState(Chunk.CHUNK_STATE_EMPTY, true);
for(int i = 0; i < Config.CHUNK_SIZE*Config.CHUNK_SIZE; i++){
grassNoiseLUT[i] = -1;
dirtNoiseLUT[i] = -1;
}
for(int i = 0; i < Config.CHUNK_3DCOORD_MAX_INDEX + 1; i++){ for(int i = 0; i < Config.CHUNK_3DCOORD_MAX_INDEX + 1; i++){
coords = SpaceFillingCurve.HILBERT_XYZ_DECODE[i]; coords = SpaceFillingCurve.HILBERT_XYZ_DECODE[i];
x = c.posx * Config.CHUNK_SIZE + coords[0]; x = c.posx * Config.CHUNK_SIZE + coords[0];
y = c.posy * Config.CHUNK_SIZE + coords[1]; y = c.posy * Config.CHUNK_SIZE + coords[1];
z = c.posz * Config.CHUNK_SIZE + coords[2]; z = c.posz * Config.CHUNK_SIZE + coords[2];
grassNoise = GRASS_OFFSET + (int) ((0.5d + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT)) * NOISE_GRASS_MULT); if(grassNoiseLUT[coords[0] + Config.CHUNK_SIZE*coords[2]] == -1) grassNoiseLUT[coords[0] +Config.CHUNK_SIZE*coords[2]] = GRASS_OFFSET + (int) ((0.5d + noiseGen1.eval(x * NOISE_GRASS_X_MULT, z * NOISE_GRASS_Z_MULT)) * NOISE_GRASS_MULT);
dirtNoise = NOISE_DIRT_MIN + (int) ((0.5f + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT)) * NOISE_DIRT_MULT); if(dirtNoiseLUT[coords[0] + Config.CHUNK_SIZE*coords[2]] == -1) dirtNoiseLUT[coords[0] +Config.CHUNK_SIZE*coords[2]] = NOISE_DIRT_MIN + (int) ((0.5f + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT)) * NOISE_DIRT_MULT);
grassNoise = grassNoiseLUT[coords[0] + Config.CHUNK_SIZE*coords[2]];
dirtNoise = dirtNoiseLUT[coords[0] + Config.CHUNK_SIZE*coords[2]];
stoneLevel = grassNoise - dirtNoise; stoneLevel = grassNoise - dirtNoise;
if (y < stoneLevel) block = Blocks.STONE; if (y < stoneLevel) block = Blocks.STONE;
@ -87,7 +101,6 @@ public class ChunkGenerator {
if(prevBlock!= Blocks.AIR) c.setState(Chunk.CHUNK_STATE_EMPTY, false); if(prevBlock!= Blocks.AIR) c.setState(Chunk.CHUNK_STATE_EMPTY, false);
c.setBlocks(prevBlock, start, Config.CHUNK_3DCOORD_MAX_INDEX + 1); c.setBlocks(prevBlock, start, Config.CHUNK_3DCOORD_MAX_INDEX + 1);
//c.blocks.print();
} }
/*public void generateNoise(Chunk c) { /*public void generateNoise(Chunk c) {