Skip to content

Commit 8a4d114

Browse files
author
Cory Leach
committed
NoiseSample and Value Derivative Calculation
1 parent 2c82dbc commit 8a4d114

File tree

7 files changed

+459
-0
lines changed

7 files changed

+459
-0
lines changed

Runtime/Utility/NoiseSample.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using UnityEngine;
2+
3+
namespace Gameframe.Procgen
4+
{
5+
/// <summary>
6+
/// A sampling of noise including the value of the noise and the derivative at the same position
7+
/// </summary>
8+
public struct NoiseSample
9+
{
10+
public float value;
11+
public Vector3 derivative;
12+
13+
public static NoiseSample operator +(NoiseSample a, NoiseSample b)
14+
{
15+
a.value += b.value;
16+
a.derivative += b.derivative;
17+
return a;
18+
}
19+
20+
public static NoiseSample operator +(NoiseSample a, float b)
21+
{
22+
a.value += b;
23+
return a;
24+
}
25+
26+
public static NoiseSample operator +(float a, NoiseSample b)
27+
{
28+
b.value += a;
29+
return b;
30+
}
31+
32+
public static NoiseSample operator -(NoiseSample a, float b)
33+
{
34+
a.value -= b;
35+
return a;
36+
}
37+
38+
public static NoiseSample operator -(float a, NoiseSample b)
39+
{
40+
b.value = a - b.value;
41+
b.derivative = -b.derivative;
42+
return b;
43+
}
44+
45+
public static NoiseSample operator -(NoiseSample a, NoiseSample b)
46+
{
47+
a.value -= b.value;
48+
a.derivative -= b.derivative;
49+
return a;
50+
}
51+
52+
public static NoiseSample operator *(NoiseSample a, float b)
53+
{
54+
a.value *= b;
55+
a.derivative *= b;
56+
return a;
57+
}
58+
59+
public static NoiseSample operator *(float a, NoiseSample b)
60+
{
61+
b.value *= a;
62+
b.derivative *= a;
63+
return b;
64+
}
65+
66+
public static NoiseSample operator *(NoiseSample a, NoiseSample b)
67+
{
68+
a.derivative = a.derivative * b.value + b.derivative * a.value;
69+
a.value *= b.value;
70+
return a;
71+
}
72+
}
73+
}

Runtime/Utility/NoiseSample.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Utility/PerlinGradientNoise.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,44 @@ public static float Noise1D(float x, uint seed)
197197
return v * 0.5f + 0.5f; //Remap from -1 to 1, to 0 to 1
198198
}
199199

200+
public static NoiseSample Sample1D(float x, uint seed, float frequency = 1)
201+
{
202+
var x0 = Mathf.FloorToInt(x * frequency);
203+
var x1 = x0 + 1;
204+
205+
var t0 = x - x0;
206+
var t1 = t0 - 1f;
207+
208+
var g0 = HashToGradient1D(Hash1D(x0, seed));
209+
var g1 = HashToGradient1D(Hash1D(x1, seed));
210+
211+
var v0 = g0 * t0;
212+
var v1 = g1 * t1;
213+
214+
var t = Smooth(t0);
215+
var dt = SmoothDerivative(t0);
216+
217+
var a = v0;
218+
var b = v1 - v0;
219+
220+
var v = a + b * t;
221+
var dv = b * t;
222+
223+
var sample = new NoiseSample
224+
{
225+
value = v * 2f,
226+
};
227+
228+
sample.derivative.x = dv;
229+
sample.derivative.y = 0;
230+
sample.derivative.z = 0;
231+
232+
sample.derivative *= frequency;
233+
234+
return sample;
235+
}
236+
237+
200238
/// <summary>
201239
/// 2 dimensional perlin noise
202240
/// </summary>
@@ -237,6 +275,52 @@ public static float Noise2D(float x, float y, uint seed)
237275
return v * 0.5f + 0.5f; //Remap from -1 to 1, to 0 to 1
238276
}
239277

278+
public static NoiseSample Sample2D(float x, float y, uint seed, float frequency = 1f)
279+
{
280+
x *= frequency;
281+
y *= frequency;
282+
283+
var x0 = Mathf.FloorToInt(x);
284+
var x1 = x0 + 1;
285+
286+
var y0 = Mathf.FloorToInt(y);
287+
var y1 = y0 + 1;
288+
289+
var tx0 = x - x0;
290+
var tx1 = tx0 - 1f;
291+
292+
var ty0 = y - y0;
293+
var ty1 = ty0 - 1f;
294+
295+
var g00 = HashToGradient2D(Hash2D(x0, y0, seed));
296+
var g10 = HashToGradient2D(Hash2D(x1, y0, seed));
297+
var g01 = HashToGradient2D(Hash2D(x0, y1, seed));
298+
var g11 = HashToGradient2D(Hash2D(x1, y1, seed));
299+
300+
var v00 = Dot2D(g00, tx0, ty0);
301+
var v10 = Dot2D(g10, tx1, ty0);
302+
var v01 = Dot2D(g01, tx0, ty1);
303+
var v11 = Dot2D(g11, tx1, ty1);
304+
305+
var tx = Smooth(tx0);
306+
var ty = Smooth(ty0);
307+
308+
var a = v00;
309+
var b = v10 - v00;
310+
311+
var v0 = Mathf.Lerp(v00, v10, tx);
312+
var v1 = Mathf.Lerp(v01, v11, tx);
313+
var v = Mathf.Lerp(v0, v1, ty) * Sqr2;
314+
315+
var sample = new NoiseSample
316+
{
317+
318+
};
319+
320+
return sample;
321+
}
322+
323+
240324
/// <summary>
241325
/// 2 dimensional perlin noise
242326
/// </summary>
@@ -377,9 +461,21 @@ private static float Smooth(float t)
377461
{
378462
return SmoothStep.Degree5(t);
379463
}
464+
465+
private static float SmoothDerivative(float t)
466+
{
467+
return SmoothStep.Degree5Derivative(t);
468+
}
380469
}
381470

382471
public static class SimplexGradientNoise
383472
{
473+
public static float Noise1D(float x, uint seed)
474+
{
475+
var x0 = Mathf.FloorToInt(x);
476+
var x1 = x - x0;
477+
478+
return 0;
479+
}
384480
}
385481
}

Runtime/Utility/SmoothStep.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,10 @@ public static float Degree5(float t)
2828
{
2929
return t * t * t * (t * (t * 6f - 15f) + 10f);
3030
}
31+
32+
public static float Degree5Derivative(float t)
33+
{
34+
return 30f * t * t * (t * (t - 2f) + 1f);
35+
}
3136
}
3237
}

Runtime/Utility/ValueNoise.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,36 @@ public static float Noise1D(float x, uint seed)
143143
return Mathf.Lerp(v0, v1, t);
144144
}
145145

146+
public static NoiseSample Sample1D(float x, uint seed, float frequency = 1)
147+
{
148+
var x0 = Mathf.FloorToInt(x * frequency);
149+
var x1 = x0 + 1;
150+
151+
var t = Smooth(x - x0);
152+
var dt = SmoothDerivative(x - x0);
153+
154+
var v0 = SquirrelEiserloh.Get1dNoiseZeroToOne(x0, seed);
155+
var v1 = SquirrelEiserloh.Get1dNoiseZeroToOne(x1, seed);
156+
157+
var a = v0;
158+
var b = v1 - v0;
159+
var v = a + b * t; //Lerp
160+
var dv = b * dt; //Lerp Derivative
161+
162+
var sample = new NoiseSample
163+
{
164+
value = v,
165+
};
166+
167+
sample.derivative.x = dv;
168+
sample.derivative.y = 0;
169+
sample.derivative.z = 0;
170+
171+
sample.derivative *= frequency;
172+
173+
return sample;
174+
}
175+
146176
public static float Noise2D(float x, float y, uint seed)
147177
{
148178
var x0 = Mathf.FloorToInt(x);
@@ -165,6 +195,49 @@ public static float Noise2D(float x, float y, uint seed)
165195
return Mathf.Lerp(edge1, edge2, ty);
166196
}
167197

198+
public static NoiseSample Sample2D(float x, float y, uint seed, float frequency = 1f)
199+
{
200+
x *= frequency;
201+
y *= frequency;
202+
203+
var x0 = Mathf.FloorToInt(x);
204+
var y0 = Mathf.FloorToInt(y);
205+
var x1 = x0 + 1;
206+
var y1 = y0 + 1;
207+
208+
var tx = Smooth(x - x0);
209+
var ty = Smooth(y - y0);
210+
211+
var dtx = SmoothDerivative(x - x0);
212+
var dty = SmoothDerivative(y - y0);
213+
214+
var v00 = SquirrelEiserloh.Get2dNoiseZeroToOne(x0, y0, seed);
215+
var v01 = SquirrelEiserloh.Get2dNoiseZeroToOne(x0, y1, seed);
216+
217+
var v10 = SquirrelEiserloh.Get2dNoiseZeroToOne(x1, y0, seed);
218+
var v11 = SquirrelEiserloh.Get2dNoiseZeroToOne(x1, y1, seed);
219+
220+
var a = v00;
221+
var b = v10 - v00;
222+
var c = v01 - v00;
223+
var d = v11 - v01 - v10 + v00;
224+
225+
var v = a + b * tx + (c + d * tx) * ty;
226+
227+
var sample = new NoiseSample
228+
{
229+
value = v
230+
};
231+
232+
sample.derivative.x = (b + d * ty) * dtx;
233+
sample.derivative.y = (c + d * tx) * dty;
234+
sample.derivative.z = 0;
235+
236+
sample.derivative *= frequency;
237+
238+
return sample;
239+
}
240+
168241
public static float Noise2D(Vector2 v, uint seed)
169242
{
170243
return Noise2D(v.x, v.y, seed);
@@ -219,5 +292,10 @@ private static float Smooth(float t)
219292
{
220293
return SmoothStep.Degree5(t);
221294
}
295+
296+
private static float SmoothDerivative(float t)
297+
{
298+
return SmoothStep.Degree5Derivative(t);
299+
}
222300
}
223301
}

0 commit comments

Comments
 (0)