Cellularize things

This commit is contained in:
cyberpwn 2021-11-12 06:24:47 -05:00
parent 60ac9dfca2
commit b52017625d
3 changed files with 163 additions and 0 deletions

View File

@ -20,6 +20,7 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.BiasedCellularNoise;
import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.noise.CNG;
import com.volmit.iris.util.noise.CNGFactory; import com.volmit.iris.util.noise.CNGFactory;
import com.volmit.iris.util.noise.NoiseType; import com.volmit.iris.util.noise.NoiseType;
@ -447,6 +448,22 @@ public enum NoiseStyle {
@Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.") @Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.")
VASCULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.VASCULAR)), VASCULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.VASCULAR)),
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
SIMPLEX_BIASED_CELLULAR(rng -> new CNG(rng, new BiasedCellularNoise(rng.lmax(),
SIMPLEX.stream(rng.nextParallelRNG(-23333666)).zoom(0.158)), 1D, 1)),
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
NOWHERE_BIASED_CELLULAR(rng -> new CNG(rng, new BiasedCellularNoise(rng.lmax(),
NOWHERE.stream(rng.nextParallelRNG(-23333666)).zoom(0.158)), 1D, 1)),
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
IRIS_BIASED_CELLULAR(rng -> new CNG(rng, new BiasedCellularNoise(rng.lmax(),
IRIS.stream(rng.nextParallelRNG(-23333666)).zoom(0.158)), 1D, 1)),
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
VASCULAR_BIASED_CELLULAR(rng -> new CNG(rng, new BiasedCellularNoise(rng.lmax(),
VASCULAR.stream(rng.nextParallelRNG(-23333666)).zoom(0.158)), 1D, 1)),
; ;
private final CNGFactory f; private final CNGFactory f;

View File

@ -0,0 +1,52 @@
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.volmit.iris.util.noise;
import com.volmit.iris.engine.object.NoiseStyle;
import com.volmit.iris.util.interpolation.IrisInterpolation;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.stream.ProceduralStream;
public class BiasedCellularNoise implements NoiseGenerator {
private final FastNoise n;
private final ProceduralStream<Double> biasShape;
public BiasedCellularNoise(long seed, ProceduralStream<Double> biasShape) {
this.biasShape = biasShape.subtract(0.5).multiply(2);
this.n = new FastNoise(new RNG(seed).imax());
n.SetNoiseType(FastNoise.NoiseType.Cellular);
n.SetCellularReturnType(FastNoise.CellularReturnType.CellValue);
n.SetCellularDistanceFunction(FastNoise.CellularDistanceFunction.Natural);
}
@Override
public double noise(double x) {
return (n.GetCellular((float) x, (float) 0, biasShape) / 2D) + 0.5D;
}
@Override
public double noise(double x, double z) {
return (n.GetCellular((float) x, (float) z, biasShape) / 2D) + 0.5D;
}
@Override
public double noise(double x, double y, double z) {
return (n.GetCellular((float) x, (float) y, biasShape) / 2D) + 0.5D;
}
}

View File

@ -20,6 +20,7 @@ package com.volmit.iris.util.noise;
import com.volmit.iris.util.math.Vector2f; import com.volmit.iris.util.math.Vector2f;
import com.volmit.iris.util.math.Vector3f; import com.volmit.iris.util.math.Vector3f;
import com.volmit.iris.util.stream.ProceduralStream;
public class FastNoise { public class FastNoise {
private static final Float2[] GRAD_2D = {new Float2(-1, -1), new Float2(1, -1), new Float2(-1, 1), new Float2(1, 1), new Float2(0, -1), new Float2(-1, 0), new Float2(0, 1), new Float2(1, 0), private static final Float2[] GRAD_2D = {new Float2(-1, -1), new Float2(1, -1), new Float2(-1, 1), new Float2(1, 1), new Float2(0, -1), new Float2(-1, 0), new Float2(0, 1), new Float2(1, 0),
@ -1728,6 +1729,19 @@ public class FastNoise {
return 0; return 0;
} }
} }
public float GetCellular(float x, float y, ProceduralStream<Double> sourceNoise) {
x *= m_frequency;
y *= m_frequency;
switch (m_cellularReturnType) {
case CellValue:
case NoiseLookup:
case Distance:
return SingleCellular(x, y, sourceNoise);
default:
return SingleCellular2Edge(x, y);
}
}
public float GetCellular(float x, float y) { public float GetCellular(float x, float y) {
x *= m_frequency; x *= m_frequency;
@ -1823,6 +1837,86 @@ public class FastNoise {
} }
} }
private float SingleCellular(float x, float y, ProceduralStream<Double> sourceNoise) {
int xr = FastRound(x);
int yr = FastRound(y);
float distance = 999999;
int xc = 0, yc = 0;
switch (m_cellularDistanceFunction) {
default:
case Euclidean:
for (int xi = xr - 1; xi <= xr + 1; xi++) {
for (int yi = yr - 1; yi <= yr + 1; yi++) {
Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255];
float vecX = xi - x + vec.x;
float vecY = yi - y + vec.y;
float newDistance = vecX * vecX + vecY * vecY;
if (newDistance < distance) {
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
case Manhattan:
for (int xi = xr - 1; xi <= xr + 1; xi++) {
for (int yi = yr - 1; yi <= yr + 1; yi++) {
Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255];
float vecX = xi - x + vec.x;
float vecY = yi - y + vec.y;
float newDistance = (Math.abs(vecX) + Math.abs(vecY));
if (newDistance < distance) {
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
case Natural:
for (int xi = xr - 1; xi <= xr + 1; xi++) {
for (int yi = yr - 1; yi <= yr + 1; yi++) {
Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255];
float vecX = xi - x + vec.x;
float vecY = yi - y + vec.y;
float newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY);
if (newDistance < distance) {
distance = newDistance;
xc = xi;
yc = yi;
}
}
}
break;
}
switch (m_cellularReturnType) {
case CellValue:
return sourceNoise.get(xc, yc).floatValue();
case NoiseLookup:
Float2 vec = CELL_2D[Hash2D(m_seed, xc, yc) & 255];
return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y);
case Distance:
return distance - 1;
default:
return 0;
}
}
private float SingleCellular2Edge(float x, float y) { private float SingleCellular2Edge(float x, float y) {
int xr = FastRound(x); int xr = FastRound(x);
int yr = FastRound(y); int yr = FastRound(y);