Skip to content

Commit 8d009ae

Browse files
worley noise improvement
Signed-off-by: Real Ant Engineer <[email protected]>
1 parent 9dd5745 commit 8d009ae

File tree

4 files changed

+82
-51
lines changed

4 files changed

+82
-51
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod_id=creatingspace
2121
mod_name=Creating Space
2222
mod_license=MIT
2323

24-
mod_version=1.20.1_1.8.0
24+
mod_version=1.20.1_1.8.0.1
2525

2626
create_version = 6.0.2-50
2727
flywheel_version = 1.0.1

src/main/java/com/rae/creatingspace/content/worldgen/WorleyNoise.java

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
public class WorleyNoise {
88
//TODO Optimise it further
99
//TODO make a 2d version of it -> makes no sens to use 3d version for a 2D map
10-
private static final float K = 0.142857142857f;
11-
private static final float Ko = 0.428571428571f;
12-
private static final float K2 = 0.020408163265306f;
13-
private static final float Kz = 0.166666666667f;
14-
private static final float Kzo = 0.416666666667f;
10+
private static final float K = 1.0f / 8.0f; // 0.125f — scale permuted into 8 buckets
11+
private static final float Ko = 0.375f; // center of [-0.375, 0.375] ( = 3 * K)
12+
private static final float K2 = 1.0f / 32.0f; // 0.03125f — second-level bucket (for Z)
13+
private static final float Kz = 1.0f / 6.0f; // 0.166666...
14+
private static final float Kzo = 0.5f - Kz; // = 0.333333... — to center Z
1515
private static final float jitter = 0.8f;
1616
private final float YMin;
1717
private final float YMax;
@@ -28,7 +28,29 @@ public float getYSize() {
2828
private final float XZSize;
2929
private final float YSize;
3030
private float x0,y0,z0;
31-
private final int[] p = new int[289];//TODO go to 256 rather than 289, now that we use the seed it doesn't make sens anymore
31+
private static final int permutations_bits = 8;
32+
private static final int permutations_amount = 1 << permutations_bits; // = 256
33+
34+
private final int[] xp = new int[permutations_amount];
35+
36+
// Offsets for the 27 neighbor cells in a 3×3×3 cube
37+
private static final int[][] OFFSETS_3D = new int[27][3];
38+
39+
static {
40+
int index = 0;
41+
for (int xi = -1; xi <= 1; xi++) {
42+
for (int yi = -1; yi <= 1; yi++) {
43+
for (int zi = -1; zi <= 1; zi++) {
44+
OFFSETS_3D[index][0] = xi;
45+
OFFSETS_3D[index][1] = yi;
46+
OFFSETS_3D[index][2] = zi;
47+
index++;
48+
}
49+
}
50+
}
51+
}
52+
53+
//TODO go to 256 rather than 289, now that we use the seed it doesn't make sens anymore
3254
//TODO have 3 permutations for x, y, z for improved performance ? need to do profiling and see if it changes anything.
3355
public WorleyNoise(float XZSize, float YSize, float YMin, float YMax) {
3456
this.XZSize = XZSize;
@@ -39,64 +61,73 @@ public WorleyNoise(float XZSize, float YSize, float YMin, float YMax) {
3961
}
4062
public void setSeed(long seed){
4163
RandomSource random = new XoroshiroRandomSource(seed);
42-
this.x0 = random.nextFloat() * 289.0f;//TODO is this needed ?
43-
this.y0 = random.nextFloat() * 289.0f;
44-
this.z0 = random.nextFloat() * 289.0f;
45-
46-
for(int i = 0; i < 289; this.p[i] = i++){
64+
this.x0 = random.nextFloat() * permutations_amount;//TODO is this needed ?
65+
this.y0 = random.nextFloat() * permutations_amount;
66+
this.z0 = random.nextFloat() * permutations_amount;
4767

68+
for (int i = 0; i < permutations_amount; i++) {
69+
this.xp[i] = i;
4870
}
4971

50-
for(int l = 0; l < 289; ++l) {
51-
int j = random.nextInt(289 - l);
52-
int k = this.p[l];
53-
this.p[l] = this.p[j + l];
54-
this.p[j + l] = k;
72+
for(int l = 0; l < permutations_amount; ++l) {
73+
int j = random.nextInt(permutations_amount - l);
74+
int k = this.xp[l];
75+
this.xp[l] = this.xp[j + l];
76+
this.xp[j + l] = k;
5577
}
5678

5779
}
58-
59-
private int permute(int x) {
60-
return p[x%289];
80+
private int permute(int x){
81+
return xp[x&(permutations_amount - 1)];
6182
}
62-
6383
public static float frac(float x) {
6484
return x - Mth.floor(x);
6585
}
6686

6787
public float cellular3x3x3(float px, float py, float pz) {
88+
//here a cell is 1 large (because in getValue we
6889
int Pix = Mth.floor(px+x0), Piy = Mth.floor(py+y0), Piz = Mth.floor(pz+z0); // Integer part
6990
float Pfx = frac(px+x0),Pfy = frac(py+y0),Pfz = frac(pz+z0); // Fractional part
7091
float minDist = Float.MAX_VALUE;
71-
72-
for (int xi = -1; xi <= 1; xi++) {
73-
for (int yi = -1; yi <= 1; yi++) {
74-
for (int zi = -1; zi <= 1; zi++) {
75-
// Compute cell coordinates
76-
//Vec3 cell = Pi.add(new Vec3(xi, yi, zi));
77-
float permuted = permute(permute(permute(Pix + xi)+Piy+yi)+Piz+zi);
78-
// Pseudo-random offset inside cell
79-
//TODO remove this/change this to a more relevant version (remnants of an old version of this code)
80-
float jitterX = ((permuted*K-Mth.floor(permuted*K))-Ko) * jitter;
81-
float jitterY = ((Mth.floor(permuted*K)%7.0f) * K-Ko) * jitter;
82-
float jitterZ = ((Mth.floor(permuted*K2)) * Kz-Kzo) * jitter;
83-
84-
85-
// Compute squared distance
86-
float dist = Mth.sqrt((jitterX+xi-Pfx)*(jitterX+xi-Pfx)+(jitterY+yi-Pfy)*(jitterY+yi-Pfy)+(jitterZ+zi-Pfz)*(jitterZ+zi-Pfz));
87-
if (Piy+jitterY+yi < YMax + y0 && Piy+jitterY+yi > YMin +y0) {
88-
// Track minimum distance
89-
minDist = Math.min(minDist, dist);
90-
}
91-
}
92-
}
92+
//if we do it with a nested loop we have a big overhead
93+
float yMaxOffset = YMax + y0;
94+
float yMinOffset = YMin + y0;
95+
for (int[] offset : OFFSETS_3D) {
96+
int xi = offset[0];
97+
int yi = offset[1];
98+
int zi = offset[2];
99+
100+
int cellX = Pix + xi;
101+
int cellY = Piy + yi;
102+
int cellZ = Piz + zi;
103+
104+
float dx = xi - Pfx;
105+
float dy = yi - Pfy;
106+
float dz = zi - Pfz;
107+
108+
float permuted = permute(permute(permute(cellX) + cellY) + cellZ);
109+
110+
float fk = permuted * K;
111+
float jitterX = (fk - Mth.floor(fk) - Ko) * jitter;
112+
float jitterY = ((Mth.floor(fk) % 8) * K - Ko) * jitter;
113+
float jitterZ = ((Mth.floor(permuted * K2)) * Kz - Kzo) * jitter;
114+
115+
float ytest = cellY + jitterY+ yi;
116+
117+
if (ytest < yMinOffset || ytest > yMaxOffset) continue;
118+
119+
float distX = dx + jitterX;
120+
float distY = dy + jitterY;
121+
float distZ = dz + jitterZ;
122+
float dist = distX * distX + distY * distY + distZ * distZ;
123+
minDist = Math.min(minDist, dist);
93124
}
94125
return Mth.sqrt(minDist); // Return the actual distance
95126
}
96127
//use int, that's lighter
97128
public double getValue(int x, int y, int z) {
98-
float F = cellular3x3x3((x) / XZSize,(y) / YSize,(z) / XZSize);
99-
return 1- (F * 2); // Mapping to range [-1, 1]
129+
float F = cellular3x3x3((x) / XZSize,(y) / YSize,(z) / XZSize);//give a result bwn 0 and 1
130+
return 1 - (F * 2); // Mapping to range [-1, 1]
100131
}
101132

102133
public float getYMin() {

src/main/resources/META-INF/mods.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ license="MIT"
66

77
[[mods]]
88
modId="creatingspace"
9-
version = "1.20.1_1.8.0"
9+
version = "1.20.1_1.8.0.1"
1010
displayName="Creating Space"
1111
logoFile = "new_logo.png"
1212
credits='''

src/main/resources/data/creatingspace/worldgen/density_function/asteroids/density.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"argument2": 0.4
2323
},
24-
"argument2": 0.2
24+
"argument2": 0.1
2525
}
2626
},
2727
"argument2": {
@@ -31,9 +31,9 @@
3131
"argument1": {
3232
"type": "max",
3333
"argument1":"creatingspace:asteroids/base_noise",
34-
"argument2": 0.1
34+
"argument2": 0.4
3535
},
36-
"argument2": -0.1
36+
"argument2": -0.4
3737
},
3838
"argument2": {
3939
"type": "minecraft:mul",
@@ -57,8 +57,8 @@
5757
"xz_scale": 1,
5858
"y_scale": 1
5959
},
60-
"argument2": 0.2
60+
"argument2": 0.4
6161
}
6262
},
63-
"argument2": -0.1
63+
"argument2": -0.3
6464
}

0 commit comments

Comments
 (0)