Skip to content

Commit 6013b16

Browse files
committed
working tiling cell noise implementation
1 parent 03becbc commit 6013b16

File tree

5 files changed

+148
-60
lines changed

5 files changed

+148
-60
lines changed

sources/noise/cell.swift

Lines changed: 107 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ extension _CellNoise2D
3131

3232
// ugly hack to get around compiler linker bug
3333
@inline(__always)
34-
fileprivate
3534
func _closest_point(_ x:Double, _ y:Double) -> (point:(Int, Int), r2:Double)
3635
{
3736
let sample:Math.DoubleV2 = (x * self.frequency, y * self.frequency)
@@ -72,7 +71,7 @@ extension _CellNoise2D
7271
// found.
7372

7473
let quadrant:Math.IntV2 = (sample_rel.x > 0.5 ? 1 : -1 , sample_rel.y > 0.5 ? 1 : -1),
75-
near:Math.IntV2 = (bin.a + (quadrant.a + 1) >> 1, bin.b + (quadrant.b + 1) >> 1),
74+
near:Math.IntV2 = Math.add(bin, ((quadrant.a + 1) >> 1, (quadrant.b + 1) >> 1)),
7675
far:Math.IntV2 = (near.a - quadrant.a , near.b - quadrant.b)
7776

7877
let nearpoint_disp:Math.DoubleV2 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
@@ -189,12 +188,6 @@ struct CellNoise2D:_CellNoise2D, HashedNoise
189188
self.permutation_table = PermutationTable(seed: seed)
190189
}
191190

192-
fileprivate
193-
func hash(point:Math.IntV2) -> Int
194-
{
195-
return self.permutation_table.hash(point)
196-
}
197-
198191
public
199192
func closest_point(_ x:Double, _ y:Double) -> (point:(Int, Int), r2:Double)
200193
{
@@ -221,7 +214,6 @@ struct CellNoise2D:_CellNoise2D, HashedNoise
221214
}
222215
}
223216

224-
/*
225217
public
226218
struct TilingCellNoise2D:_CellNoise2D, HashedTilingNoise
227219
{
@@ -256,12 +248,6 @@ struct TilingCellNoise2D:_CellNoise2D, HashedTilingNoise
256248
self.wavelengths = (wavelengths_x, wavelengths_y)
257249
}
258250

259-
fileprivate
260-
func hash(point:Math.IntV2) -> Int
261-
{
262-
return self.permutation_table.hash(Math.mod(point, self.wavelengths))
263-
}
264-
265251
public
266252
func closest_point(_ x:Double, _ y:Double) -> (point:(Int, Int), r2:Double)
267253
{
@@ -287,34 +273,24 @@ struct TilingCellNoise2D:_CellNoise2D, HashedTilingNoise
287273
return self.evaluate(x, y)
288274
}
289275
}
290-
*/
291276

292-
public
293-
struct CellNoise3D:HashedNoise
294-
{
295-
let permutation_table:PermutationTable,
296-
amplitude:Double,
297-
frequency:Double
298277

299-
init(amplitude:Double, frequency:Double, permutation_table:PermutationTable)
300-
{
301-
self.amplitude = amplitude
302-
self.frequency = frequency
303-
self.permutation_table = permutation_table
304-
}
278+
fileprivate
279+
protocol _CellNoise3D
280+
{
281+
var frequency:Double { get }
282+
var amplitude:Double { get }
305283

306-
public
307-
init(amplitude:Double, frequency:Double, seed:Int = 0)
308-
{
309-
self.amplitude = amplitude * 1/3
310-
self.frequency = frequency
311-
self.permutation_table = PermutationTable(seed: seed)
312-
}
284+
func hash(point:Math.IntV3) -> Int
285+
}
313286

287+
extension _CellNoise3D
288+
{
289+
@inline(__always)
314290
private
315291
func distance2(from sample_point:Math.DoubleV3, generating_point:Math.IntV3) -> Double
316292
{
317-
let hash:Int = self.permutation_table.hash(generating_point)
293+
let hash:Int = self.hash(point: generating_point)
318294
// hash is within 0 ... 255, take it to 0 ... 0.5
319295

320296
// Notice that we have 256 possible hashes, and therefore 8 bits of entropy,
@@ -333,8 +309,8 @@ struct CellNoise3D:HashedNoise
333309
return Math.dot(dv, dv)
334310
}
335311

336-
public
337-
func closest_point(_ x:Double, _ y:Double, _ z:Double) -> (point:(Int, Int, Int), r2:Double)
312+
@inline(__always)
313+
func _closest_point(_ x:Double, _ y:Double, _ z:Double) -> (point:(Int, Int, Int), r2:Double)
338314
{
339315
let sample:Math.DoubleV3 = (x * self.frequency, y * self.frequency, z * self.frequency)
340316

@@ -354,9 +330,9 @@ struct CellNoise3D:HashedNoise
354330
let quadrant:Math.IntV3 = (sample_rel.x > 0.5 ? 1 : -1,
355331
sample_rel.y > 0.5 ? 1 : -1,
356332
sample_rel.z > 0.5 ? 1 : -1)
357-
let near:Math.IntV3 = (bin.a + (quadrant.a + 1) >> 1,
358-
bin.b + (quadrant.b + 1) >> 1,
359-
bin.c + (quadrant.c + 1) >> 1)
333+
let near:Math.IntV3 = Math.add(bin, ((quadrant.a + 1) >> 1,
334+
(quadrant.b + 1) >> 1,
335+
(quadrant.c + 1) >> 1))
360336

361337
let nearpoint_disp:Math.DoubleV3 = (abs(sample_rel.x - Double((quadrant.a + 1) >> 1)),
362338
abs(sample_rel.y - Double((quadrant.b + 1) >> 1)),
@@ -539,6 +515,96 @@ struct CellNoise3D:HashedNoise
539515
// stop outside r^2 = 3.0
540516
return (closest_point, r2)
541517
}
518+
}
519+
520+
public
521+
struct CellNoise3D:_CellNoise3D, HashedNoise
522+
{
523+
let permutation_table:PermutationTable,
524+
amplitude:Double,
525+
frequency:Double
526+
527+
init(amplitude:Double, frequency:Double, permutation_table:PermutationTable)
528+
{
529+
self.amplitude = amplitude
530+
self.frequency = frequency
531+
self.permutation_table = permutation_table
532+
}
533+
534+
public
535+
init(amplitude:Double, frequency:Double, seed:Int = 0)
536+
{
537+
self.amplitude = amplitude * 1/3
538+
self.frequency = frequency
539+
self.permutation_table = PermutationTable(seed: seed)
540+
}
541+
542+
public
543+
func closest_point(_ x:Double, _ y:Double, _ z:Double) -> (point:(Int, Int, Int), r2:Double)
544+
{
545+
return self._closest_point(x, y, z)
546+
}
547+
548+
public
549+
func evaluate(_ x:Double, _ y:Double) -> Double
550+
{
551+
return self.evaluate(x, y, 0)
552+
}
553+
554+
public
555+
func evaluate(_ x:Double, _ y:Double, _ z:Double) -> Double
556+
{
557+
let (_, r2):((Int, Int, Int), Double) = self.closest_point(x, y, z)
558+
return self.amplitude * r2
559+
}
560+
561+
public
562+
func evaluate(_ x:Double, _ y:Double, _ z:Double, _:Double) -> Double
563+
{
564+
return self.evaluate(x, y, z)
565+
}
566+
}
567+
568+
public
569+
struct TilingCellNoise3D:_CellNoise3D, HashedTilingNoise
570+
{
571+
let permutation_table:PermutationTable,
572+
amplitude:Double,
573+
frequency:Double,
574+
wavelengths:Math.IntV3
575+
576+
init(amplitude:Double, frequency:Double, permutation_table:PermutationTable, wavelengths:Math.IntV3)
577+
{
578+
self.amplitude = amplitude
579+
self.frequency = frequency
580+
self.permutation_table = permutation_table
581+
self.wavelengths = wavelengths
582+
}
583+
584+
public
585+
init(amplitude:Double, frequency:Double, wavelengths:Int, seed:Int = 0)
586+
{
587+
self.init( amplitude: amplitude, frequency: frequency,
588+
wavelengths_x: wavelengths,
589+
wavelengths_y: wavelengths,
590+
wavelengths_z: wavelengths,
591+
seed: seed)
592+
}
593+
594+
public
595+
init(amplitude:Double, frequency:Double, wavelengths_x:Int, wavelengths_y:Int, wavelengths_z:Int, seed:Int = 0)
596+
{
597+
self.amplitude = 1 / 3 * amplitude
598+
self.frequency = frequency
599+
self.permutation_table = PermutationTable(seed: seed)
600+
self.wavelengths = (wavelengths_x, wavelengths_y, wavelengths_z)
601+
}
602+
603+
public
604+
func closest_point(_ x:Double, _ y:Double, _ z:Double) -> (point:(Int, Int, Int), r2:Double)
605+
{
606+
return self._closest_point(x, y, z)
607+
}
542608

543609
public
544610
func evaluate(_ x:Double, _ y:Double) -> Double

sources/noise/gradient.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ extension _ClassicNoise3D
2323

2424
// ugly hack to get around compiler linker bug
2525
@inline(__always)
26-
fileprivate
2726
func _evaluate(_ x:Double, _ y:Double, _ z:Double) -> Double
2827
{
2928
let sample:Math.DoubleV3 = (x * self.frequency, y * self.frequency, z * self.frequency)
@@ -77,12 +76,6 @@ struct ClassicNoise3D:_ClassicNoise3D, HashedNoise
7776
self.permutation_table = PermutationTable(seed: seed)
7877
}
7978

80-
fileprivate
81-
func hash(point:Math.IntV3) -> Int
82-
{
83-
return self.permutation_table.hash(point)
84-
}
85-
8679
public
8780
func evaluate(_ x:Double, _ y:Double) -> Double
8881
{
@@ -138,12 +131,6 @@ struct TilingClassicNoise3D:_ClassicNoise3D, HashedTilingNoise
138131
self.wavelengths = (wavelengths_x, wavelengths_y, wavelengths_z)
139132
}
140133

141-
fileprivate
142-
func hash(point:Math.IntV3) -> Int
143-
{
144-
return self.permutation_table.hash(Math.mod(point, self.wavelengths))
145-
}
146-
147134
public
148135
func evaluate(_ x:Double, _ y:Double) -> Double
149136
{

sources/noise/hash.swift

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ extension HashedNoise
2626
let new_table:PermutationTable = PermutationTable(reseeding: self.permutation_table)
2727
return Self(amplitude: self.amplitude, frequency: self.frequency, permutation_table: new_table)
2828
}
29+
30+
func hash(point:Math.IntV2) -> Int
31+
{
32+
return self.permutation_table.hash(point)
33+
}
34+
35+
func hash(point:Math.IntV3) -> Int
36+
{
37+
return self.permutation_table.hash(point)
38+
}
2939
}
3040

3141
protocol HashedTilingNoise:Noise
@@ -38,6 +48,8 @@ protocol HashedTilingNoise:Noise
3848
var wavelengths:IntV { get }
3949

4050
init(amplitude:Double, frequency:Double, permutation_table:PermutationTable, wavelengths:IntV)
51+
52+
func _transpose_wavelengths(_ wavelengths:IntV, octaves:Int) -> IntV
4153
}
4254

4355
extension HashedTilingNoise
@@ -61,20 +73,42 @@ extension HashedTilingNoise
6173
return Self(amplitude: self.amplitude, frequency: self.frequency,
6274
permutation_table: new_table, wavelengths: self.wavelengths)
6375
}
64-
}
65-
/*
66-
extension HashedTilingNoise where IntV == Math.IntV3
67-
{
76+
6877
public
6978
func transposed(octaves:Int) -> Self
7079
{
7180
let frequency_factor:Double = octaves >= 0 ? Double(1 << octaves) : 1 / Double(1 << -octaves)
7281
return Self(amplitude: self.amplitude, frequency: self.frequency * frequency_factor,
7382
permutation_table: self.permutation_table,
74-
wavelengths: (self.wavelengths.a << octaves, self.wavelengths.b << octaves, self.wavelengths.c << octaves))
83+
wavelengths: self._transpose_wavelengths(self.wavelengths, octaves: octaves))
84+
}
85+
}
86+
87+
extension HashedTilingNoise where IntV == Math.IntV2
88+
{
89+
func _transpose_wavelengths(_ wavelengths:Math.IntV2, octaves:Int) -> Math.IntV2
90+
{
91+
return (wavelengths.a << octaves, wavelengths.b << octaves)
92+
}
93+
94+
func hash(point:Math.IntV2) -> Int
95+
{
96+
return self.permutation_table.hash(Math.mod(point, self.wavelengths))
97+
}
98+
}
99+
100+
extension HashedTilingNoise where IntV == Math.IntV3
101+
{
102+
func _transpose_wavelengths(_ wavelengths:Math.IntV3, octaves:Int) -> Math.IntV3
103+
{
104+
return (wavelengths.a << octaves, wavelengths.b << octaves, wavelengths.c << octaves)
105+
}
106+
107+
func hash(point:Math.IntV3) -> Int
108+
{
109+
return self.permutation_table.hash(Math.mod(point, self.wavelengths))
75110
}
76111
}
77-
*/
78112

79113
public
80114
struct RandomXorshift

tests/LinuxMain.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ try png_encode(path: "tests/disk2d.png", raw_data: pixbuf, properties: png_prope
3535

3636
benchmark(noise: CellNoise2D(amplitude: 255, frequency: 0.01), name: "cell2d")
3737
benchmark(noise: CellNoise3D(amplitude: 255, frequency: 0.01), name: "cell3d")
38+
benchmark(noise: TilingCellNoise3D(amplitude: 255, frequency: 16 / Double(viewer_size), wavelengths: 16), name: "cell_tiling3d")
3839
benchmark(noise: FBM<ClassicNoise3D>(ClassicNoise3D(amplitude: 255, frequency: 0.001), octaves: 10, persistence: 0.62), name: "classic3d", offset: 127.5)
3940
benchmark(noise: TilingClassicNoise3D(amplitude: 255, frequency: 16 / Double(viewer_size), wavelengths: 16), name: "classic_tiling3d", offset: 127.5)
4041
benchmark(noise: FBM<GradientNoise2D>(GradientNoise2D(amplitude: 180, frequency: 0.001), octaves: 10, persistence: 0.62), name: "gradient2d", offset: 127.5)

tests/cell_tiling3d.png

105 KB
Loading

0 commit comments

Comments
 (0)