Skip to content

Commit d82995c

Browse files
MaxGraeydcodeIO
authored andcommitted
Improve mandelbort example (AssemblyScript#308)
1 parent 2ec89ee commit d82995c

File tree

8 files changed

+859
-351
lines changed

8 files changed

+859
-351
lines changed

examples/mandelbrot/assembly/index.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,47 @@ const NUM_COLORS = 2048;
55

66
/** Computes a single line in the rectangle `width` x `height`. */
77
export function computeLine(y: u32, width: u32, height: u32, limit: u32): void {
8-
var translateX = width / 1.6;
9-
var translateY = height / 2.0;
10-
var scale = 10.0 / min(3 * width, 4 * height);
11-
var imaginary = (y - translateY) * scale;
8+
var translateX = width * (1.0 / 1.6);
9+
var translateY = height * (1.0 / 2.0);
10+
var scale = 10.0 / min(3 * width, 4 * height);
11+
var imaginary = (y - translateY) * scale;
12+
var realOffset = translateX * scale;
13+
var stride = (y * width) << 1;
14+
var invLimit = 1.0 / limit;
15+
16+
var minIterations = min(8, limit);
17+
1218
for (let x: u32 = 0; x < width; ++x) {
13-
let real = (x - translateX) * scale;
19+
let real = x * scale - realOffset;
1420

1521
// Iterate until either the escape radius or iteration limit is exceeded
1622
let ix = 0.0, iy = 0.0, ixSq: f64, iySq: f64;
1723
let iteration: u32 = 0;
1824
while ((ixSq = ix * ix) + (iySq = iy * iy) <= 4.0) {
19-
let ixNew = ixSq - iySq + real;
2025
iy = 2.0 * ix * iy + imaginary;
21-
ix = ixNew;
26+
ix = ixSq - iySq + real;
2227
if (iteration >= limit) break;
2328
++iteration;
2429
}
2530

2631
// Do a few extra iterations for quick escapes to reduce error margin
27-
for (let minIterations = min(8, limit); iteration < minIterations; ++iteration) {
32+
while (iteration < minIterations) {
2833
let ixNew = ix * ix - iy * iy + real;
2934
iy = 2.0 * ix * iy + imaginary;
3035
ix = ixNew;
36+
++iteration;
3137
}
3238

3339
// Iteration count is a discrete value in the range [0, limit] here, but we'd like it to be
3440
// normalized in the range [0, 2047] so it maps to the gradient computed in JS.
3541
// see also: http://linas.org/art-gallery/escape/escape.html
36-
let frac = Math.log(Math.log(Math.sqrt(ix * ix + iy * iy))) / Math.LN2;
37-
let icol = isFinite(frac)
38-
? <u32>((NUM_COLORS - 1) * clamp((iteration + 1 - frac) / limit, 0.0, 1.0))
39-
: NUM_COLORS - 1;
40-
store<u16>((y * width + x) << 1, icol);
42+
let col = NUM_COLORS - 1;
43+
let sqd = ix * ix + iy * iy;
44+
if (sqd > 1.0) {
45+
let frac = Math.log2(0.5 * Math.log(sqd));
46+
col = <u32>((NUM_COLORS - 1) * clamp((iteration + 1 - frac) * invLimit, 0.0, 1.0));
47+
}
48+
store<u16>(stride + (x << 1), col);
4149
}
4250
}
4351

15 Bytes
Binary file not shown.

examples/mandelbrot/build/optimized.wat

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
(type $FF (func (param f64) (result f64)))
44
(type $v (func))
55
(import "env" "memory" (memory $0 0))
6-
(import "Math" "LN2" (global $~lib/bindings/Math/LN2 f64))
7-
(import "Math" "sqrt" (func $~lib/bindings/Math/sqrt (param f64) (result f64)))
86
(import "Math" "log" (func $~lib/bindings/Math/log (param f64) (result f64)))
7+
(import "Math" "log2" (func $~lib/bindings/Math/log2 (param f64) (result f64)))
98
(table $0 1 anyfunc)
109
(elem (i32.const 0) $null)
1110
(export "memory" (memory $0))
@@ -21,15 +20,13 @@
2120
(local $10 f64)
2221
(local $11 f64)
2322
(local $12 f64)
24-
get_local $1
25-
f64.convert_u/i32
26-
tee_local $6
27-
f64.const 1.6
28-
f64.div
29-
set_local $12
23+
(local $13 f64)
24+
(local $14 f64)
3025
f64.const 10
3126
f64.const 3
32-
get_local $6
27+
get_local $1
28+
f64.convert_u/i32
29+
tee_local $8
3330
f64.mul
3431
f64.const 4
3532
get_local $2
@@ -42,23 +39,45 @@
4239
get_local $0
4340
f64.convert_u/i32
4441
get_local $4
45-
f64.const 2
46-
f64.div
42+
f64.const 0.5
43+
f64.mul
4744
f64.sub
4845
get_local $9
4946
f64.mul
5047
set_local $10
48+
get_local $8
49+
f64.const 0.625
50+
f64.mul
51+
get_local $9
52+
f64.mul
53+
set_local $12
54+
get_local $0
55+
get_local $1
56+
i32.mul
57+
i32.const 1
58+
i32.shl
59+
set_local $0
60+
f64.const 1
61+
get_local $3
62+
f64.convert_u/i32
63+
tee_local $6
64+
f64.div
65+
set_local $13
66+
f64.const 8
67+
get_local $6
68+
f64.min
69+
set_local $8
5170
loop $repeat|0
5271
get_local $7
5372
get_local $1
5473
i32.lt_u
5574
if
5675
get_local $7
5776
f64.convert_u/i32
58-
get_local $12
59-
f64.sub
6077
get_local $9
6178
f64.mul
79+
get_local $12
80+
f64.sub
6281
set_local $11
6382
f64.const 0
6483
set_local $4
@@ -70,11 +89,11 @@
7089
get_local $4
7190
get_local $4
7291
f64.mul
73-
tee_local $6
92+
tee_local $14
7493
get_local $5
7594
get_local $5
7695
f64.mul
77-
tee_local $8
96+
tee_local $6
7897
f64.add
7998
f64.const 4
8099
f64.le
@@ -88,8 +107,8 @@
88107
get_local $10
89108
f64.add
90109
set_local $5
110+
get_local $14
91111
get_local $6
92-
get_local $8
93112
f64.sub
94113
get_local $11
95114
f64.add
@@ -106,15 +125,10 @@
106125
end
107126
end
108127
end
109-
f64.const 8
110-
get_local $3
111-
f64.convert_u/i32
112-
f64.min
113-
set_local $6
114-
loop $repeat|2
128+
loop $continue|2
115129
get_local $2
116130
f64.convert_u/i32
117-
get_local $6
131+
get_local $8
118132
f64.lt
119133
if
120134
get_local $4
@@ -126,7 +140,7 @@
126140
f64.sub
127141
get_local $11
128142
f64.add
129-
set_local $8
143+
set_local $6
130144
f64.const 2
131145
get_local $4
132146
f64.mul
@@ -135,50 +149,44 @@
135149
get_local $10
136150
f64.add
137151
set_local $5
138-
get_local $8
152+
get_local $6
139153
set_local $4
140154
get_local $2
141155
i32.const 1
142156
i32.add
143157
set_local $2
144-
br $repeat|2
158+
br $continue|2
145159
end
146160
end
147-
get_local $0
148-
get_local $1
149-
i32.mul
150161
get_local $7
151-
i32.add
152162
i32.const 1
153163
i32.shl
164+
get_local $0
165+
i32.add
154166
get_local $4
155167
get_local $4
156168
f64.mul
157169
get_local $5
158170
get_local $5
159171
f64.mul
160172
f64.add
161-
call $~lib/bindings/Math/sqrt
162-
call $~lib/bindings/Math/log
163-
call $~lib/bindings/Math/log
164-
get_global $~lib/bindings/Math/LN2
165-
f64.div
166173
tee_local $6
167-
get_local $6
168-
f64.sub
169-
f64.const 0
170-
f64.eq
174+
f64.const 1
175+
f64.gt
171176
if (result i32)
172177
f64.const 2047
173178
get_local $2
174179
i32.const 1
175180
i32.add
176181
f64.convert_u/i32
182+
f64.const 0.5
177183
get_local $6
184+
call $~lib/bindings/Math/log
185+
f64.mul
186+
call $~lib/bindings/Math/log2
178187
f64.sub
179-
get_local $3
180-
f64.convert_u/i32
181-
f64.div
188+
get_local $13
189+
f64.mul
182190
f64.const 0
183191
f64.max
184192
f64.const 1

0 commit comments

Comments
 (0)