Skip to content

Commit

Permalink
Optimize noise generation
Browse files Browse the repository at this point in the history
  • Loading branch information
s-yh-china committed Jul 18, 2023
1 parent 31b9df3 commit 1df9d40
Show file tree
Hide file tree
Showing 2 changed files with 288 additions and 2 deletions.
9 changes: 7 additions & 2 deletions patches/server/0004-Leaves-Server-Config-And-Command.patch
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ index 35d2da9d91dcdd89de7c0f4af028fd182376ea8d..d73482fb1e71fe2951e96ae0593de268
.withRequiredArg()
diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..af0e5cdf562f437abef4a417cb93643d3c12cd4f
index 0000000000000000000000000000000000000000..d1a6bd01cb03424e0bdac98127dada77b3d11ea2
--- /dev/null
+++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
@@ -0,0 +1,876 @@
@@ -0,0 +1,881 @@
+package top.leavesmc.leaves;
+
+import com.destroystokyo.paper.util.SneakyThrow;
Expand Down Expand Up @@ -833,6 +833,11 @@ index 0000000000000000000000000000000000000000..af0e5cdf562f437abef4a417cb93643d
+ cacheBlockStatePairKeyHash = getBoolean("settings.performance.cache-BlockStatePairKey-hash", cacheBlockStatePairKeyHash);
+ }
+
+ public static boolean optimizeNoiseGeneration = false;
+ private static void optimizeNoiseGeneration() {
+ optimizeNoiseGeneration = getBoolean("settings.performance.optimize-noise-generation", optimizeNoiseGeneration);
+ }
+
+ public static final class WorldConfig {
+
+ public final String worldName;
Expand Down
281 changes: 281 additions & 0 deletions patches/server/0097-Optimize-noise-generation.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: violetc <[email protected]>
Date: Tue, 18 Jul 2023 15:27:19 +0800
Subject: [PATCH] Optimize noise generation

This patch is Powered by Gale(https://github.com/GaleMC/Gale)

diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
index fb84d703b4461343d50510d7c9be32fc1f09ed22..0e025df446d0243275c13bca7efd7a0bae1dc35b 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java
@@ -11,6 +11,27 @@ public final class ImprovedNoise {
public final double yo;
public final double zo;

+ // Leaves start - optimize noise generation
+ private static final double[] FLAT_SIMPLEX_GRAD = new double[]{
+ 1, 1, 0, 0,
+ -1, 1, 0, 0,
+ 1, -1, 0, 0,
+ -1, -1, 0, 0,
+ 1, 0, 1, 0,
+ -1, 0, 1, 0,
+ 1, 0, -1, 0,
+ -1, 0, -1, 0,
+ 0, 1, 1, 0,
+ 0, -1, 1, 0,
+ 0, 1, -1, 0,
+ 0, -1, -1, 0,
+ 1, 1, 0, 0,
+ 0, -1, 1, 0,
+ -1, 1, 0, 0,
+ 0, -1, -1, 0,
+ };
+ // Leaves end - optimize noise generation
+
public ImprovedNoise(RandomSource random) {
this.xo = random.nextDouble() * 256.0D;
this.yo = random.nextDouble() * 256.0D;
@@ -43,9 +64,20 @@ public final class ImprovedNoise {
int i = Mth.floor(d);
int j = Mth.floor(e);
int k = Mth.floor(f);
- double g = d - (double)i;
- double h = e - (double)j;
- double l = f - (double)k;
+ // Leaves start - optimize noise generation
+ double g;
+ double h;
+ double l;
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ g = d - (double)i;
+ h = e - (double)j;
+ l = f - (double)k;
+ } else {
+ g = d - i;
+ h = e - j;
+ l = f - k;
+ }
+ // Leaves end - optimize noise generation
double o;
if (yScale != 0.0D) {
double m;
@@ -55,12 +87,24 @@ public final class ImprovedNoise {
m = h;
}

- o = (double)Mth.floor(m / yScale + (double)1.0E-7F) * yScale;
+ // Leaves start - optimize noise generation
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ o = (double)Mth.floor(m / yScale + (double)1.0E-7F) * yScale;
+ } else {
+ o = Math.floor(m / yScale + (double)1.0E-7F) * yScale;
+ }
+ // Leaves end - optimize noise generation
} else {
o = 0.0D;
}

- return this.sampleAndLerp(i, j, k, g, h - o, l, h);
+ // Leaves start - optimize noise generation
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ return this.sampleAndLerp(i, j, k, g, h - o, l, h);
+ } else {
+ return this.sampleAndLerp((int) i, (int) j, (int) k, g, h - o, l, h);
+ }
+ // Leaves end - optimize noise generation
}

public double noiseWithDerivative(double x, double y, double z, double[] ds) {
@@ -70,10 +114,19 @@ public final class ImprovedNoise {
int i = Mth.floor(d);
int j = Mth.floor(e);
int k = Mth.floor(f);
- double g = d - (double)i;
- double h = e - (double)j;
- double l = f - (double)k;
- return this.sampleWithDerivative(i, j, k, g, h, l, ds);
+ // Leaves start - optimize noise generation
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ double g = d - (double)i;
+ double h = e - (double)j;
+ double l = f - (double)k;
+ return this.sampleWithDerivative(i, j, k, g, h, l, ds);
+ } else {
+ double g = d - i;
+ double h = e - j;
+ double l = f - k;
+ return this.sampleWithDerivative((int) i, (int) j, (int) k, g, h, l, ds);
+ }
+ // Leaves end - optimize noise generation
}

private static double gradDot(int hash, double x, double y, double z) {
@@ -85,24 +138,90 @@ public final class ImprovedNoise {
}

private double sampleAndLerp(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double fadeLocalY) {
- int i = this.p(sectionX);
- int j = this.p(sectionX + 1);
- int k = this.p(i + sectionY);
- int l = this.p(i + sectionY + 1);
- int m = this.p(j + sectionY);
- int n = this.p(j + sectionY + 1);
- double d = gradDot(this.p(k + sectionZ), localX, localY, localZ);
- double e = gradDot(this.p(m + sectionZ), localX - 1.0D, localY, localZ);
- double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0D, localZ);
- double g = gradDot(this.p(n + sectionZ), localX - 1.0D, localY - 1.0D, localZ);
- double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0D);
- double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0D, localY, localZ - 1.0D);
- double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0D, localZ - 1.0D);
- double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0D, localY - 1.0D, localZ - 1.0D);
- double r = Mth.smoothstep(localX);
- double s = Mth.smoothstep(fadeLocalY);
- double t = Mth.smoothstep(localZ);
- return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q);
+ // Leaves start - optimize noise generation
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ int i = this.p(sectionX);
+ int j = this.p(sectionX + 1);
+ int k = this.p(i + sectionY);
+ int l = this.p(i + sectionY + 1);
+ int m = this.p(j + sectionY);
+ int n = this.p(j + sectionY + 1);
+ double d = gradDot(this.p(k + sectionZ), localX, localY, localZ);
+ double e = gradDot(this.p(m + sectionZ), localX - 1.0D, localY, localZ);
+ double f = gradDot(this.p(l + sectionZ), localX, localY - 1.0D, localZ);
+ double g = gradDot(this.p(n + sectionZ), localX - 1.0D, localY - 1.0D, localZ);
+ double h = gradDot(this.p(k + sectionZ + 1), localX, localY, localZ - 1.0D);
+ double o = gradDot(this.p(m + sectionZ + 1), localX - 1.0D, localY, localZ - 1.0D);
+ double p = gradDot(this.p(l + sectionZ + 1), localX, localY - 1.0D, localZ - 1.0D);
+ double q = gradDot(this.p(n + sectionZ + 1), localX - 1.0D, localY - 1.0D, localZ - 1.0D);
+ double r = Mth.smoothstep(localX);
+ double s = Mth.smoothstep(fadeLocalY);
+ double t = Mth.smoothstep(localZ);
+ return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q);
+ } else {
+ final int var0 = sectionX & 0xFF;
+ final int var1 = (sectionX + 1) & 0xFF;
+ final int var2 = this.p[var0] & 0xFF;
+ final int var3 = this.p[var1] & 0xFF;
+ final int var4 = (var2 + sectionY) & 0xFF;
+ final int var5 = (var3 + sectionY) & 0xFF;
+ final int var6 = (var2 + sectionY + 1) & 0xFF;
+ final int var7 = (var3 + sectionY + 1) & 0xFF;
+ final int var8 = this.p[var4] & 0xFF;
+ final int var9 = this.p[var5] & 0xFF;
+ final int var10 = this.p[var6] & 0xFF;
+ final int var11 = this.p[var7] & 0xFF;
+
+ final int var12 = (var8 + sectionZ) & 0xFF;
+ final int var13 = (var9 + sectionZ) & 0xFF;
+ final int var14 = (var10 + sectionZ) & 0xFF;
+ final int var15 = (var11 + sectionZ) & 0xFF;
+ final int var16 = (var8 + sectionZ + 1) & 0xFF;
+ final int var17 = (var9 + sectionZ + 1) & 0xFF;
+ final int var18 = (var10 + sectionZ + 1) & 0xFF;
+ final int var19 = (var11 + sectionZ + 1) & 0xFF;
+ final int var20 = (this.p[var12] & 15) << 2;
+ final int var21 = (this.p[var13] & 15) << 2;
+ final int var22 = (this.p[var14] & 15) << 2;
+ final int var23 = (this.p[var15] & 15) << 2;
+ final int var24 = (this.p[var16] & 15) << 2;
+ final int var25 = (this.p[var17] & 15) << 2;
+ final int var26 = (this.p[var18] & 15) << 2;
+ final int var27 = (this.p[var19] & 15) << 2;
+ final double var60 = localX - 1.0;
+ final double var61 = localY - 1.0;
+ final double var62 = localZ - 1.0;
+ final double var87 = FLAT_SIMPLEX_GRAD[(var20) | 0] * localX + FLAT_SIMPLEX_GRAD[(var20) | 1] * localY + FLAT_SIMPLEX_GRAD[(var20) | 2] * localZ;
+ final double var88 = FLAT_SIMPLEX_GRAD[(var21) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var21) | 1] * localY + FLAT_SIMPLEX_GRAD[(var21) | 2] * localZ;
+ final double var89 = FLAT_SIMPLEX_GRAD[(var22) | 0] * localX + FLAT_SIMPLEX_GRAD[(var22) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var22) | 2] * localZ;
+ final double var90 = FLAT_SIMPLEX_GRAD[(var23) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var23) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var23) | 2] * localZ;
+ final double var91 = FLAT_SIMPLEX_GRAD[(var24) | 0] * localX + FLAT_SIMPLEX_GRAD[(var24) | 1] * localY + FLAT_SIMPLEX_GRAD[(var24) | 2] * var62;
+ final double var92 = FLAT_SIMPLEX_GRAD[(var25) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var25) | 1] * localY + FLAT_SIMPLEX_GRAD[(var25) | 2] * var62;
+ final double var93 = FLAT_SIMPLEX_GRAD[(var26) | 0] * localX + FLAT_SIMPLEX_GRAD[(var26) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var26) | 2] * var62;
+ final double var94 = FLAT_SIMPLEX_GRAD[(var27) | 0] * var60 + FLAT_SIMPLEX_GRAD[(var27) | 1] * var61 + FLAT_SIMPLEX_GRAD[(var27) | 2] * var62;
+
+ final double var95 = localX * 6.0 - 15.0;
+ final double var96 = fadeLocalY * 6.0 - 15.0;
+ final double var97 = localZ * 6.0 - 15.0;
+ final double var98 = localX * var95 + 10.0;
+ final double var99 = fadeLocalY * var96 + 10.0;
+ final double var100 = localZ * var97 + 10.0;
+ final double var101 = localX * localX * localX * var98;
+ final double var102 = fadeLocalY * fadeLocalY * fadeLocalY * var99;
+ final double var103 = localZ * localZ * localZ * var100;
+
+ final double var113 = var87 + var101 * (var88 - var87);
+ final double var114 = var93 + var101 * (var94 - var93);
+ final double var115 = var91 + var101 * (var92 - var91);
+ final double var116 = var89 + var101 * (var90 - var89);
+ final double var117 = var114 - var115;
+ final double var118 = var102 * (var116 - var113);
+ final double var119 = var102 * var117;
+ final double var120 = var113 + var118;
+ final double var121 = var115 + var119;
+ return var120 + (var103 * (var121 - var120));
+ }
+ // Leaves end - optimize noise generation
}

private double sampleWithDerivative(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double[] ds) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
index 97ef7288ea935f3d17c5b7a9eba642143c786c2b..c71dc320b055c5b1981561894617be05dae35653 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
@@ -26,6 +26,10 @@ public class PerlinNoise {
private final double lowestFreqValueFactor;
private final double lowestFreqInputFactor;
private final double maxValue;
+ // Leaves start - optimize noise generation
+ private final int octaveSamplersCount;
+ private final double [] amplitudesArray;
+ // Leaves end - optimize noise generation

/** @deprecated */
@Deprecated
@@ -131,6 +135,10 @@ public class PerlinNoise {
this.lowestFreqInputFactor = Math.pow(2.0D, (double)(-j));
this.lowestFreqValueFactor = Math.pow(2.0D, (double)(i - 1)) / (Math.pow(2.0D, (double)i) - 1.0D);
this.maxValue = this.edgeValue(2.0D);
+ // Leaves start - optimize noise generation
+ this.octaveSamplersCount = this.noiseLevels.length;
+ this.amplitudesArray = this.amplitudes.toDoubleArray();
+ // Leaves end - optimize noise generation
}

protected double maxValue() {
@@ -142,7 +150,30 @@ public class PerlinNoise {
}

public double getValue(double x, double y, double z) {
- return this.getValue(x, y, z, 0.0D, 0.0D, false);
+ // Leaves start - optimize noise generation
+ if (!top.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) {
+ return this.getValue(x, y, z, 0.0D, 0.0D, false);
+ } else {
+ double d = 0.0;
+ double e = this.lowestFreqInputFactor;
+ double f = this.lowestFreqValueFactor;
+
+ for(int i = 0; i < this.octaveSamplersCount; ++i) {
+ ImprovedNoise perlinNoiseSampler = this.noiseLevels[i];
+ if (perlinNoiseSampler != null) {
+ @SuppressWarnings("deprecation")
+ double g = perlinNoiseSampler.noise(
+ wrap(x * e), wrap(y * e), wrap(z * e), 0.0, 0.0
+ );
+ d += this.amplitudesArray[i] * g * f;
+ }
+
+ e *= 2.0;
+ f /= 2.0;
+ }
+ return d;
+ }
+ // Leaves end - optimize noise generation
}

/** @deprecated */

0 comments on commit 1df9d40

Please sign in to comment.