p5 2.2.1 → 2.2.2-rc.1
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/dist/accessibility/color_namer.js +6 -6
- package/dist/accessibility/index.js +6 -6
- package/dist/app.js +6 -6
- package/dist/color/color_conversion.js +6 -6
- package/dist/color/creating_reading.js +1 -1
- package/dist/color/index.js +2 -2
- package/dist/color/p5.Color.js +1 -1
- package/dist/color/setting.js +2 -2
- package/dist/{constants-DQyACdzq.js → constants-DAnmXDew.js} +1 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/environment.js +1 -1
- package/dist/core/filterShaders.js +1 -1
- package/dist/core/friendly_errors/fes_core.js +1 -1
- package/dist/core/friendly_errors/file_errors.js +1 -1
- package/dist/core/friendly_errors/index.js +1 -1
- package/dist/core/friendly_errors/param_validator.js +1 -1
- package/dist/core/friendly_errors/sketch_verifier.js +2 -2
- package/dist/core/helpers.js +1 -1
- package/dist/core/init.js +6 -6
- package/dist/core/internationalization.js +1 -1
- package/dist/core/legacy.js +6 -6
- package/dist/core/main.js +6 -6
- package/dist/core/p5.Graphics.js +4 -4
- package/dist/core/p5.Renderer.js +3 -3
- package/dist/core/p5.Renderer2D.js +6 -6
- package/dist/core/p5.Renderer3D.js +4 -4
- package/dist/core/rendering.js +4 -4
- package/dist/{creating_reading-ZXzcZEsb.js → creating_reading-C7hu6sg1.js} +2 -2
- package/dist/dom/dom.js +2 -2
- package/dist/dom/index.js +2 -2
- package/dist/dom/p5.Element.js +2 -2
- package/dist/dom/p5.MediaElement.js +2 -2
- package/dist/image/const.js +1 -1
- package/dist/image/filterRenderer2D.js +5 -5
- package/dist/image/image.js +4 -4
- package/dist/image/index.js +4 -4
- package/dist/image/loading_displaying.js +4 -4
- package/dist/image/p5.Image.js +3 -3
- package/dist/io/files.js +4 -4
- package/dist/io/index.js +4 -4
- package/dist/{ir_builders-DXNgaB9N.js → ir_builders-w12-GSxu.js} +37 -5
- package/dist/{main-DvN69W3f.js → main-E-swj5tF.js} +4 -4
- package/dist/math/Matrices/Matrix.js +1 -1
- package/dist/math/Matrices/MatrixNumjs.js +1 -1
- package/dist/math/index.js +1 -1
- package/dist/math/p5.Matrix.js +1 -1
- package/dist/math/p5.Vector.js +1 -1
- package/dist/math/trigonometry.js +1 -1
- package/dist/{p5.Renderer-D-5LdCRz.js → p5.Renderer-DOk9UW65.js} +2 -2
- package/dist/{rendering-h9unX5K0.js → rendering-B8V5Zt4k.js} +58 -14
- package/dist/shape/2d_primitives.js +1 -1
- package/dist/shape/attributes.js +1 -1
- package/dist/shape/custom_shapes.js +2 -2
- package/dist/shape/index.js +2 -2
- package/dist/strands/ir_builders.js +1 -1
- package/dist/strands/p5.strands.js +1 -1
- package/dist/strands/strands_api.js +91 -31
- package/dist/strands/strands_conditionals.js +1 -1
- package/dist/strands/strands_for.js +2 -2
- package/dist/strands/strands_node.js +1 -1
- package/dist/type/index.js +3 -3
- package/dist/type/p5.Font.js +3 -3
- package/dist/type/textCore.js +3 -3
- package/dist/webgl/3d_primitives.js +4 -4
- package/dist/webgl/GeometryBuilder.js +1 -1
- package/dist/webgl/ShapeBuilder.js +1 -1
- package/dist/webgl/enums.js +1 -1
- package/dist/webgl/index.js +5 -5
- package/dist/webgl/interaction.js +1 -1
- package/dist/webgl/light.js +4 -4
- package/dist/webgl/loading.js +12 -14
- package/dist/webgl/material.js +4 -4
- package/dist/webgl/p5.Camera.js +4 -4
- package/dist/webgl/p5.Framebuffer.js +4 -4
- package/dist/webgl/p5.Geometry.js +1 -1
- package/dist/webgl/p5.Quat.js +1 -1
- package/dist/webgl/p5.RendererGL.js +5 -5
- package/dist/webgl/p5.Texture.js +4 -4
- package/dist/webgl/strands_glslBackend.js +1 -1
- package/dist/webgl/text.js +5 -5
- package/dist/webgl/utils.js +4 -4
- package/dist/webgpu/index.js +2 -2
- package/dist/webgpu/p5.RendererWebGPU.js +13 -4
- package/dist/webgpu/strands_wgslBackend.js +5 -4
- package/lib/p5.esm.js +196 -62
- package/lib/p5.esm.min.js +1 -1
- package/lib/p5.js +196 -62
- package/lib/p5.min.js +1 -1
- package/lib/p5.webgpu.esm.js +51 -9
- package/lib/p5.webgpu.js +51 -9
- package/lib/p5.webgpu.min.js +1 -1
- package/package.json +1 -1
- package/types/global.d.ts +1453 -1383
- package/types/p5.d.ts +729 -694
package/dist/webgpu/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import rendererWebGPU from './p5.RendererWebGPU.js';
|
|
2
|
-
import '../constants-
|
|
2
|
+
import '../constants-DAnmXDew.js';
|
|
3
3
|
import '../webgl/enums.js';
|
|
4
4
|
import '../strands/ir_types.js';
|
|
5
5
|
import './shaders/color.js';
|
|
@@ -10,7 +10,7 @@ import './shaders/blit.js';
|
|
|
10
10
|
import './strands_wgslBackend.js';
|
|
11
11
|
import '../strands/ir_dag.js';
|
|
12
12
|
import '../strands/strands_FES.js';
|
|
13
|
-
import '../ir_builders-
|
|
13
|
+
import '../ir_builders-w12-GSxu.js';
|
|
14
14
|
import '../strands/ir_cfg.js';
|
|
15
15
|
import '../strands/strands_builtins.js';
|
|
16
16
|
import './shaders/functions/noise3DWGSL.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as WEBGPU, T as TRIANGLE_STRIP, L as LIGHTEST, D as DARKEST, S as SUBTRACT, R as REPLACE, E as EXCLUSION, a as SCREEN, M as MULTIPLY, b as REMOVE, A as ADD, B as BLEND, c as TRIANGLES, U as UNSIGNED_BYTE, F as FLOAT, H as HALF_FLOAT, d as UNSIGNED_INT, e as MIRROR, f as REPEAT, C as CLAMP, g as LINEAR, N as NEAREST } from '../constants-
|
|
1
|
+
import { W as WEBGPU, T as TRIANGLE_STRIP, L as LIGHTEST, D as DARKEST, S as SUBTRACT, R as REPLACE, E as EXCLUSION, a as SCREEN, M as MULTIPLY, b as REMOVE, A as ADD, B as BLEND, c as TRIANGLES, U as UNSIGNED_BYTE, F as FLOAT, H as HALF_FLOAT, d as UNSIGNED_INT, e as MIRROR, f as REPEAT, C as CLAMP, g as LINEAR, N as NEAREST } from '../constants-DAnmXDew.js';
|
|
2
2
|
import { getStrokeDefs } from '../webgl/enums.js';
|
|
3
3
|
import { DataType } from '../strands/ir_types.js';
|
|
4
4
|
import { colorVertexShader, colorFragmentShader } from './shaders/color.js';
|
|
@@ -12,7 +12,7 @@ import { baseFilterVertexShader, baseFilterFragmentShader } from './shaders/filt
|
|
|
12
12
|
import { imageLightVertexShader, imageLightDiffusedFragmentShader, imageLightSpecularFragmentShader } from './shaders/imageLight.js';
|
|
13
13
|
import '../strands/ir_dag.js';
|
|
14
14
|
import '../strands/strands_FES.js';
|
|
15
|
-
import '../ir_builders-
|
|
15
|
+
import '../ir_builders-w12-GSxu.js';
|
|
16
16
|
import '../strands/ir_cfg.js';
|
|
17
17
|
import '../strands/strands_builtins.js';
|
|
18
18
|
|
|
@@ -97,6 +97,10 @@ function rendererWebGPU(p5, fn) {
|
|
|
97
97
|
this.finalCamera = new Camera(this);
|
|
98
98
|
this.finalCamera._computeCameraDefaultSettings();
|
|
99
99
|
this.finalCamera._setDefaultCamera();
|
|
100
|
+
|
|
101
|
+
this.depthFormat = 'depth24plus-stencil8';
|
|
102
|
+
this.depthTexture = null;
|
|
103
|
+
this.depthTextureView = null;
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
async setupContext() {
|
|
@@ -137,7 +141,6 @@ function rendererWebGPU(p5, fn) {
|
|
|
137
141
|
});
|
|
138
142
|
|
|
139
143
|
// TODO disablable stencil
|
|
140
|
-
this.depthFormat = 'depth24plus-stencil8';
|
|
141
144
|
this.mainFramebuffer = this.createFramebuffer({ _useCanvasFormat: true });
|
|
142
145
|
this._updateSize();
|
|
143
146
|
this._update();
|
|
@@ -194,6 +197,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
_updateSize() {
|
|
200
|
+
if (!this.device || !this.depthFormat) return;
|
|
197
201
|
if (this.depthTexture && this.depthTexture.destroy) {
|
|
198
202
|
this.flushDraw();
|
|
199
203
|
const textureToDestroy = this.depthTexture;
|
|
@@ -288,6 +292,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
clear(...args) {
|
|
295
|
+
if (!this.device || !this.drawingContext) return;
|
|
291
296
|
const _r = args[0] || 0;
|
|
292
297
|
const _g = args[1] || 0;
|
|
293
298
|
const _b = args[2] || 0;
|
|
@@ -354,6 +359,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
354
359
|
* occlude anything subsequently drawn.
|
|
355
360
|
*/
|
|
356
361
|
clearDepth(depth = 1) {
|
|
362
|
+
if (!this.device || !this.depthTextureView) return;
|
|
357
363
|
this._finishActiveRenderPass();
|
|
358
364
|
const commandEncoder = this.device.createCommandEncoder();
|
|
359
365
|
|
|
@@ -1902,7 +1908,7 @@ function rendererWebGPU(p5, fn) {
|
|
|
1902
1908
|
|
|
1903
1909
|
getNextBindingIndex({ vert, frag }, group = 0) {
|
|
1904
1910
|
// Get the highest binding index in the specified group and return the next available
|
|
1905
|
-
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var
|
|
1911
|
+
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var(?:<uniform>)?\s+(\w+)\s*:\s*(texture_2d<f32>|sampler|uniform|\w+)/g;
|
|
1906
1912
|
let maxBindingIndex = -1;
|
|
1907
1913
|
|
|
1908
1914
|
for (const [src, visibility] of [
|
|
@@ -2252,6 +2258,9 @@ function rendererWebGPU(p5, fn) {
|
|
|
2252
2258
|
// Inject hook uniforms as a separate struct at a new binding
|
|
2253
2259
|
let hookUniformFields = '';
|
|
2254
2260
|
for (const key in shader.hooks.uniforms) {
|
|
2261
|
+
// Skip textures, they don't get added to structs
|
|
2262
|
+
if (key.endsWith(': sampler2D')) continue;
|
|
2263
|
+
|
|
2255
2264
|
// WGSL format: "name: type"
|
|
2256
2265
|
hookUniformFields += ` ${key},\n`;
|
|
2257
2266
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseType, DataType, NodeTypeToName, NodeType, OpCode, OpCodeToSymbol, isStructType, StatementType, BlockType } from '../strands/ir_types.js';
|
|
2
2
|
import { getNodeDataFromID, extractNodeTypeInfo } from '../strands/ir_dag.js';
|
|
3
3
|
import { internalError } from '../strands/strands_FES.js';
|
|
4
|
-
import { v as variableNode, c as createStrandsNode, f as functionCallNode } from '../ir_builders-
|
|
4
|
+
import { v as variableNode, c as createStrandsNode, f as functionCallNode } from '../ir_builders-w12-GSxu.js';
|
|
5
5
|
import '../strands/ir_cfg.js';
|
|
6
6
|
import '../strands/strands_builtins.js';
|
|
7
7
|
|
|
@@ -225,10 +225,11 @@ const wgslBackend = {
|
|
|
225
225
|
return primitiveTypeName;
|
|
226
226
|
},
|
|
227
227
|
generateHookUniformKey(name, typeInfo) {
|
|
228
|
-
// For sampler2D types, we don't add them to the uniform struct
|
|
229
|
-
//
|
|
228
|
+
// For sampler2D types, we don't add them to the uniform struct,
|
|
229
|
+
// but we still need them in the shader's hooks object so that
|
|
230
|
+
// they can be set by users.
|
|
230
231
|
if (typeInfo.baseType === 'sampler2D') {
|
|
231
|
-
return
|
|
232
|
+
return `${name}: sampler2D`; // Signal that this should not be added to uniform struct
|
|
232
233
|
}
|
|
233
234
|
return `${name}: ${this.getTypeName(typeInfo.baseType, typeInfo.dimension)}`;
|
|
234
235
|
},
|
package/lib/p5.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! p5.js v2.2.1 February
|
|
1
|
+
/*! p5.js v2.2.2-rc.1 February 19, 2026 */
|
|
2
2
|
/**
|
|
3
3
|
* @module Constants
|
|
4
4
|
* @submodule Constants
|
|
@@ -12,7 +12,7 @@ const _PI = Math.PI;
|
|
|
12
12
|
* @property {String} VERSION
|
|
13
13
|
* @final
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = '2.2.1';
|
|
15
|
+
const VERSION = '2.2.2-rc.1';
|
|
16
16
|
|
|
17
17
|
// GRAPHICS RENDERER
|
|
18
18
|
/**
|
|
@@ -12611,11 +12611,11 @@ function creatingReading(p5, fn){
|
|
|
12611
12611
|
* values. 0 is equal to the first color, 0.1 is very near the first color,
|
|
12612
12612
|
* 0.5 is halfway between the two colors, and so on. Negative numbers are set
|
|
12613
12613
|
* to 0. Numbers greater than 1 are set to 1. This differs from the behavior of
|
|
12614
|
-
* <a href="#/lerp">lerp</a>. It's necessary because numbers outside of the
|
|
12614
|
+
* <a href="#/p5/lerp">lerp</a>. It's necessary because numbers outside of the
|
|
12615
12615
|
* interval [0, 1] will produce strange and unexpected colors.
|
|
12616
12616
|
*
|
|
12617
12617
|
* The way that colors are interpolated depends on the current
|
|
12618
|
-
* <a href="#/colorMode">colorMode()</a>.
|
|
12618
|
+
* <a href="#/p5/colorMode">colorMode()</a>.
|
|
12619
12619
|
*
|
|
12620
12620
|
* @method lerpColor
|
|
12621
12621
|
* @param {p5.Color} c1 interpolate from this color.
|
|
@@ -61237,6 +61237,40 @@ function material(p5, fn) {
|
|
|
61237
61237
|
* }
|
|
61238
61238
|
* ```
|
|
61239
61239
|
*
|
|
61240
|
+
* We can use the `noise()` function built into strands to generate a color for each pixel. (Again no need here for underlying content for the filter to operate on.) Again we'll animate by passing in an announced uniform variable `time` with `setUniform()`, each frame.
|
|
61241
|
+
*
|
|
61242
|
+
* ```js example
|
|
61243
|
+
* let myFilter;
|
|
61244
|
+
*
|
|
61245
|
+
* function setup() {
|
|
61246
|
+
* createCanvas(100, 100, WEBGL);
|
|
61247
|
+
* myFilter = buildFilterShader(noiseShaderCallback);
|
|
61248
|
+
* describe('Evolving animated cloud-like noise in cyan and magenta');
|
|
61249
|
+
* }
|
|
61250
|
+
*
|
|
61251
|
+
* function noiseShaderCallback() {
|
|
61252
|
+
* let time = uniformFloat();
|
|
61253
|
+
* filterColor.begin();
|
|
61254
|
+
* let coord = filterColor.texCoord;
|
|
61255
|
+
*
|
|
61256
|
+
* //generate a value roughly between 0 and 1
|
|
61257
|
+
* let noiseVal = noise(coord.x, coord.y, time / 2000);
|
|
61258
|
+
*
|
|
61259
|
+
* let result = mix(
|
|
61260
|
+
* [1, 0, 1, 1], // Magenta
|
|
61261
|
+
* [0, 1, 1, 1], // Cyan
|
|
61262
|
+
* noiseVal
|
|
61263
|
+
* );
|
|
61264
|
+
* filterColor.set(result);
|
|
61265
|
+
* filterColor.end();
|
|
61266
|
+
* }
|
|
61267
|
+
*
|
|
61268
|
+
* function draw() {
|
|
61269
|
+
* myFilter.setUniform("time", millis());
|
|
61270
|
+
* filter(myFilter);
|
|
61271
|
+
* }
|
|
61272
|
+
* ```
|
|
61273
|
+
*
|
|
61240
61274
|
* Like the `modify()` method on shaders,
|
|
61241
61275
|
* advanced users can also fill in `filterColor` using <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders" target="_blank">GLSL</a>
|
|
61242
61276
|
* instead of JavaScript.
|
|
@@ -61251,15 +61285,17 @@ function material(p5, fn) {
|
|
|
61251
61285
|
* @beta
|
|
61252
61286
|
* @submodule p5.strands
|
|
61253
61287
|
* @param {Function} callback A function building a p5.strands shader.
|
|
61288
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
61254
61289
|
* @returns {p5.Shader} The material shader
|
|
61255
61290
|
*/
|
|
61256
61291
|
/**
|
|
61257
61292
|
* @method buildFilterShader
|
|
61258
61293
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
61294
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
61259
61295
|
* @returns {p5.Shader} The material shader
|
|
61260
61296
|
*/
|
|
61261
|
-
fn.buildFilterShader = function (callback) {
|
|
61262
|
-
return this.baseFilterShader().modify(callback);
|
|
61297
|
+
fn.buildFilterShader = function (callback, scope) {
|
|
61298
|
+
return this.baseFilterShader().modify(callback, scope);
|
|
61263
61299
|
};
|
|
61264
61300
|
|
|
61265
61301
|
/**
|
|
@@ -62079,15 +62115,17 @@ function material(p5, fn) {
|
|
|
62079
62115
|
* @submodule p5.strands
|
|
62080
62116
|
* @beta
|
|
62081
62117
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62118
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62082
62119
|
* @returns {p5.Shader} The material shader.
|
|
62083
62120
|
*/
|
|
62084
62121
|
/**
|
|
62085
62122
|
* @method buildMaterialShader
|
|
62086
62123
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62124
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62087
62125
|
* @returns {p5.Shader} The material shader.
|
|
62088
62126
|
*/
|
|
62089
|
-
fn.buildMaterialShader = function (cb) {
|
|
62090
|
-
return this.baseMaterialShader().modify(cb);
|
|
62127
|
+
fn.buildMaterialShader = function (cb, scope) {
|
|
62128
|
+
return this.baseMaterialShader().modify(cb, scope);
|
|
62091
62129
|
};
|
|
62092
62130
|
|
|
62093
62131
|
/**
|
|
@@ -62186,7 +62224,7 @@ function material(p5, fn) {
|
|
|
62186
62224
|
/**
|
|
62187
62225
|
* Returns the base shader used for filters.
|
|
62188
62226
|
*
|
|
62189
|
-
* Calling <a href="#/p5/
|
|
62227
|
+
* Calling <a href="#/p5/buildFilterShader">`buildFilterShader(shaderFunction)`</a>
|
|
62190
62228
|
* is equivalent to calling `baseFilterShader().modify(shaderFunction)`.
|
|
62191
62229
|
*
|
|
62192
62230
|
* Read <a href="#/p5/buildFilterShader">the `buildFilterShader` reference</a> or
|
|
@@ -62295,15 +62333,17 @@ function material(p5, fn) {
|
|
|
62295
62333
|
* @submodule p5.strands
|
|
62296
62334
|
* @beta
|
|
62297
62335
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62336
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62298
62337
|
* @returns {p5.Shader} The normal shader.
|
|
62299
62338
|
*/
|
|
62300
62339
|
/**
|
|
62301
62340
|
* @method buildNormalShader
|
|
62302
62341
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62342
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62303
62343
|
* @returns {p5.Shader} The normal shader.
|
|
62304
62344
|
*/
|
|
62305
|
-
fn.buildNormalShader = function (cb) {
|
|
62306
|
-
return this.baseNormalShader().modify(cb);
|
|
62345
|
+
fn.buildNormalShader = function (cb, scope) {
|
|
62346
|
+
return this.baseNormalShader().modify(cb, scope);
|
|
62307
62347
|
};
|
|
62308
62348
|
|
|
62309
62349
|
/**
|
|
@@ -62459,15 +62499,17 @@ function material(p5, fn) {
|
|
|
62459
62499
|
* @submodule p5.strands
|
|
62460
62500
|
* @beta
|
|
62461
62501
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62502
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62462
62503
|
* @returns {p5.Shader} The color shader.
|
|
62463
62504
|
*/
|
|
62464
62505
|
/**
|
|
62465
62506
|
* @method buildColorShader
|
|
62466
62507
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62508
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62467
62509
|
* @returns {p5.Shader} The color shader.
|
|
62468
62510
|
*/
|
|
62469
|
-
fn.buildColorShader = function (cb) {
|
|
62470
|
-
return this.baseColorShader().modify(cb);
|
|
62511
|
+
fn.buildColorShader = function (cb, scope) {
|
|
62512
|
+
return this.baseColorShader().modify(cb, scope);
|
|
62471
62513
|
};
|
|
62472
62514
|
|
|
62473
62515
|
/**
|
|
@@ -62714,15 +62756,17 @@ function material(p5, fn) {
|
|
|
62714
62756
|
* @submodule p5.strands
|
|
62715
62757
|
* @beta
|
|
62716
62758
|
* @param {Function} callback A function building a p5.strands shader.
|
|
62759
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62717
62760
|
* @returns {p5.Shader} The stroke shader.
|
|
62718
62761
|
*/
|
|
62719
62762
|
/**
|
|
62720
62763
|
* @method buildStrokeShader
|
|
62721
62764
|
* @param {Object} hooks An object specifying p5.strands hooks in GLSL.
|
|
62765
|
+
* @param {Object} [scope] An optional scope object passed to .modify().
|
|
62722
62766
|
* @returns {p5.Shader} The stroke shader.
|
|
62723
62767
|
*/
|
|
62724
|
-
fn.buildStrokeShader = function (cb) {
|
|
62725
|
-
return this.baseStrokeShader().modify(cb);
|
|
62768
|
+
fn.buildStrokeShader = function (cb, scope) {
|
|
62769
|
+
return this.baseStrokeShader().modify(cb, scope);
|
|
62726
62770
|
};
|
|
62727
62771
|
|
|
62728
62772
|
/**
|
|
@@ -69201,7 +69245,7 @@ class StrandsNode {
|
|
|
69201
69245
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
69202
69246
|
|
|
69203
69247
|
let newValueID;
|
|
69204
|
-
if (value
|
|
69248
|
+
if (value?.isStrandsNode) {
|
|
69205
69249
|
newValueID = value.id;
|
|
69206
69250
|
} else {
|
|
69207
69251
|
const newVal = primitiveConstructorNode(
|
|
@@ -69256,7 +69300,7 @@ class StrandsNode {
|
|
|
69256
69300
|
const baseType = orig?.baseType ?? BaseType.FLOAT;
|
|
69257
69301
|
|
|
69258
69302
|
let newValueID;
|
|
69259
|
-
if (value
|
|
69303
|
+
if (value?.isStrandsNode) {
|
|
69260
69304
|
newValueID = value.id;
|
|
69261
69305
|
} else {
|
|
69262
69306
|
const newVal = primitiveConstructorNode(
|
|
@@ -69486,7 +69530,7 @@ function unaryOpNode(strandsContext, nodeOrValue, opCode) {
|
|
|
69486
69530
|
const { dag, cfg } = strandsContext;
|
|
69487
69531
|
let dependsOn;
|
|
69488
69532
|
let node;
|
|
69489
|
-
if (nodeOrValue
|
|
69533
|
+
if (nodeOrValue?.isStrandsNode) {
|
|
69490
69534
|
node = nodeOrValue;
|
|
69491
69535
|
} else {
|
|
69492
69536
|
const { id, dimension } = primitiveConstructorNode(strandsContext, { baseType: BaseType.FLOAT, dimension: null }, nodeOrValue);
|
|
@@ -69686,6 +69730,20 @@ function constructTypeFromIDs(strandsContext, typeInfo, strandsNodesArray) {
|
|
|
69686
69730
|
|
|
69687
69731
|
function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
69688
69732
|
const cfg = strandsContext.cfg;
|
|
69733
|
+
dependsOn = (Array.isArray(dependsOn) ? dependsOn : [dependsOn])
|
|
69734
|
+
.flat(Infinity)
|
|
69735
|
+
.map(a => {
|
|
69736
|
+
if (
|
|
69737
|
+
a.isStrandsNode &&
|
|
69738
|
+
a.typeInfo().baseType === BaseType.INT &&
|
|
69739
|
+
// TODO: handle ivec inputs instead of just int scalars
|
|
69740
|
+
a.typeInfo().dimension === 1
|
|
69741
|
+
) {
|
|
69742
|
+
return castToFloat(strandsContext, a);
|
|
69743
|
+
} else {
|
|
69744
|
+
return a;
|
|
69745
|
+
}
|
|
69746
|
+
});
|
|
69689
69747
|
const { mappedDependencies, inferredTypeInfo } = mapPrimitiveDepsToIDs(strandsContext, typeInfo, dependsOn);
|
|
69690
69748
|
|
|
69691
69749
|
const finalType = {
|
|
@@ -69701,6 +69759,24 @@ function primitiveConstructorNode(strandsContext, typeInfo, dependsOn) {
|
|
|
69701
69759
|
return { id, dimension: finalType.dimension, components: mappedDependencies };
|
|
69702
69760
|
}
|
|
69703
69761
|
|
|
69762
|
+
function castToFloat(strandsContext, dep) {
|
|
69763
|
+
const { id, dimension } = functionCallNode(
|
|
69764
|
+
strandsContext,
|
|
69765
|
+
strandsContext.backend.getTypeName('float', dep.typeInfo().dimension),
|
|
69766
|
+
[dep],
|
|
69767
|
+
{
|
|
69768
|
+
overloads: [{
|
|
69769
|
+
params: [dep.typeInfo()],
|
|
69770
|
+
returnType: {
|
|
69771
|
+
...dep.typeInfo(),
|
|
69772
|
+
baseType: BaseType.FLOAT,
|
|
69773
|
+
},
|
|
69774
|
+
}],
|
|
69775
|
+
}
|
|
69776
|
+
);
|
|
69777
|
+
return createStrandsNode(id, dimension, strandsContext);
|
|
69778
|
+
}
|
|
69779
|
+
|
|
69704
69780
|
function structConstructorNode(strandsContext, structTypeInfo, rawUserArgs) {
|
|
69705
69781
|
const { cfg, dag } = strandsContext;
|
|
69706
69782
|
const { properties } = structTypeInfo;
|
|
@@ -69920,7 +69996,7 @@ function swizzleTrap(id, dimension, strandsContext, onRebind) {
|
|
|
69920
69996
|
// This may not be the most efficient way, as we swizzle each component individually,
|
|
69921
69997
|
// so that .xyz becomes .x, .y, .z
|
|
69922
69998
|
let scalars = [];
|
|
69923
|
-
if (value
|
|
69999
|
+
if (value?.isStrandsNode) {
|
|
69924
70000
|
if (value.dimension === 1) {
|
|
69925
70001
|
scalars = Array(chars.length).fill(value);
|
|
69926
70002
|
} else if (value.dimension === chars.length) {
|
|
@@ -96586,7 +96662,7 @@ const verifierUtils = {
|
|
|
96586
96662
|
|
|
96587
96663
|
try {
|
|
96588
96664
|
const ast = parse(code, {
|
|
96589
|
-
ecmaVersion:
|
|
96665
|
+
ecmaVersion: 'latest',
|
|
96590
96666
|
sourceType: 'module',
|
|
96591
96667
|
locations: true // This helps us get the line number.
|
|
96592
96668
|
});
|
|
@@ -110019,12 +110095,10 @@ function loading$1(p5, fn){
|
|
|
110019
110095
|
const vertString = tokens[vertexTokens[tokenInd]];
|
|
110020
110096
|
let vertParts = vertString.split('/');
|
|
110021
110097
|
|
|
110022
|
-
// TODO: Faces can technically use negative numbers to refer to the
|
|
110023
|
-
// previous nth vertex. I haven't seen this used in practice, but
|
|
110024
|
-
// it might be good to implement this in the future.
|
|
110025
|
-
|
|
110026
110098
|
for (let i = 0; i < vertParts.length; i++) {
|
|
110027
|
-
|
|
110099
|
+
let index = parseInt(vertParts[i]);
|
|
110100
|
+
if (index > 0) index -= 1; // OBJ uses 1-based indexing
|
|
110101
|
+
vertParts[i] = index;
|
|
110028
110102
|
}
|
|
110029
110103
|
|
|
110030
110104
|
if (!usedVerts[vertString]) {
|
|
@@ -110033,11 +110107,11 @@ function loading$1(p5, fn){
|
|
|
110033
110107
|
|
|
110034
110108
|
if (usedVerts[vertString][currentMaterial] === undefined) {
|
|
110035
110109
|
const vertIndex = model.vertices.length;
|
|
110036
|
-
model.vertices.push(loadedVerts.v
|
|
110037
|
-
model.uvs.push(loadedVerts.vt
|
|
110038
|
-
loadedVerts.vt
|
|
110039
|
-
model.vertexNormals.push(loadedVerts.vn
|
|
110040
|
-
loadedVerts.vn
|
|
110110
|
+
model.vertices.push(loadedVerts.v.at(vertParts[0]).copy());
|
|
110111
|
+
model.uvs.push(loadedVerts.vt.at(vertParts[1]) ?
|
|
110112
|
+
loadedVerts.vt.at(vertParts[1]).slice() : [0, 0]);
|
|
110113
|
+
model.vertexNormals.push(loadedVerts.vn.at(vertParts[2]) ?
|
|
110114
|
+
loadedVerts.vn.at(vertParts[2]).copy() : new Vector());
|
|
110041
110115
|
|
|
110042
110116
|
usedVerts[vertString][currentMaterial] = vertIndex;
|
|
110043
110117
|
face.push(vertIndex);
|
|
@@ -120917,7 +120991,7 @@ function text(p5, fn) {
|
|
|
120917
120991
|
|
|
120918
120992
|
if (!p5.Font.hasGlyphData(this.states.textFont)) {
|
|
120919
120993
|
console.log(
|
|
120920
|
-
'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported'
|
|
120994
|
+
'WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts with glyph data are supported. Make sure to set the font using textFont() before drawing text.'
|
|
120921
120995
|
);
|
|
120922
120996
|
return;
|
|
120923
120997
|
}
|
|
@@ -132149,7 +132223,7 @@ class StrandsFor {
|
|
|
132149
132223
|
let initialVar = this.initialCb();
|
|
132150
132224
|
|
|
132151
132225
|
// Convert to StrandsNode if it's not already one
|
|
132152
|
-
if (!(initialVar
|
|
132226
|
+
if (!(initialVar?.isStrandsNode)) {
|
|
132153
132227
|
const { id, dimension } = primitiveConstructorNode(this.strandsContext, { baseType: BaseType.FLOAT, dimension: 1 }, initialVar);
|
|
132154
132228
|
initialVar = createStrandsNode(id, dimension, this.strandsContext);
|
|
132155
132229
|
}
|
|
@@ -132308,32 +132382,45 @@ function _getBuiltinGlobalsCache(strandsContext) {
|
|
|
132308
132382
|
return strandsContext._builtinGlobals
|
|
132309
132383
|
}
|
|
132310
132384
|
|
|
132311
|
-
function
|
|
132312
|
-
const spec = BUILTIN_GLOBAL_SPECS[name];
|
|
132313
|
-
if (!spec) return null
|
|
132314
|
-
|
|
132385
|
+
function getOrCreateUniformNode(strandsContext, uniformName, typeInfo, defaultValueFn) {
|
|
132315
132386
|
const cache = _getBuiltinGlobalsCache(strandsContext);
|
|
132316
|
-
|
|
132387
|
+
|
|
132317
132388
|
const cached = cache.nodes.get(uniformName);
|
|
132318
|
-
if (cached) return cached
|
|
132389
|
+
if (cached) return cached;
|
|
132319
132390
|
|
|
132320
132391
|
if (!cache.uniformsAdded.has(uniformName)) {
|
|
132321
132392
|
cache.uniformsAdded.add(uniformName);
|
|
132322
132393
|
strandsContext.uniforms.push({
|
|
132323
132394
|
name: uniformName,
|
|
132324
|
-
typeInfo
|
|
132325
|
-
defaultValue:
|
|
132326
|
-
const p5Instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
|
|
132327
|
-
return p5Instance ? spec.get(p5Instance) : undefined
|
|
132328
|
-
},
|
|
132395
|
+
typeInfo,
|
|
132396
|
+
defaultValue: defaultValueFn,
|
|
132329
132397
|
});
|
|
132330
132398
|
}
|
|
132331
132399
|
|
|
132332
|
-
const { id, dimension } = variableNode(strandsContext,
|
|
132400
|
+
const { id, dimension } = variableNode(strandsContext, typeInfo, uniformName);
|
|
132333
132401
|
const node = createStrandsNode(id, dimension, strandsContext);
|
|
132334
|
-
node._originalBuiltinName = name;
|
|
132335
132402
|
cache.nodes.set(uniformName, node);
|
|
132336
|
-
return node
|
|
132403
|
+
return node;
|
|
132404
|
+
}
|
|
132405
|
+
|
|
132406
|
+
function getBuiltinGlobalNode(strandsContext, name) {
|
|
132407
|
+
const spec = BUILTIN_GLOBAL_SPECS[name];
|
|
132408
|
+
if (!spec) return null;
|
|
132409
|
+
|
|
132410
|
+
const uniformName = `_p5_global_${name}`;
|
|
132411
|
+
const instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
|
|
132412
|
+
|
|
132413
|
+
const node = getOrCreateUniformNode(
|
|
132414
|
+
strandsContext,
|
|
132415
|
+
uniformName,
|
|
132416
|
+
spec.typeInfo,
|
|
132417
|
+
() => {
|
|
132418
|
+
return instance ? spec.get(instance) : undefined;
|
|
132419
|
+
}
|
|
132420
|
+
);
|
|
132421
|
+
|
|
132422
|
+
node._originalBuiltinName = name;
|
|
132423
|
+
return node;
|
|
132337
132424
|
}
|
|
132338
132425
|
|
|
132339
132426
|
function installBuiltinGlobalAccessors(strandsContext) {
|
|
@@ -132409,7 +132496,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132409
132496
|
}
|
|
132410
132497
|
|
|
132411
132498
|
// Convert value to a StrandsNode if it isn't already
|
|
132412
|
-
const valueNode = value
|
|
132499
|
+
const valueNode = value?.isStrandsNode ? value : p5.strandsNode(value);
|
|
132413
132500
|
|
|
132414
132501
|
// Create a new CFG block for the early return
|
|
132415
132502
|
const earlyReturnBlockID = createBasicBlock(cfg, BlockType.DEFAULT);
|
|
@@ -132496,6 +132583,7 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132496
132583
|
// Add noise function with backend-agnostic implementation
|
|
132497
132584
|
const originalNoise = fn.noise;
|
|
132498
132585
|
const originalNoiseDetail = fn.noiseDetail;
|
|
132586
|
+
const originalMillis = fn.millis;
|
|
132499
132587
|
|
|
132500
132588
|
strandsContext._noiseOctaves = null;
|
|
132501
132589
|
strandsContext._noiseAmpFalloff = null;
|
|
@@ -132558,6 +132646,21 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132558
132646
|
return createStrandsNode(id, dimension, strandsContext);
|
|
132559
132647
|
};
|
|
132560
132648
|
|
|
132649
|
+
fn.millis = function (...args) {
|
|
132650
|
+
if (!strandsContext.active) {
|
|
132651
|
+
return originalMillis.apply(this, args);
|
|
132652
|
+
}
|
|
132653
|
+
const instance = strandsContext.renderer?._pInst || strandsContext.p5?.instance;
|
|
132654
|
+
return getOrCreateUniformNode(
|
|
132655
|
+
strandsContext,
|
|
132656
|
+
'_p5_global_millis',
|
|
132657
|
+
DataType.float1,
|
|
132658
|
+
() => {
|
|
132659
|
+
return instance ? instance.millis() : undefined;
|
|
132660
|
+
}
|
|
132661
|
+
);
|
|
132662
|
+
};
|
|
132663
|
+
|
|
132561
132664
|
// Next is type constructors and uniform functions.
|
|
132562
132665
|
// For some of them, we have aliases so that you can write either a more human-readable
|
|
132563
132666
|
// variant or also one more directly translated from GLSL, or to be more compatible with
|
|
@@ -132624,12 +132727,17 @@ function initGlobalStrandsAPI(p5, fn, strandsContext) {
|
|
|
132624
132727
|
fn[typeInfo.fnName] = function(...args) {
|
|
132625
132728
|
if (strandsContext.active) {
|
|
132626
132729
|
if (args.length === 1 && args[0].dimension && args[0].dimension === typeInfo.dimension) {
|
|
132627
|
-
const { id, dimension } = functionCallNode(
|
|
132628
|
-
|
|
132629
|
-
|
|
132630
|
-
|
|
132631
|
-
|
|
132632
|
-
|
|
132730
|
+
const { id, dimension } = functionCallNode(
|
|
132731
|
+
strandsContext,
|
|
132732
|
+
strandsContext.backend.getTypeName(typeInfo.baseType, typeInfo.dimension),
|
|
132733
|
+
args,
|
|
132734
|
+
{
|
|
132735
|
+
overloads: [{
|
|
132736
|
+
params: [args[0].typeInfo()],
|
|
132737
|
+
returnType: typeInfo,
|
|
132738
|
+
}]
|
|
132739
|
+
}
|
|
132740
|
+
);
|
|
132633
132741
|
return createStrandsNode(id, dimension, strandsContext);
|
|
132634
132742
|
} else {
|
|
132635
132743
|
// For vector types with a single argument, repeat it for each component
|
|
@@ -132686,7 +132794,7 @@ function createHookArguments(strandsContext, parameters){
|
|
|
132686
132794
|
const oldDependsOn = dag.dependsOn[structNode.id];
|
|
132687
132795
|
const newDependsOn = [...oldDependsOn];
|
|
132688
132796
|
let newValueID;
|
|
132689
|
-
if (val
|
|
132797
|
+
if (val?.isStrandsNode) {
|
|
132690
132798
|
newValueID = val.id;
|
|
132691
132799
|
}
|
|
132692
132800
|
else {
|
|
@@ -132718,7 +132826,7 @@ function createHookArguments(strandsContext, parameters){
|
|
|
132718
132826
|
return args;
|
|
132719
132827
|
}
|
|
132720
132828
|
function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName) {
|
|
132721
|
-
if (!(returned
|
|
132829
|
+
if (!(returned?.isStrandsNode)) {
|
|
132722
132830
|
// try {
|
|
132723
132831
|
const result = primitiveConstructorNode(strandsContext, expectedType, returned);
|
|
132724
132832
|
return result.id;
|
|
@@ -132740,7 +132848,12 @@ function enforceReturnTypeMatch(strandsContext, expectedType, returned, hookName
|
|
|
132740
132848
|
};
|
|
132741
132849
|
if (receivedType.dimension !== expectedType.dimension) {
|
|
132742
132850
|
if (receivedType.dimension !== 1) {
|
|
132743
|
-
|
|
132851
|
+
const receivedTypeDisplay = receivedType.baseType + (receivedType.dimension > 1 ? receivedType.dimension : '');
|
|
132852
|
+
const expectedTypeDisplay = expectedType.baseType + expectedType.dimension;
|
|
132853
|
+
userError('type error',
|
|
132854
|
+
`You have returned a ${receivedTypeDisplay} in ${hookName} when a ${expectedTypeDisplay} was expected!\n\n` +
|
|
132855
|
+
`Make sure your hook returns the correct type.`
|
|
132856
|
+
);
|
|
132744
132857
|
}
|
|
132745
132858
|
else {
|
|
132746
132859
|
const result = primitiveConstructorNode(strandsContext, expectedType, returned);
|
|
@@ -132827,10 +132940,27 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
|
|
|
132827
132940
|
const handleRetVal = (retNode) => {
|
|
132828
132941
|
if(isStructType(expectedReturnType)) {
|
|
132829
132942
|
const expectedStructType = structType(expectedReturnType);
|
|
132830
|
-
if (retNode
|
|
132943
|
+
if (retNode?.isStrandsNode) {
|
|
132831
132944
|
const returnedNode = getNodeDataFromID(strandsContext.dag, retNode.id);
|
|
132832
132945
|
if (returnedNode.baseType !== expectedStructType.typeName) {
|
|
132833
|
-
|
|
132946
|
+
const receivedTypeName = returnedNode.baseType || 'undefined';
|
|
132947
|
+
const receivedDim = dag.dimensions[retNode.id];
|
|
132948
|
+
const receivedTypeDisplay = receivedDim > 1 ?
|
|
132949
|
+
`${receivedTypeName}${receivedDim}` : receivedTypeName;
|
|
132950
|
+
|
|
132951
|
+
const expectedProps = expectedStructType.properties
|
|
132952
|
+
.map(p => p.name).join(', ');
|
|
132953
|
+
userError('type error',
|
|
132954
|
+
`You have returned a ${receivedTypeDisplay} from ${hookType.name} when a ${expectedStructType.typeName} was expected.\n\n` +
|
|
132955
|
+
`The ${expectedStructType.typeName} struct has these properties: { ${expectedProps} }\n\n` +
|
|
132956
|
+
`Instead of returning a different type, you should modify and return the ${expectedStructType.typeName} struct that was passed to your hook.\n\n` +
|
|
132957
|
+
`For example:\n` +
|
|
132958
|
+
`${hookType.name}((inputs) => {\n` +
|
|
132959
|
+
` // Modify properties of inputs\n` +
|
|
132960
|
+
` inputs.someProperty = ...;\n` +
|
|
132961
|
+
` return inputs; // Return the modified struct\n` +
|
|
132962
|
+
`})`
|
|
132963
|
+
);
|
|
132834
132964
|
}
|
|
132835
132965
|
const newDeps = returnedNode.dependsOn.slice();
|
|
132836
132966
|
for (let i = 0; i < expectedStructType.properties.length; i++) {
|
|
@@ -132849,10 +132979,14 @@ function createShaderHooksFunctions(strandsContext, fn, shader) {
|
|
|
132849
132979
|
const propName = expectedProp.name;
|
|
132850
132980
|
const receivedValue = retNode[propName];
|
|
132851
132981
|
if (receivedValue === undefined) {
|
|
132852
|
-
|
|
132853
|
-
|
|
132854
|
-
|
|
132855
|
-
`
|
|
132982
|
+
const expectedProps = expectedReturnType.properties.map(p => p.name).join(', ');
|
|
132983
|
+
const receivedProps = Object.keys(retNode).join(', ');
|
|
132984
|
+
userError('type error',
|
|
132985
|
+
`You've returned an incomplete ${expectedStructType.typeName} struct from ${hookType.name}.\n\n` +
|
|
132986
|
+
`Expected properties: { ${expectedProps} }\n` +
|
|
132987
|
+
`Received properties: { ${receivedProps} }\n\n` +
|
|
132988
|
+
`All properties are required! Make sure to include all properties in the returned struct.`
|
|
132989
|
+
);
|
|
132856
132990
|
}
|
|
132857
132991
|
const expectedTypeInfo = expectedProp.dataType;
|
|
132858
132992
|
const returnedPropID = enforceReturnTypeMatch(strandsContext, expectedTypeInfo, receivedValue, hookType.name);
|