Skip to content

Commit bc4e526

Browse files
authored
Merge branch 'dev-2.0' into feat/storagebuffer-read
2 parents f181fd9 + d516e81 commit bc4e526

29 files changed

Lines changed: 759 additions & 388 deletions

File tree

docs/parameterData.json

Lines changed: 253 additions & 247 deletions
Large diffs are not rendered by default.

src/core/p5.Renderer3D.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ export class Renderer3D extends Renderer {
160160

161161
// clipping
162162
this._clipDepths = [];
163+
this._textContextSavedStack = [];
163164
this._isClipApplied = false;
164165
this._stencilTestOn = false;
165166

@@ -1327,13 +1328,25 @@ export class Renderer3D extends Renderer {
13271328
return this;
13281329
}
13291330

1331+
push() {
1332+
super.push()
1333+
const saved = !!(this.states.textFont?.font);
1334+
if (saved) {
1335+
this.textDrawingContext().save()
1336+
}
1337+
this._textContextSavedStack.push(saved);
1338+
}
1339+
13301340
pop(...args) {
13311341
if (
13321342
this._clipDepths.length > 0 &&
13331343
this._pushPopDepth === this._clipDepths[this._clipDepths.length - 1]
13341344
) {
13351345
this._clearClip();
13361346
}
1347+
if (this._textContextSavedStack.pop()) {
1348+
this.textDrawingContext().restore()
1349+
}
13371350
super.pop(...args);
13381351
this._applyStencilTestIfClipping();
13391352
}

src/core/rendering.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ function rendering(p5, fn){
4545
* system variable to check what version is being used, or call
4646
* `setAttributes({ version: 1 })` to create a WebGL1 context.
4747
*
48+
* Note: In WebGPU mode, you must `await` this function.
49+
*
4850
* @method createCanvas
4951
* @param {Number} [width] width of the canvas. Defaults to 100.
5052
* @param {Number} [height] height of the canvas. Defaults to 100.
51-
* @param {(P2D|WEBGL|P2DHDR|WEBGPU)} [renderer] either P2D, WEBGL, or WEBGPU. Defaults to `P2D`.
53+
* @param {(P2D|WEBGL|P2DHDR)} [renderer] either P2D or WEBGL. Defaults to `P2D`.
5254
* @param {HTMLCanvasElement} [canvas] existing canvas element that should be used for the sketch.
5355
* @return {p5.Renderer} new `p5.Renderer` that holds the canvas.
5456
*
@@ -106,6 +108,14 @@ function rendering(p5, fn){
106108
* describe('A diagonal line drawn from top-left to bottom-right on a gray background.');
107109
* }
108110
*/
111+
/**
112+
* @method createCanvas
113+
* @param {Number} width
114+
* @param {Number} height
115+
* @param {WEBGPU} renderer
116+
* @param {HTMLCanvasElement} [canvas]
117+
* @return {Promise<p5.Renderer>}
118+
*/
109119
/**
110120
* @method createCanvas
111121
* @param {Number} [width]

src/shape/attributes.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ function attributes(p5, fn){
107107
* In WebGL mode, `noSmooth()` causes all shapes to be drawn with jagged
108108
* (aliased) edges. The functions don't affect images or fonts.
109109
*
110+
* Note: In WebGPU mode, you must `await` this function.
111+
*
110112
* @method noSmooth
111-
* @chainable
113+
* @return {void|Promise<void>}
112114
*
113115
* @example
114116
* let heart;
@@ -162,10 +164,10 @@ function attributes(p5, fn){
162164
if ('imageSmoothingEnabled' in this.drawingContext) {
163165
this.drawingContext.imageSmoothingEnabled = false;
164166
}
167+
return this;
165168
} else {
166-
this.setAttributes('antialias', false);
169+
return this.setAttributes('antialias', false);
167170
}
168-
return this;
169171
};
170172

171173
/**

src/strands/p5.strands.js

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,17 @@ if (typeof p5 !== "undefined") {
213213

214214
/* ------------------------------------------------------------- */
215215
/**
216-
* @property {Object} worldInputs
216+
* @typedef {Object} WorldInputsHook
217+
* @property {any} position
218+
* @property {any} normal
219+
* @property {any} texCoord
220+
* @property {any} color
221+
* @property {function(): undefined} begin
222+
* @property {function(): undefined} end
223+
*/
224+
225+
/**
226+
* @property {WorldInputsHook} worldInputs
217227
* @beta
218228
* @description
219229
* A shader hook block that modifies the world-space properties of each vertex in a shader. This hook can be used inside <a href="#/p5/buildColorShader">`buildColorShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to customize vertex positions, normals, texture coordinates, and colors before rendering. Modifications happen between the `.begin()` and `.end()` methods of the hook. "World space" refers to the coordinate system of the 3D scene, before any camera or projection transformations are applied.
@@ -258,7 +268,22 @@ if (typeof p5 !== "undefined") {
258268
*/
259269

260270
/**
261-
* @property {Object} combineColors
271+
* @typedef {Object} CombineColorsHook
272+
* @property {any} baseColor
273+
* @property {any} diffuse
274+
* @property {any} ambientColor
275+
* @property {any} ambient
276+
* @property {any} specularColor
277+
* @property {any} specular
278+
* @property {any} emissive
279+
* @property {any} opacity
280+
* @property {function(): undefined} begin
281+
* @property {function(): undefined} end
282+
* @property {function(color: any): void} set
283+
*/
284+
285+
/**
286+
* @property {CombineColorsHook} combineColors
262287
* @beta
263288
* @description
264289
* A shader hook block that modifies how color components are combined in the fragment shader. This hook can be used inside <a href="#/p5/buildMaterialShader">`buildMaterialShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to control the final color output of a material. Modifications happen between the `.begin()` and `.end()` methods of the hook.
@@ -591,7 +616,26 @@ if (typeof p5 !== "undefined") {
591616
*/
592617

593618
/**
594-
* @property {Object} pixelInputs
619+
* @typedef {Object} PixelInputsHook
620+
* @property {any} normal
621+
* @property {any} texCoord
622+
* @property {any} ambientLight
623+
* @property {any} ambientMaterial
624+
* @property {any} specularMaterial
625+
* @property {any} emissiveMaterial
626+
* @property {any} color
627+
* @property {any} shininess
628+
* @property {any} metalness
629+
* @property {any} tangent
630+
* @property {any} center
631+
* @property {any} position
632+
* @property {any} strokeWeight
633+
* @property {function(): undefined} begin
634+
* @property {function(): undefined} end
635+
*/
636+
637+
/**
638+
* @property {PixelInputsHook} pixelInputs
595639
* @beta
596640
* @description
597641
* A shader hook block that modifies the properties of each pixel before the final color is calculated. This hook can be used inside <a href="#/p5/buildMaterialShader">`buildMaterialShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to adjust per-pixel data before lighting is applied. Modifications happen between the `.begin()` and `.end()` methods of the hook.
@@ -679,13 +723,23 @@ if (typeof p5 !== "undefined") {
679723
*/
680724

681725
/**
682-
* @property finalColor
726+
* @typedef {Object} FinalColorHook
727+
* @property {any} color
728+
* @property {any} texCoord
729+
* @property {function(): undefined} begin
730+
* @property {function(): undefined} end
731+
* @property {function(color: any): void} set
732+
*/
733+
734+
/**
735+
* @property {FinalColorHook} finalColor
683736
* @beta
684737
* @description
685738
* A shader hook block that modifies the final color of each pixel after all lighting is applied. This hook can be used inside <a href="#/p5/buildMaterialShader">`buildMaterialShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to adjust the color before it appears on the screen. Modifications happen between the `.begin()` and `.end()` methods of the hook.
686739
*
687740
* `finalColor` has the following properties:
688741
* - `color`: a four-component vector representing the pixel color (red, green, blue, alpha).
742+
* - `texCoord`: a two-component vector representing the texture coordinates (u, v)
689743
*
690744
* Call `.set()` on the hook with a vector with four components (red, green, blue, alpha) to update the final color.
691745
*
@@ -762,8 +816,18 @@ if (typeof p5 !== "undefined") {
762816
*/
763817

764818
/**
765-
* @property {Object} filterColor
766-
* @beta
819+
* @typedef {Object} FilterColorHook
820+
* @property {any} texCoord
821+
* @property {any} canvasSize
822+
* @property {any} texelSize
823+
* @property {any} canvasContent
824+
* @property {function(): undefined} begin
825+
* @property {function(): undefined} end
826+
* @property {function(color: any): void} set
827+
*/
828+
829+
/**
830+
* @property {FilterColorHook} filterColor
767831
* @description
768832
* A shader hook block that sets the color for each pixel in a filter shader. This hook can be used inside <a href="#/p5/buildFilterShader">`buildFilterShader()`</a> to control the output color for each pixel.
769833
*
@@ -807,7 +871,17 @@ if (typeof p5 !== "undefined") {
807871
*/
808872

809873
/**
810-
* @property {Object} objectInputs
874+
* @typedef {Object} ObjectInputsHook
875+
* @property {any} position
876+
* @property {any} normal
877+
* @property {any} texCoord
878+
* @property {any} color
879+
* @property {function(): undefined} begin
880+
* @property {function(): undefined} end
881+
*/
882+
883+
/**
884+
* @property {ObjectInputsHook} objectInputs
811885
* @beta
812886
* @description
813887
* A shader hook block to modify the properties of each vertex before any transformations are applied. This hook can be used inside <a href="#/p5/buildMaterialShader">`buildMaterialShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to customize vertex positions, normals, texture coordinates, and colors before rendering. Modifications happen between the `.begin()` and `.end()` methods of the hook. "Object space" refers to the coordinate system of the 3D scene before any transformations, cameras, or projection transformations are applied.
@@ -849,7 +923,17 @@ if (typeof p5 !== "undefined") {
849923
*/
850924

851925
/**
852-
* @property {Object} cameraInputs
926+
* @typedef {Object} CameraInputsHook
927+
* @property {any} position
928+
* @property {any} normal
929+
* @property {any} texCoord
930+
* @property {any} color
931+
* @property {function(): undefined} begin
932+
* @property {function(): undefined} end
933+
*/
934+
935+
/**
936+
* @property {CameraInputsHook} cameraInputs
853937
* @beta
854938
* @description
855939
* A shader hook block that adjusts vertex properties from the perspective of the camera. This hook can be used inside <a href="#/p5/buildMaterialShader">`buildMaterialShader()`</a> and similar shader <a href="#/p5.Shader/modify">`modify()`</a> calls to customize vertex positions, normals, texture coordinates, and colors before rendering. "Camera space" refers to the coordinate system of the 3D scene after transformations have been applied, seen relative to the camera.

src/strands/strands_transpiler.js

Lines changed: 33 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,35 @@ function replaceReferences(node, tempVarMap) {
235235
internalReplaceReferences(node);
236236
}
237237

238+
// Shared handler for both BinaryExpression and LogicalExpression —
239+
// both follow the same operator-to-method-call transformation pattern.
240+
function transformBinaryOrLogical(node, state, ancestors) {
241+
if (ancestors.some(a => nodeIsUniform(a) || nodeIsUniformCallbackFn(a, state.uniformCallbackNames))) {
242+
return;
243+
}
244+
const unsafeTypes = ['Literal', 'ArrayExpression', 'Identifier'];
245+
if (unsafeTypes.includes(node.left.type)) {
246+
node.left = {
247+
type: 'CallExpression',
248+
callee: {
249+
type: 'Identifier',
250+
name: '__p5.strandsNode',
251+
},
252+
arguments: [node.left]
253+
};
254+
}
255+
node.type = 'CallExpression';
256+
node.callee = {
257+
type: 'MemberExpression',
258+
object: node.left,
259+
property: {
260+
type: 'Identifier',
261+
name: replaceBinaryOperator(node.operator),
262+
},
263+
};
264+
node.arguments = [node.right];
265+
}
266+
238267
const ASTCallbacks = {
239268
UnaryExpression(node, state, ancestors) {
240269
if (ancestors.some(a => nodeIsUniform(a) || nodeIsUniformCallbackFn(a, state.uniformCallbackNames))) {
@@ -509,72 +538,10 @@ const ASTCallbacks = {
509538
}
510539
}
511540
},
512-
BinaryExpression(node, state, ancestors) {
513-
// Don't convert uniform default values to node methods, as
514-
// they should be evaluated at runtime, not compiled.
515-
if (ancestors.some(a => nodeIsUniform(a) || nodeIsUniformCallbackFn(a, state.uniformCallbackNames))) {
516-
return;
517-
}
518-
// If the left hand side of an expression is one of these types,
519-
// we should construct a node from it.
520-
const unsafeTypes = ['Literal', 'ArrayExpression', 'Identifier'];
521-
if (unsafeTypes.includes(node.left.type)) {
522-
const leftReplacementNode = {
523-
type: 'CallExpression',
524-
callee: {
525-
type: 'Identifier',
526-
name: '__p5.strandsNode',
527-
},
528-
arguments: [node.left]
529-
}
530-
node.left = leftReplacementNode;
531-
}
532-
// Replace the binary operator with a call expression
533-
// in other words a call to BaseNode.mult(), .div() etc.
534-
node.type = 'CallExpression';
535-
node.callee = {
536-
type: 'MemberExpression',
537-
object: node.left,
538-
property: {
539-
type: 'Identifier',
540-
name: replaceBinaryOperator(node.operator),
541-
},
542-
};
543-
node.arguments = [node.right];
544-
},
545-
LogicalExpression(node, state, ancestors) {
546-
// Don't convert uniform default values to node methods, as
547-
// they should be evaluated at runtime, not compiled.
548-
if (ancestors.some(a => nodeIsUniform(a) || nodeIsUniformCallbackFn(a, state.uniformCallbackNames))) {
549-
return;
550-
}
551-
// If the left hand side of an expression is one of these types,
552-
// we should construct a node from it.
553-
const unsafeTypes = ['Literal', 'ArrayExpression', 'Identifier'];
554-
if (unsafeTypes.includes(node.left.type)) {
555-
const leftReplacementNode = {
556-
type: 'CallExpression',
557-
callee: {
558-
type: 'Identifier',
559-
name: '__p5.strandsNode',
560-
},
561-
arguments: [node.left]
562-
}
563-
node.left = leftReplacementNode;
564-
}
565-
// Replace the logical operator with a call expression
566-
// in other words a call to BaseNode.or(), .and() etc.
567-
node.type = 'CallExpression';
568-
node.callee = {
569-
type: 'MemberExpression',
570-
object: node.left,
571-
property: {
572-
type: 'Identifier',
573-
name: replaceBinaryOperator(node.operator),
574-
},
575-
};
576-
node.arguments = [node.right];
577-
},
541+
BinaryExpression: transformBinaryOrLogical,
542+
LogicalExpression: transformBinaryOrLogical,
543+
544+
578545
ConditionalExpression(node, state, ancestors) {
579546
if (ancestors.some(a => nodeIsUniform(a) || nodeIsUniformCallbackFn(a, state.uniformCallbackNames))) {
580547
return;

src/type/textCore.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,13 +1587,6 @@ function textCore(p5, fn) {
15871587
if (typeof weight === 'number') {
15881588
this.states.setValue('fontWeight', weight);
15891589
this._applyTextProperties();
1590-
1591-
// Safari works without weight set in the canvas style attribute, and actually
1592-
// has buggy behavior if it is present, using the wrong weight when drawing
1593-
// multiple times with different weights
1594-
if (!p5.prototype._isSafari()) {
1595-
this._setCanvasStyleProperty('font-variation-settings', `"wght" ${weight}`);
1596-
}
15971590
return;
15981591
}
15991592
// the getter

0 commit comments

Comments
 (0)