q5 2.0.17 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/q5-math.js CHANGED
@@ -1,4 +1,4 @@
1
- Q5.modules.math = ($, p) => {
1
+ Q5.modules.math = ($, q) => {
2
2
  $.DEGREES = 'degrees';
3
3
  $.RADIANS = 'radians';
4
4
 
@@ -27,7 +27,7 @@ Q5.modules.math = ($, p) => {
27
27
  $.degrees = (x) => x * $._RADTODEG;
28
28
  $.radians = (x) => x * $._DEGTORAD;
29
29
 
30
- $.map = (value, istart, istop, ostart, ostop, clamp) => {
30
+ $.map = Q5.prototype.map = (value, istart, istop, ostart, ostop, clamp) => {
31
31
  let val = ostart + (ostop - ostart) * (((value - istart) * 1.0) / (istop - istart));
32
32
  if (!clamp) {
33
33
  return val;
@@ -285,7 +285,7 @@ Q5.modules.math = ($, p) => {
285
285
  let _noise;
286
286
 
287
287
  $.noiseMode = (mode) => {
288
- p.Noise = Q5[mode[0].toUpperCase() + mode.slice(1) + 'Noise'];
288
+ q.Noise = Q5[mode[0].toUpperCase() + mode.slice(1) + 'Noise'];
289
289
  _noise = null;
290
290
  };
291
291
  $.noiseSeed = (seed) => {
package/src/q5-sound.js CHANGED
@@ -1,11 +1,12 @@
1
- Q5.modules.sound = ($, p) => {
1
+ Q5.modules.sound = ($, q) => {
2
2
  $.Sound = Q5.Sound;
3
3
  $.loadSound = (path, cb) => {
4
- p._preloadCount++;
4
+ q._preloadCount++;
5
5
  Q5.aud ??= new window.AudioContext();
6
6
  let a = new Q5.Sound(path, cb);
7
7
  a.addEventListener('canplaythrough', () => {
8
- p._preloadCount--;
8
+ q._preloadCount--;
9
+ a.loaded = true;
9
10
  if (cb) cb(a);
10
11
  });
11
12
  return a;
@@ -37,4 +38,10 @@ Q5.Sound = class extends Audio {
37
38
  setPan(value) {
38
39
  this.pan = value;
39
40
  }
41
+ isLoaded() {
42
+ return this.loaded;
43
+ }
44
+ isPlaying() {
45
+ return !this.paused;
46
+ }
40
47
  };
package/src/q5-util.js CHANGED
@@ -1,6 +1,6 @@
1
- Q5.modules.util = ($, p) => {
1
+ Q5.modules.util = ($, q) => {
2
2
  $._loadFile = (path, cb, type) => {
3
- p._preloadCount++;
3
+ q._preloadCount++;
4
4
  let ret = {};
5
5
  fetch(path)
6
6
  .then((r) => {
@@ -8,7 +8,7 @@ Q5.modules.util = ($, p) => {
8
8
  if (type == 'text') return r.text();
9
9
  })
10
10
  .then((r) => {
11
- p._preloadCount--;
11
+ q._preloadCount--;
12
12
  Object.assign(ret, r);
13
13
  if (cb) cb(r);
14
14
  });
package/src/q5-vector.js CHANGED
@@ -20,7 +20,7 @@ Q5.Vector = class {
20
20
  return new Q5.Vector(this.x, this.y, this.z);
21
21
  }
22
22
  _arg2v(x, y, z) {
23
- if (x.x !== undefined) return x;
23
+ if (x?.x !== undefined) return x;
24
24
  if (y !== undefined) {
25
25
  return { x, y, z: z || 0 };
26
26
  }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * q5-webgpu
3
+ *
4
+ * EXPERIMENTAL, for developer testing only!
5
+ */
6
+ Q5.renderers.webgpu = {};
7
+
8
+ Q5.renderers.webgpu.canvas = ($, q) => {
9
+ let c = $.canvas;
10
+
11
+ c.width = $.width = 500;
12
+ c.height = $.height = 500;
13
+
14
+ if ($.colorMode) $.colorMode('rgb', 'float');
15
+
16
+ let colorsStack;
17
+
18
+ $._createCanvas = (w, h, opt) => {
19
+ q.ctx = q.drawingContext = c.getContext('webgpu');
20
+
21
+ $._canvasFormat = navigator.gpu.getPreferredCanvasFormat();
22
+ opt.format = $._canvasFormat;
23
+ opt.device = Q5.device;
24
+
25
+ $.ctx.configure(opt);
26
+
27
+ $.pipelines = [];
28
+
29
+ // pipeline changes for each draw call
30
+ $.pipelinesStack = [];
31
+
32
+ // vertices for each draw call
33
+ $.verticesStack = [];
34
+
35
+ // number of vertices for each draw call
36
+ $.drawStack = [];
37
+
38
+ // colors used for each draw call
39
+ colorsStack = $.colorsStack = [];
40
+
41
+ // current color index, used to associate a vertex with a color
42
+ $._colorIndex = -1;
43
+ };
44
+
45
+ $._resizeCanvas = (w, h) => {
46
+ $._setCanvasSize(w, h);
47
+ };
48
+
49
+ $.resetMatrix = () => {};
50
+ $.translate = () => {};
51
+
52
+ $._beginRender = () => {
53
+ $.encoder = Q5.device.createCommandEncoder();
54
+
55
+ q.pass = $.encoder.beginRenderPass({
56
+ colorAttachments: [
57
+ {
58
+ view: ctx.getCurrentTexture().createView(),
59
+ loadOp: 'clear',
60
+ storeOp: 'store'
61
+ }
62
+ ]
63
+ });
64
+ };
65
+
66
+ $._render = () => {
67
+ // run pre-render methods
68
+ for (let m of $._hooks.preRender) m();
69
+
70
+ $.pass.setPipeline($.pipelines[0]);
71
+
72
+ let drawStack = $.drawStack; // local variables used for performance
73
+ let o = 0; // vertex offset
74
+ for (let i = 0; i < drawStack.length; i++) {
75
+ $.pass.draw(drawStack[i], 1, o, 0);
76
+ o += drawStack[i];
77
+ }
78
+ };
79
+
80
+ $._finishRender = () => {
81
+ $.pass.end();
82
+ const commandBuffer = $.encoder.finish();
83
+ Q5.device.queue.submit([commandBuffer]);
84
+ q.pass = $.encoder = null;
85
+
86
+ // clear the stacks for the next frame
87
+ $.verticesStack.length = 0;
88
+ $.drawStack.length = 0;
89
+ $.colorsStack.length = 0;
90
+ $.pipelinesStack.length = 0;
91
+ $._colorIndex = -1;
92
+ };
93
+
94
+ $.fill = (r, g, b, a = 1) => {
95
+ // grayscale mode `fill(1, 0.5)`
96
+ if (b == undefined) {
97
+ a = g;
98
+ g = b = r;
99
+ }
100
+ let levels;
101
+ if (r._q5Color) levels = r.levels;
102
+ else levels = [r, g, b, a];
103
+
104
+ colorsStack.push(...levels);
105
+ $._colorIndex++;
106
+ };
107
+ };
108
+
109
+ Q5.webgpu = async function (scope, parent) {
110
+ if (!navigator.gpu) {
111
+ console.error('q5 WebGPU not supported on this browser!');
112
+ return new Q5(scope, parent);
113
+ }
114
+ let adapter = await navigator.gpu.requestAdapter();
115
+ if (!adapter) throw new Error('No appropriate GPUAdapter found.');
116
+ Q5.device = await adapter.requestDevice();
117
+
118
+ return new Q5(scope, parent, 'webgpu');
119
+ };
@@ -0,0 +1,281 @@
1
+ Q5.renderers.webgpu.drawing = ($, q) => {
2
+ $.CLOSE = 1;
3
+
4
+ let verticesStack, drawStack, colorsStack;
5
+
6
+ $._hooks.postCanvas.push(() => {
7
+ verticesStack = $.verticesStack;
8
+ drawStack = $.drawStack;
9
+ colorsStack = $.colorsStack;
10
+
11
+ let vertexBufferLayout = {
12
+ arrayStride: 12, // 2 coordinates + 1 color index * 4 bytes each
13
+ attributes: [
14
+ {
15
+ format: 'float32x2',
16
+ offset: 0,
17
+ shaderLocation: 0 // position
18
+ },
19
+ {
20
+ format: 'float32',
21
+ offset: 8,
22
+ shaderLocation: 1 // colorIndex
23
+ }
24
+ ]
25
+ };
26
+
27
+ let vertexShader = Q5.device.createShaderModule({
28
+ code: `
29
+ struct VertexOutput {
30
+ @builtin(position) position: vec4<f32>,
31
+ @location(1) colorIndex: f32
32
+ };
33
+
34
+ @vertex
35
+ fn vertexMain(@location(0) pos: vec2<f32>, @location(1) colorIndex: f32) -> VertexOutput {
36
+ var output: VertexOutput;
37
+ output.position = vec4<f32>(pos, 0.0, 1.0);
38
+ output.colorIndex = colorIndex;
39
+ return output;
40
+ }
41
+ `
42
+ });
43
+
44
+ let fragmentShader = Q5.device.createShaderModule({
45
+ code: `
46
+ @group(0) @binding(0) var<storage, read> uColors : array<vec4<f32>>;
47
+
48
+ @fragment
49
+ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4<f32> {
50
+ let index = u32(colorIndex);
51
+ return mix(uColors[index], uColors[index + 1u], fract(colorIndex));
52
+ }
53
+ `
54
+ });
55
+
56
+ let bindGroupLayout = Q5.device.createBindGroupLayout({
57
+ entries: [
58
+ {
59
+ binding: 0,
60
+ visibility: GPUShaderStage.FRAGMENT,
61
+ buffer: {
62
+ type: 'read-only-storage',
63
+ hasDynamicOffset: false
64
+ }
65
+ }
66
+ ]
67
+ });
68
+
69
+ let pipelineLayout = Q5.device.createPipelineLayout({
70
+ bindGroupLayouts: [bindGroupLayout]
71
+ });
72
+
73
+ $.pipelines[0] = Q5.device.createRenderPipeline({
74
+ layout: pipelineLayout,
75
+ vertex: {
76
+ module: vertexShader,
77
+ entryPoint: 'vertexMain',
78
+ buffers: [vertexBufferLayout]
79
+ },
80
+ fragment: {
81
+ module: fragmentShader,
82
+ entryPoint: 'fragmentMain',
83
+ targets: [
84
+ {
85
+ format: $._canvasFormat
86
+ }
87
+ ]
88
+ },
89
+ primitive: {
90
+ topology: 'triangle-list'
91
+ }
92
+ });
93
+ });
94
+
95
+ let shapeVertices;
96
+
97
+ $.beginShape = () => {
98
+ shapeVertices = [];
99
+ };
100
+
101
+ $.vertex = (x, y) => {
102
+ shapeVertices.push(x / $.canvas.hw, -y / $.canvas.hh, $._colorIndex);
103
+ };
104
+
105
+ $.endShape = (close) => {
106
+ if (shapeVertices.length < 6) {
107
+ throw new Error('A shape must have at least 3 vertices.');
108
+ }
109
+ if (close) {
110
+ // Close the shape by adding the first vertex at the end
111
+ shapeVertices.push(shapeVertices[0], shapeVertices[1], shapeVertices[2]);
112
+ }
113
+ // Convert the shape to triangles
114
+ let triangles = [];
115
+ for (let i = 3; i < shapeVertices.length; i += 3) {
116
+ triangles.push(
117
+ shapeVertices[0],
118
+ shapeVertices[1],
119
+ shapeVertices[2], // First vertex
120
+ shapeVertices[i - 3],
121
+ shapeVertices[i - 2],
122
+ shapeVertices[i - 1], // Previous vertex
123
+ shapeVertices[i],
124
+ shapeVertices[i + 1],
125
+ shapeVertices[i + 2] // Current vertex
126
+ );
127
+ }
128
+
129
+ verticesStack.push(...triangles);
130
+ drawStack.push(triangles.length / 3);
131
+ shapeVertices = [];
132
+ };
133
+
134
+ $.triangle = (x1, y1, x2, y2, x3, y3) => {
135
+ $.beginShape();
136
+ $.vertex(x1, y1);
137
+ $.vertex(x2, y2);
138
+ $.vertex(x3, y3);
139
+ $.endShape(1);
140
+ };
141
+
142
+ $.rect = (x, y, w, h) => {
143
+ let hw = w / 2;
144
+ let hh = h / 2;
145
+ // convert the coordinates from pixel space to NDC space
146
+ let left = (x - hw) / $.canvas.hw;
147
+ let right = (x + hw) / $.canvas.hw;
148
+ let top = -(y - hh) / $.canvas.hh; // y is inverted in WebGPU
149
+ let bottom = -(y + hh) / $.canvas.hh; // y is inverted in WebGPU
150
+
151
+ let ci = $._colorIndex;
152
+ // two triangles make a rectangle
153
+ verticesStack.push(
154
+ left,
155
+ top,
156
+ ci,
157
+ right,
158
+ top,
159
+ ci,
160
+ left,
161
+ bottom,
162
+ ci,
163
+ right,
164
+ top,
165
+ ci,
166
+ left,
167
+ bottom,
168
+ ci,
169
+ right,
170
+ bottom,
171
+ ci
172
+ );
173
+ drawStack.push(6);
174
+ };
175
+
176
+ /**
177
+ * Derived from: ceil(Math.log(d) * 7) * 2 - ceil(28)
178
+ * This lookup table is used for better performance.
179
+ * @param {Number} d diameter of the circle
180
+ * @returns n number of segments
181
+ */
182
+ // prettier-ignore
183
+ const getArcSegments = (d) =>
184
+ d < 14 ? 8 :
185
+ d < 16 ? 10 :
186
+ d < 18 ? 12 :
187
+ d < 20 ? 14 :
188
+ d < 22 ? 16 :
189
+ d < 24 ? 18 :
190
+ d < 28 ? 20 :
191
+ d < 34 ? 22 :
192
+ d < 42 ? 24 :
193
+ d < 48 ? 26 :
194
+ d < 56 ? 28 :
195
+ d < 64 ? 30 :
196
+ d < 72 ? 32 :
197
+ d < 84 ? 34 :
198
+ d < 96 ? 36 :
199
+ d < 98 ? 38 :
200
+ d < 113 ? 40 :
201
+ d < 149 ? 44 :
202
+ d < 199 ? 48 :
203
+ d < 261 ? 52 :
204
+ d < 353 ? 56 :
205
+ d < 461 ? 60 :
206
+ d < 585 ? 64 :
207
+ d < 1200 ? 70 :
208
+ d < 1800 ? 80 :
209
+ d < 2400 ? 90 :
210
+ 100;
211
+
212
+ $.ellipse = (x, y, w, h) => {
213
+ const n = getArcSegments(w == h ? w : Math.max(w, h));
214
+
215
+ let a = Math.max(w, 1) / 2;
216
+ let b = w == h ? a : Math.max(h, 1) / 2;
217
+
218
+ x /= $.canvas.hw;
219
+ y /= -$.canvas.hh;
220
+ a /= $.canvas.hw;
221
+ b /= -$.canvas.hh;
222
+
223
+ let t = 0; // theta
224
+ const angleIncrement = $.TAU / n;
225
+ const ci = $._colorIndex;
226
+ let vx1, vy1, vx2, vy2;
227
+ for (let i = 0; i <= n; i++) {
228
+ vx1 = vx2;
229
+ vy1 = vy2;
230
+ vx2 = x + a * Math.cos(t);
231
+ vy2 = y + b * Math.sin(t);
232
+ t += angleIncrement;
233
+
234
+ if (i == 0) continue;
235
+
236
+ verticesStack.push(x, y, ci, vx1, vy1, ci, vx2, vy2, ci);
237
+ }
238
+
239
+ drawStack.push(n * 3);
240
+ };
241
+
242
+ $.circle = (x, y, d) => $.ellipse(x, y, d, d);
243
+
244
+ $.noStroke = () => {};
245
+
246
+ $.background = () => {};
247
+
248
+ $._hooks.preRender.push(() => {
249
+ const vertexBuffer = Q5.device.createBuffer({
250
+ size: verticesStack.length * 6,
251
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
252
+ });
253
+
254
+ Q5.device.queue.writeBuffer(vertexBuffer, 0, new Float32Array(verticesStack));
255
+ $.pass.setVertexBuffer(0, vertexBuffer);
256
+
257
+ const colorBuffer = Q5.device.createBuffer({
258
+ size: colorsStack.length * 4,
259
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
260
+ });
261
+
262
+ Q5.device.queue.writeBuffer(colorBuffer, 0, new Float32Array(colorsStack));
263
+
264
+ const bindGroup = Q5.device.createBindGroup({
265
+ layout: $.pipelines[0].getBindGroupLayout(0),
266
+ entries: [
267
+ {
268
+ binding: 0,
269
+ resource: {
270
+ buffer: colorBuffer,
271
+ offset: 0,
272
+ size: colorsStack.length * 4
273
+ }
274
+ }
275
+ ]
276
+ });
277
+
278
+ // set the bind group once before rendering
279
+ $.pass.setBindGroup(0, bindGroup);
280
+ });
281
+ };
@@ -0,0 +1 @@
1
+ Q5.renderers.webgpu.image = ($, q) => {};
@@ -0,0 +1 @@
1
+ Q5.renderers.webgpu.text = ($, q) => {};
package/src/readme.md CHANGED
@@ -32,12 +32,39 @@ Additional modules:
32
32
  <script src="https://q5js.org/src/q5-sensors.js"></script>
33
33
  ```
34
34
 
35
+ WebGPU rendering modules are in development:
36
+
37
+ ```html
38
+ <script src="https://q5js.org/src/q5-webgpu-canvas.js"></script>
39
+ <script src="https://q5js.org/src/q5-webgpu-drawing.js"></script>
40
+ ```
41
+
35
42
  # Module Info
36
43
 
44
+ - [Modular Use](#modular-use)
45
+ - [Module Info](#module-info)
46
+ - [core](#core)
47
+ - [canvas](#canvas)
48
+ - [q2d-canvas](#q2d-canvas)
49
+ - [q2d-drawing](#q2d-drawing)
50
+ - [q2d-image](#q2d-image)
51
+ - [q2d-soft-filters](#q2d-soft-filters)
52
+ - [q2d-text](#q2d-text)
53
+ - [webgpu-canvas](#webgpu-canvas)
54
+ - [webgpu-drawing](#webgpu-drawing)
55
+ - [math](#math)
56
+ - [noisier](#noisier)
57
+
37
58
  ## core
38
59
 
39
60
  The core module provides the absolute basic functionality necessary to run q5.
40
61
 
62
+ It loads other modules by passing `$` (alias for `this`) and `q` (which in global mode is a proxy for `this` and `window` or `global`).
63
+
64
+ ## canvas
65
+
66
+ The canvas module provides shared functionality for all canvas renderers, such as adding the canvas to the DOM, resizing the canvas, setting pixel density,
67
+
41
68
  ## q2d-canvas
42
69
 
43
70
  Adds canvas 2D rendering support to q5.
@@ -60,27 +87,77 @@ The filters in q5-image use the [CanvasRenderingContext2D.filter](https://develo
60
87
 
61
88
  Software implementation of image filters.
62
89
 
63
- This module includes additional filters not implemented in q5-image and legacy filter support for Safari which lacks ctx.filter.
90
+ This module includes additional filters not implemented in q5-image and legacy filter support for Safari which lacks `ctx.filter`.
64
91
 
65
- These filters are slow, real-time use of them is not recommended.
92
+ These filters are slow. Real-time use of them is not recommended.
66
93
 
67
- As of April 2024, Safari Technology Preview supports ctx.filter under a flag. Hopefully in the near future mainline Safari will support ctx.filter and this module can be omitted from the default bundle.
94
+ As of April 2024, Safari Technology Preview supports `ctx.filter` under a flag. Hopefully in the near future this module can be omitted from the default bundle.
68
95
 
69
96
  ## q2d-text
70
97
 
71
98
  Adds canvas 2D text rendering support to q5.
72
99
 
100
+ Image based features in this module require the q5-2d-image module.
101
+
73
102
  `createTextImage(str, w, h)` provides a simple way for users to create images from text.
74
103
 
75
104
  `textImage(img, x, y)` displays text images, complying with the user's text position settings instead of their image position settings. The idea is that text will appear in the same place as it would if it were drawn with the `text` function.
76
105
 
77
106
  `textCache(bool, maxSize)` enables or disables text caching. As of June 2024, drawing rotated text is super slow in all browsers, so q5 creates and stores images of text and rotates that instead. Can improve rendering performance 90x but uses more memory. `maxSize` param determines the maximum number of text images to cache, default is 500 since these images will typically be quite small. The text image cache (tic) is a timed cache, so the oldest images are removed first.
78
107
 
79
- Of course, use of these image based features requires the q5-2d-image module.
108
+ ## webgpu-canvas
109
+
110
+ > ⚠️ Experimental features! ⚠️
111
+
112
+ This module adds WebGPU rendering support to q5.
113
+
114
+ Instead of `new Q5()`, run the async function `Q5.webgpu()`. Explicit use of `createCanvas` is required.
115
+
116
+ ```js
117
+ let q = await Q5.webgpu();
118
+
119
+ createCanvas(500, 500);
120
+ ```
121
+
122
+ Set the script type of your sketch to "module" to use `await` on the top level.
123
+
124
+ ```html
125
+ <script type="module" src="sketch.js"></script>
126
+ ```
127
+
128
+ Using q5 with the webgpu renderer requires a different approach to setting up sketches. That's because variables and functions declared in a module are not added to the global `window` object.
129
+
130
+ Add functions like `setup` and `draw` as properties of `q`, the instance of Q5.
131
+
132
+ ```js
133
+ q.draw = function () {
134
+ // draw stuff
135
+ };
136
+ ```
137
+
138
+ Implemented functions:
139
+
140
+ `createCanvas`, `resizeCanvas`
141
+
142
+ ## webgpu-drawing
143
+
144
+ > Uses `colorMode('rgb', 'float')` by default. Changing it to 'oklch' is not supported yet for the webgpu renderer.
145
+
146
+ > All basic shapes are drawn from their center. Strokes are not implemented yet.
147
+
148
+ q5's WebGPU renderer drawing functions like `rect` don't actually draw anything to the canvas. Instead, they prepare vertex and color data to be sent to the GPU in bulk, which occurs after the user's `draw` function and any post-draw addon functions are run. This approach better utilizes the GPU, so it doesn't have to repeatedly wait for the CPU to send small chunks of data that describe each individual shape. It's why webgpu is typically 2-3x faster than canvas 2d.
149
+
150
+ Hooks into the q5-core `draw` loop were added to support webgpu rendering: `_beginRender`, `_render`, `_finishRender`.
151
+
152
+ The current implementation is provided to give developers a taste of what q5 programming will be like with webgpu. Significant changes need to be made to support transformations such as rotation and scaling.
153
+
154
+ Implemented functions:
155
+
156
+ `fill`, `rect`, `circle`, `ellipse`, `triangle`, `beginShape`, `vertex`, `endShape`
80
157
 
81
158
  ## math
82
159
 
83
- `PerlinNoise` is q5's default noise algorithm. Kevin Perlin won an Academy Award for his work on the original algorithm for the 1982 movie Tron. q5's JavaScript implementation was authored by Tezumie.
160
+ `PerlinNoise` is q5's default noise algorithm. Kevin Perlin won an Academy Award for his work on the original algorithm for the 1982 movie Tron. The JavaScript implementation of it in q5 was authored by Tezumie.
84
161
 
85
162
  `noiseMode` enables users to switch between noise algorithms, although only "perlin" is included in q5-math.
86
163
 
@@ -90,4 +167,4 @@ Adds additional noise functions to q5.
90
167
 
91
168
  `SimplexNoise` is a simplex noise implementation in JavaScript by Tezumie. Kevin Perlin's patent on simplex noise expired in 2022. Simplex noise is slightly faster but arguably less visually appealing than perlin noise.
92
169
 
93
- `BlockyNoise` is similar to p5's default `noise` function, which is a bit notorious in the gen art community for not actually being perlin noise, despite its claims to be. It looks closer to value noise but is not a standard implementation of that either. It's a bit blocky at 1 octave, hence the name.
170
+ `BlockyNoise` is similar to p5's default `noise` function, which is a bit notorious in the gen art community for not actually being perlin noise, despite its claims to be. It looks closer to value noise but is not a standard implementation of that either. When visualized in 2d it's a bit blocky at 1 octave, hence the name.