From 9f425c615998f378dd2a1128c1718e59e0864a5f Mon Sep 17 00:00:00 2001 From: Astrash Date: Wed, 9 Oct 2024 20:39:45 +1100 Subject: [PATCH] Add support for derivatives in FBM --- .../noise/fractal/BrownianMotionSampler.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java index bc766c731..6c78ce727 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java @@ -7,6 +7,7 @@ package com.dfsek.terra.addons.noise.samplers.noise.fractal; +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.util.MathUtil; @@ -52,4 +53,59 @@ public class BrownianMotionSampler extends FractalNoiseFunction { return sum; } + + @Override + public boolean isDifferentiable() { + return input instanceof DerivativeNoiseSampler dSampler && dSampler.isDifferentiable(); + } + + @Override + public double[] getNoiseDerivativeRaw(long seed, double x, double y) { + double[] sum = {0, 0, 0}; + double amp = fractalBounding; + + for(int i = 0; i < octaves; i++) { + // This should only be called after `input` is verified as a `DerivativeNoiseSampler` + // so this should be a safe cast + double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y); + sum[0] += noise[0] * amp; + + // Directional derivative of each octave can be subject to the same addition and product + // as per derivative sum and product rules in order to produce the correct final derivative + sum[1] += noise[1] * amp; + sum[2] += noise[2] * amp; + + amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise[0] + 1, 2) * 0.5); + + x *= lacunarity; + y *= lacunarity; + amp *= gain; + } + + return sum; + } + + @Override + public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) { + double[] sum = {0, 0, 0}; + double amp = fractalBounding; + + for(int i = 0; i < octaves; i++) { + double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y, z); + sum[0] += noise[0] * amp; + + // See comment in 2D version + sum[1] += noise[1] * amp; + sum[2] += noise[2] * amp; + + amp *= MathUtil.lerp(weightedStrength, 1.0, (noise[0] + 1) * 0.5); + + x *= lacunarity; + y *= lacunarity; + z *= lacunarity; + amp *= gain; + } + + return sum; + } }