From e3dd39f21ab52094efd68191b1c6a8396b422095 Mon Sep 17 00:00:00 2001 From: EmaMaker Date: Sun, 28 Aug 2022 17:49:47 +0200 Subject: [PATCH] terrain gen: store noise values into a LUT generation times went from 135uS to 35uS --- .../world/chunk/ChunkGenerator.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/emamaker/voxeltest/intervaltrees/world/chunk/ChunkGenerator.java b/src/main/java/com/emamaker/voxeltest/intervaltrees/world/chunk/ChunkGenerator.java index bb49fef..2375b43 100644 --- a/src/main/java/com/emamaker/voxeltest/intervaltrees/world/chunk/ChunkGenerator.java +++ b/src/main/java/com/emamaker/voxeltest/intervaltrees/world/chunk/ChunkGenerator.java @@ -52,6 +52,13 @@ public class ChunkGenerator { OpenSimplexNoise noiseGen1 = 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) { short coords[]; int x, y, z; @@ -60,14 +67,21 @@ public class ChunkGenerator { Blocks prevBlock = null, block = Blocks.AIR; 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++){ coords = SpaceFillingCurve.HILBERT_XYZ_DECODE[i]; x = c.posx * Config.CHUNK_SIZE + coords[0]; y = c.posy * Config.CHUNK_SIZE + coords[1]; 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); - dirtNoise = NOISE_DIRT_MIN + (int) ((0.5f + noiseGen2.eval(x * NOISE_DIRT_X_MULT, z * NOISE_DIRT_Z_MULT)) * NOISE_DIRT_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); + 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; if (y < stoneLevel) block = Blocks.STONE; @@ -87,7 +101,6 @@ public class ChunkGenerator { if(prevBlock!= Blocks.AIR) c.setState(Chunk.CHUNK_STATE_EMPTY, false); c.setBlocks(prevBlock, start, Config.CHUNK_3DCOORD_MAX_INDEX + 1); - //c.blocks.print(); } /*public void generateNoise(Chunk c) {