Created
March 23, 2019 01:48
-
-
Save JSandusky/b9d030edf793fc55e7f75c64df1f7f83 to your computer and use it in GitHub Desktop.
Ubernoise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Description("Uses noise derivatives to produce an extremely versatile noise")] | |
[PropertyData.PropertyIgnore("Interpolation")] | |
public partial class UberNoise : NoiseGenerator | |
{ | |
float lacunarity_ = 2.0f; | |
int octaves_ = 3; | |
float gain_ = 0.5f; | |
float perturbFeatures_ = 0.2f; | |
float sharpness_ = 0.7f; | |
float amplify_ = 0.7f; | |
float altitudeErosion_ = 0.7f; | |
float ridgeErosion_ = 0.7f; | |
float slopeErosion_ = 0.7f; | |
[PropertyData.AllowPermutations] | |
[Description("Factor to scale each successive octave by")] | |
public float Lacunarity { get { return lacunarity_; } set { lacunarity_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Number of passes to accumulate")] | |
public int Octaves { get { return octaves_; } set { octaves_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Power applied to each octave")] | |
public float Gain { get { return gain_; } set { gain_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Perturbation creates rippled shapes")] | |
public float PerturbFeatures { get { return perturbFeatures_; } set { perturbFeatures_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Brightness of the ridged pattern")] | |
public float Sharpness { get { return sharpness_; } set { sharpness_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Intensity of the centers of the ridged pattern")] | |
public float AmplifyFeatures { get { return amplify_; } set { amplify_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Dampens noise in the pattern")] | |
public float AltitudeErosion { get { return altitudeErosion_; } set { altitudeErosion_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Intensity of the \"clouds\" like effect")] | |
public float RidgeErosion { get { return ridgeErosion_; } set { ridgeErosion_ = value; OnPropertyChanged(); } } | |
[PropertyData.AllowPermutations] | |
[Description("Smoothness of the overall pattern")] | |
public float SlopeErosion { get { return slopeErosion_; } set { slopeErosion_ = value; OnPropertyChanged(); } } | |
public override void Construct() | |
{ | |
base.Construct(); | |
Name = "Uber-Noise"; | |
} | |
public override void Execute(object param) | |
{ | |
Vector4 vParam = (Vector4)param; | |
Vector4 pos = new Vector4(vParam.X * Period.X, vParam.Y * Period.Y, 0.0f, 0.0f); | |
float value = 0.0f; | |
var seed = noise_.GetSeed(); | |
float sum = 0.0f, featureNoise = 0.0f; | |
var noiseValue = DerivativeNoise(pos, seed); | |
featureNoise = noiseValue.X; | |
float max = 0.0f; | |
float amp = 1.0f; | |
float currentGain = 1.0f; | |
int i = 0; | |
Vector3 lDerivative = new Vector3(noiseValue.Y, noiseValue.Z, noiseValue.W); | |
var aaddToPos = lDerivative * PerturbFeatures; | |
pos.X += aaddToPos.X; | |
pos.Y += aaddToPos.Y; | |
pos.Z += aaddToPos.Z; | |
Vector3 ridgeErosionDerivative = new Vector3(0, 0, 0); | |
Vector3 slopeErosionDerivative = new Vector3(0, 0, 0); | |
while (++i < Octaves) | |
{ | |
// Accumulate max (amp * 2 covers full damped amp range) | |
max += amp * 2 + (currentGain * AmplifyFeatures); | |
// Accumulate derivatives | |
ridgeErosionDerivative += lDerivative * RidgeErosion; | |
slopeErosionDerivative += lDerivative * SlopeErosion; | |
// Sharpness | |
float ridgedNoise = ((1.0f) - Mathf.Abs(featureNoise)); | |
float billowNoise = featureNoise * featureNoise; | |
featureNoise = Mathf.Lerp(featureNoise, billowNoise, Math.Max(0.0f, Sharpness)); | |
featureNoise = Mathf.Lerp(featureNoise, ridgedNoise, Mathf.Abs(Math.Min(0.0f, Sharpness))); | |
// Slope Erosion | |
sum += amp * featureNoise * (1.0f / (1.0f + slopeErosionDerivative.LengthSquared())); | |
// Amplitude damping | |
float dampedAmp = amp * (1.0f - (RidgeErosion / (1.0f * ridgeErosionDerivative.LengthSquared()))); | |
sum += dampedAmp * featureNoise * (1.0f / (1.0f * slopeErosionDerivative.LengthSquared())); | |
amp *= Mathf.Lerp(currentGain, currentGain * Mathf.Lerp(0.0f, 1.0f, sum / max), AltitudeErosion); | |
// Amplify features | |
sum += featureNoise * currentGain * AmplifyFeatures; | |
currentGain = currentGain * Gain * AmplifyFeatures; | |
// Prepare for next pass | |
seed = (seed + i) & 0x7fffffff; | |
var addToPos = lDerivative * PerturbFeatures; | |
pos.X += addToPos.X; | |
pos.Y += addToPos.Y; | |
pos.Z += addToPos.Z; | |
pos.X *= Lacunarity; | |
pos.Y *= Lacunarity; | |
pos.Z *= Lacunarity; | |
pos.W *= Lacunarity; | |
noiseValue = DerivativeNoise(pos, ++seed); | |
featureNoise = noiseValue.X; | |
lDerivative = new Vector3(noiseValue.Y, noiseValue.Z, noiseValue.W); | |
} | |
value = Mathf.Clamp01(sum / max); | |
value = Mathf.Normalize(value, -1.0f, 1.0f); | |
if (Inverted) | |
OutputSockets[0].Data = 1.0f - value; | |
else | |
OutputSockets[0].Data = value; | |
// stupid | |
OutputSockets[1].Data = OutputSockets[0].Data; | |
} | |
Vector4 DerivativeNoise(Vector4 p, int seed) | |
{ | |
float baseNoise = noise_.GetSimplex(p.X, p.Y, p.Z, p.W); | |
float H = 0.1f; | |
float dx = noise_.GetSimplex(p.X + H, p.Y, p.Z, p.W) - noise_.GetSimplex(p.X - H, p.Y, p.Z, p.W); | |
float dy = noise_.GetSimplex(p.X, p.Y + H, p.Z, p.W) - noise_.GetSimplex(p.X, p.Y - H, p.Z, p.W); | |
float dz = noise_.GetSimplex(p.X, p.Y, p.Z + H, p.W) - noise_.GetSimplex(p.X, p.Y, p.Z - H, p.W); | |
//var v = new Vector3(dx, dy, dz); | |
return new Vector4(baseNoise, dx, dy, 1);// v.z); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment