Skip to content

Commit ce973e2

Browse files
authored
Merge branch 'dev-2.0' into variable-font-perf
2 parents 549b44a + 8010b5d commit ce973e2

13 files changed

Lines changed: 327 additions & 29 deletions

File tree

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/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/webgl/3d_primitives.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,33 +1792,38 @@ function primitives3D(p5, fn){
17921792
const prevMode = this.states.textureMode;
17931793
this.states.setValue('textureMode', constants.NORMAL);
17941794
const prevOrder = this.bezierOrder();
1795-
this.bezierOrder(2);
1795+
this.bezierOrder(3);
17961796
this.beginShape();
17971797
const addUVs = (x, y) => [x, y, 0, (x - x1)/width, (y - y1)/height];
1798+
const rr = 0.5523; // kappa: 4*(sqrt(2)-1)/3, handle ratio for cubic bezier circle approximation
17981799
if (tr !== 0) {
17991800
this.vertex(...addUVs(x2 - tr, y1));
1800-
this.bezierVertex(...addUVs(x2, y1));
1801+
this.bezierVertex(...addUVs(x2 - tr + tr * rr, y1));
1802+
this.bezierVertex(...addUVs(x2, y1 + tr - tr * rr));
18011803
this.bezierVertex(...addUVs(x2, y1 + tr));
18021804
} else {
18031805
this.vertex(...addUVs(x2, y1));
18041806
}
18051807
if (br !== 0) {
18061808
this.vertex(...addUVs(x2, y2 - br));
1807-
this.bezierVertex(...addUVs(x2, y2));
1809+
this.bezierVertex(...addUVs(x2, y2 - br + br * rr));
1810+
this.bezierVertex(...addUVs(x2 - br + rr * br, y2));
18081811
this.bezierVertex(...addUVs(x2 - br, y2));
18091812
} else {
18101813
this.vertex(...addUVs(x2, y2));
18111814
}
18121815
if (bl !== 0) {
18131816
this.vertex(...addUVs(x1 + bl, y2));
1814-
this.bezierVertex(...addUVs(x1, y2));
1817+
this.bezierVertex(...addUVs(x1 + bl - bl * rr, y2));
1818+
this.bezierVertex(...addUVs(x1, y2 - bl + bl * rr));
18151819
this.bezierVertex(...addUVs(x1, y2 - bl));
18161820
} else {
18171821
this.vertex(...addUVs(x1, y2));
18181822
}
18191823
if (tl !== 0) {
18201824
this.vertex(...addUVs(x1, y1 + tl));
1821-
this.bezierVertex(...addUVs(x1, y1));
1825+
this.bezierVertex(...addUVs(x1, y1 + tl - tl * rr));
1826+
this.bezierVertex(...addUVs(x1 + tl - tl * rr, y1));
18221827
this.bezierVertex(...addUVs(x1 + tl, y1));
18231828
} else {
18241829
this.vertex(...addUVs(x1, y1));

src/webgl/loading.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ function loading(p5, fn){
629629
model.vertexColors.push(1);
630630
} else {
631631
hasColorlessVertices = true;
632+
model.vertexColors.push(-1, -1, -1, -1);
632633
}
633634
} else {
634635
face.push(usedVerts[vertString][currentMaterial]);
@@ -650,9 +651,8 @@ function loading(p5, fn){
650651
if (model.vertexNormals.length === 0) {
651652
model.computeNormals();
652653
}
653-
if (hasColoredVertices === hasColorlessVertices) {
654-
// If both are true or both are false, throw an error because the model is inconsistent
655-
throw new Error('Model coloring is inconsistent. Either all vertices should have colors or none should.');
654+
if (!hasColoredVertices) {
655+
model.vertexColors = [];
656656
}
657657

658658
return model;

src/webgl/p5.RendererGL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ class RendererGL extends Renderer3D {
529529

530530
/**
531531
* Loads the pixels data for this canvas into the pixels[] attribute.
532-
* Note that updatePixels() and set() do not work.
532+
* Note that set() does not work.
533533
* Any pixel manipulation must be done directly to the pixels[] array.
534534
*
535535
* @private

test/unit/io/loadModel.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,27 @@ suite('loadModel', function() {
7979
assert.deepEqual(model.vertexColors, expectedColors);
8080
});
8181

82-
test('inconsistent vertex coloring throws error', async function() {
83-
// Attempt to load the model and catch the error
84-
await expect(mockP5Prototype.loadModel(inconsistentColorObjFile))
85-
.rejects
86-
.toThrow('Model coloring is inconsistent. Either all vertices should have colors or none should.');
82+
test('mixed material coloring loads model with sentinel colors for uncolored vertices', async function() {
83+
const model = await mockP5Prototype.loadModel(inconsistentColorObjFile);
84+
assert.instanceOf(model, Geometry);
85+
assert.equal(
86+
model.vertexColors.length,
87+
model.vertices.length * 4,
88+
'vertexColors should have four entries per vertex'
89+
);
90+
const hasSentinel = model.vertexColors.some(
91+
(_, i) =>
92+
i % 4 === 0 &&
93+
model.vertexColors[i] === -1 &&
94+
model.vertexColors[i + 1] === -1 &&
95+
model.vertexColors[i + 2] === -1 &&
96+
model.vertexColors[i + 3] === -1
97+
);
98+
const hasRealColor = model.vertexColors.some(
99+
(_, i) => i % 4 === 0 && model.vertexColors[i] !== -1
100+
);
101+
assert.isTrue(hasSentinel, 'Uncolored vertices should have sentinel color');
102+
assert.isTrue(hasRealColor, 'Colored vertices should retain their color');
87103
});
88104

89105
test('missing MTL file shows OBJ model without vertexColors', async function() {

test/unit/visual/cases/webgl.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,17 @@ visualSuite('WebGL', function() {
15061506
});
15071507
});
15081508

1509+
visualSuite('2D Shapes', function() {
1510+
visualTest('rect() rounded into a circle', function(p5, screenshot) {
1511+
p5.createCanvas(50, 50, p5.WEBGL);
1512+
p5.background(255);
1513+
p5.noStroke();
1514+
p5.fill('red');
1515+
p5.rect(-20, -20, 40, 40, 20);
1516+
screenshot();
1517+
});
1518+
});
1519+
15091520
visualSuite('3D Primitives', function() {
15101521
visualTest('cylinder() renders correctly', function(p5, screenshot) {
15111522
p5.createCanvas(100, 100, p5.WEBGL);
612 Bytes
Loading
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"numScreenshots": 1
3+
}
-53 Bytes
Loading

0 commit comments

Comments
 (0)