@@ -21,13 +21,13 @@ func write_rgb_png(path:String, width:Int, height:Int, pixbuf:[UInt8])
21
21
}
22
22
23
23
func color_noise_png( r_noise: Noise , g_noise: Noise , b_noise: Noise ,
24
- width: Int , height: Int , value_offset: Double , invert: Bool = false , path: String )
24
+ width: Int , height: Int , value_offset: ( r : Double , g : Double , b : Double ) , invert: Bool = false , path: String )
25
25
{
26
26
var pixbuf : [ UInt8 ] = [ ]
27
27
pixbuf. reserveCapacity ( 3 * width * height)
28
- for (r, ( g, b) ) in zip ( r_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset) ,
29
- zip ( g_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset) ,
30
- b_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset) ) )
28
+ for (r, ( g, b) ) in zip ( r_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset. r ) ,
29
+ zip ( g_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset. g ) ,
30
+ b_noise. sample_area_saturated_to_u8 ( width: width, height: height, offset: value_offset. b ) ) )
31
31
{
32
32
if invert
33
33
{
@@ -53,7 +53,7 @@ func banner_simplex2d(width:Int, height:Int, seed:Int)
53
53
b_noise: SimplexNoise2D ( amplitude: 0.5 * 255 , frequency: 0.00375 , seed: seed + 2 ) ,
54
54
width: width,
55
55
height: height,
56
- value_offset: 0.65 * 255 ,
56
+ value_offset: ( 0.65 * 255 , 0.65 * 255 , 0.65 * 255 ) ,
57
57
path: " tests/banner_simplex2d.png " )
58
58
}
59
59
@@ -64,7 +64,7 @@ func banner_supersimplex2d(width:Int, height:Int, seed:Int)
64
64
b_noise: SuperSimplexNoise2D ( amplitude: 0.5 * 255 , frequency: 0.0025 , seed: seed + 2 ) ,
65
65
width: width,
66
66
height: height,
67
- value_offset: 0.65 * 255 ,
67
+ value_offset: ( 0.65 * 255 , 0.65 * 255 , 0.65 * 255 ) ,
68
68
path: " tests/banner_supersimplex2d.png " )
69
69
}
70
70
@@ -75,7 +75,7 @@ func banner_supersimplex3d(width:Int, height:Int, seed:Int)
75
75
b_noise: SuperSimplexNoise3D ( amplitude: 0.5 * 255 , frequency: 0.0025 , seed: seed + 2 ) ,
76
76
width: width,
77
77
height: height,
78
- value_offset: 0.65 * 255 ,
78
+ value_offset: ( 0.65 * 255 , 0.65 * 255 , 0.65 * 255 ) ,
79
79
path: " tests/banner_supersimplex3d.png " )
80
80
}
81
81
@@ -86,7 +86,7 @@ func banner_cell2d(width:Int, height:Int, seed:Int)
86
86
b_noise: CellNoise2D ( amplitude: 3 * 255 , frequency: 0.0075 , seed: seed + 2 ) ,
87
87
width: width,
88
88
height: height,
89
- value_offset: 0 ,
89
+ value_offset: ( 0 , 0 , 0 ) ,
90
90
invert: true ,
91
91
path: " tests/banner_cell2d.png " )
92
92
}
@@ -98,11 +98,23 @@ func banner_cell3d(width:Int, height:Int, seed:Int)
98
98
b_noise: CellNoise3D ( amplitude: 3 * 255 , frequency: 0.0075 , seed: seed + 2 ) ,
99
99
width: width,
100
100
height: height,
101
- value_offset: 0 ,
101
+ value_offset: ( 0 , 0 , 0 ) ,
102
102
invert: true ,
103
103
path: " tests/banner_cell3d.png " )
104
104
}
105
105
106
+ func banner_FBM( width: Int , height: Int , seed: Int )
107
+ {
108
+ color_noise_png ( r_noise: FBM < CellNoise3D > ( amplitude: 2.7 * 255 , frequency: 0.01 , octaves: 7 , seed: seed + 2 ) ,
109
+ g_noise: FBM < SuperSimplexNoise3D > ( amplitude: 255 / 3 , frequency: 0.005 , octaves: 7 , seed: seed + 1 ) ,
110
+ b_noise: FBM < SimplexNoise2D > ( amplitude: 255 / 3 , frequency: 0.03 , octaves: 7 , seed: seed) ,
111
+ width: width,
112
+ height: height,
113
+ value_offset: ( 0 , 150 , 150 ) ,
114
+ invert: false ,
115
+ path: " tests/banner_FBM.png " )
116
+ }
117
+
106
118
func circle_at( cx: Double , cy: Double , r: Double , width: Int , height: Int , _ f: ( Int , Int , Double ) -> ( ) )
107
119
{
108
120
// get bounding box
@@ -130,29 +142,92 @@ func banner_disk2d(width:Int, height:Int, seed:Int)
130
142
var pixbuf : [ UInt8 ] = [ UInt8] ( repeating: 255 , count: 3 * width * height)
131
143
132
144
let points = poisson. generate ( radius: 20 , width: width, height: height, k: 80 )
133
- for point : ( x: Double , y: Double ) in points
145
+
146
+ @inline ( __always)
147
+ func _dots( _ points: [ ( x: Double , y: Double ) ] , color: ( r: UInt8 , g: UInt8 , b: UInt8 ) )
134
148
{
135
- circle_at ( cx : point. x , cy : point . y , r : 5 , width : width , height : height ,
149
+ for point : ( x : Double , y : Double ) in points
136
150
{
137
- ( x: Int , y: Int , v: Double ) in
138
-
139
- let base_addr : Int = 3 * ( y * width + x)
140
- pixbuf [ base_addr + 1 ] = pixbuf [ base_addr + 1 ] &- UInt8 ( 255 * v)
141
- } )
151
+ circle_at ( cx: point. x, cy: point. y, r: 10 , width: width, height: height,
152
+ {
153
+ ( x: Int , y: Int , v: Double ) in
154
+
155
+ let base_addr : Int = 3 * ( y * width + x)
156
+ pixbuf [ base_addr ] = UInt8 ( clamping: Int ( pixbuf [ base_addr ] ) - Int( Double ( color. r) * v) )
157
+ pixbuf [ base_addr + 1 ] = UInt8 ( clamping: Int ( pixbuf [ base_addr + 1 ] ) - Int( Double ( color. g) * v) )
158
+ pixbuf [ base_addr + 2 ] = UInt8 ( clamping: Int ( pixbuf [ base_addr + 2 ] ) - Int( Double ( color. b) * v) )
159
+ } )
160
+ }
142
161
}
143
162
163
+ _dots ( poisson. generate ( radius: 35 , width: width, height: height, k: 80 , seed: ( 10 , 10 ) ) , color: ( 0 , 210 , 70 ) )
164
+ _dots ( poisson. generate ( radius: 25 , width: width, height: height, k: 80 , seed: ( 45 , 15 ) ) , color: ( 0 , 10 , 235 ) )
165
+ _dots ( poisson. generate ( radius: 30 , width: width, height: height, k: 80 , seed: ( 15 , 45 ) ) , color: ( 225 , 20 , 0 ) )
166
+
144
167
write_rgb_png ( path: " tests/banner_disk2d.png " , width: width, height: height, pixbuf: pixbuf)
145
168
}
146
169
170
+ func banner_voronoi2d( width: Int , height: Int , seed: Int )
171
+ {
172
+ let voronoi = CellNoise2D ( amplitude: 255 , frequency: 0.025 , seed: seed)
173
+ var pixbuf : [ UInt8 ] = [ UInt8] ( repeating: 0 , count: 3 * width * height)
174
+
175
+ let r : PermutationTable = PermutationTable ( seed: seed) ,
176
+ g : PermutationTable = PermutationTable ( seed: seed + 1 ) ,
177
+ b : PermutationTable = PermutationTable ( seed: seed + 2 )
178
+
179
+ var base_addr : Int = 0
180
+ for y in 0 ..< height
181
+ {
182
+ for x in 0 ..< width
183
+ {
184
+ @inline ( __always)
185
+ func _supersample( _ x: Double , _ y: Double ) -> ( r: UInt8 , g: UInt8 , b: UInt8 )
186
+ {
187
+ let ( point, _) : ( ( Int , Int ) , Double ) = voronoi. closest_point ( Double ( x) , Double ( y) )
188
+ let r : UInt8 = r. hash ( point. 0 , point. 1 ) ,
189
+ g : UInt8 = g. hash ( point. 0 , point. 1 ) ,
190
+ b : UInt8 = b. hash ( point. 0 , point. 1 ) ,
191
+ peak : UInt8 = max ( r, max ( g, b) ) ,
192
+ saturate : Double = Double ( UInt8 . max) / Double( peak)
193
+ return ( UInt8 ( Double ( r) * saturate) , UInt8 ( Double ( g) * saturate) , UInt8 ( Double ( b) * saturate) )
194
+ }
195
+
196
+ var r : Int = 0 ,
197
+ g : Int = 0 ,
198
+ b : Int = 0
199
+ let supersamples : [ ( Double , Double ) ] = [ ( 0 , 0 ) , ( 0 , 0.4 ) , ( 0.4 , 0 ) , ( - 0.4 , 0 ) , ( 0 , - 0.4 ) ,
200
+ ( - 0.25 , - 0.25 ) , ( 0.25 , 0.25 ) , ( - 0.25 , 0.25 ) , ( 0.25 , - 0.25 ) ]
201
+ for (dx, dy) in supersamples
202
+ {
203
+ let contribution : ( r: UInt8 , g: UInt8 , b: UInt8 ) = _supersample ( Double ( x) + dx, Double ( y) + dy)
204
+ r += Int ( contribution. r)
205
+ g += Int ( contribution. g)
206
+ b += Int ( contribution. b)
207
+ }
208
+ pixbuf [ base_addr ] = UInt8 ( r / supersamples. count)
209
+ pixbuf [ base_addr + 1 ] = UInt8 ( g / supersamples. count)
210
+ pixbuf [ base_addr + 2 ] = UInt8 ( b / supersamples. count)
211
+
212
+ base_addr += 3
213
+ }
214
+ }
215
+
216
+ write_rgb_png ( path: " tests/banner_voronoi2d.png " , width: width, height: height, pixbuf: pixbuf)
217
+ }
218
+
147
219
public
148
220
func banners( width: Int , ratio: Double )
149
221
{
150
222
let height : Int = Int ( Double ( width) / ratio)
151
- banner_simplex2d ( width: width, height: height, seed: 5 )
223
+ banner_simplex2d ( width: width, height: height, seed: 5 )
152
224
banner_supersimplex2d ( width: width, height: height, seed: 8 )
153
225
banner_supersimplex3d ( width: width, height: height, seed: 0 )
154
- banner_cell2d ( width: width, height: height, seed: 0 )
155
- banner_cell3d ( width: width, height: height, seed: 0 )
226
+ banner_cell2d ( width: width, height: height, seed: 0 )
227
+ banner_cell3d ( width: width, height: height, seed: 0 )
228
+ banner_voronoi2d ( width: width, height: height, seed: 3 )
229
+
230
+ banner_FBM ( width: width, height: height, seed: 0 )
156
231
157
- banner_disk2d ( width: width, height: height, seed: 0 )
232
+ banner_disk2d ( width: width, height: height, seed: 0 )
158
233
}
0 commit comments