Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 64 additions & 84 deletions src/core/p5.Renderer3D.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ export class Renderer3D extends Renderer {

this._curShader = undefined;
this.drawShapeCount = 1;
// Set by the instances() wrapper; undefined means "no instancing".
this._instanceCount = undefined;

this.scratchMat3 = new Matrix(3);

Expand Down Expand Up @@ -530,7 +532,7 @@ export class Renderer3D extends Renderer {
}

endShape(mode, count) {
this.drawShapeCount = count;
this.drawShapeCount = count ?? this._instanceCount ?? 1;
super.endShape(mode, count);
}

Expand All @@ -547,7 +549,8 @@ export class Renderer3D extends Renderer {
this.updateShapeVertexProperties();
}

model(model, count = 1) {
model(model, count) {
count = count ?? this._instanceCount ?? 1;
if (model.vertices.length > 0) {
if (this.geometryBuilder) {
this.geometryBuilder.addRetained(model);
Expand Down Expand Up @@ -679,6 +682,7 @@ export class Renderer3D extends Renderer {
}

_drawGeometryScaled(model, scaleX, scaleY, scaleZ) {
const count = this._instanceCount || 1;
let originalModelMatrix = this.states.uModelMatrix;
this.states.setValue("uModelMatrix", this.states.uModelMatrix.clone());
try {
Expand All @@ -687,7 +691,7 @@ export class Renderer3D extends Renderer {
if (this.geometryBuilder) {
this.geometryBuilder.addRetained(model);
} else {
this._drawGeometry(model);
this._drawGeometry(model, { count });
}
} finally {
this.states.setValue("uModelMatrix", originalModelMatrix);
Expand Down Expand Up @@ -2034,61 +2038,55 @@ function renderer3D(p5, fn) {
* item is accessed by index, and its properties are available by name.
*
* ```js example
* let instanceData;
* let instancesShader;
* let instance;
* let count = 5;
*
* async function setup() {
* await createCanvas(200, 200, WEBGPU);
*
* let data = [];
* for (let i = 0; i < count; i++) {
* data.push({
* position: createVector(
* random(-1, 1) * width / 2,
* random(-1, 1) * height / 2,
* 0,
* ),
* color: color(
* random(255),
* random(255),
* random(255)
* )
* });
* }
* instanceData = createStorage(data);
* instance = buildGeometry(drawInstance);
* instancesShader = buildMaterialShader(drawInstances);
* describe('Five spheres at random positions, each a different random color.');
* }
*
* function drawInstance() {
* sphere(15);
* }
*
* function drawInstances() {
* let data = uniformStorage(instanceData);
* let itemColor = sharedVec4();
*
* worldInputs.begin();
* let item = data[instanceID()];
* itemColor = item.color;
* worldInputs.position += item.position;
* worldInputs.end();
*
* finalColor.begin();
* finalColor.set(itemColor);
* finalColor.end();
* }
*
* function draw() {
* background(220);
* lights();
* noStroke();
* shader(instancesShader);
* model(instance, count);
* }
* let instanceData;
* let instancesShader;
* let count = 5;
*
* async function setup() {
* await createCanvas(200, 200, WEBGPU);
*
* let data = [];
* for (let i = 0; i < count; i++) {
* data.push({
* position: createVector(
* random(-1, 1) * width / 2,
* random(-1, 1) * height / 2,
* 0,
* ),
* color: color(
* random(255),
* random(255),
* random(255)
* )
* });
* }
* instanceData = createStorage(data);
* instancesShader = buildMaterialShader(drawInstances);
* describe('Five spheres at random positions, each a different random color.');
* }
*
* function drawInstances() {
* let data = uniformStorage(instanceData);
* let itemColor = sharedVec4();
*
* worldInputs.begin();
* let item = data[instanceIndex];
* itemColor = item.color;
* worldInputs.position += item.position;
* worldInputs.end();
*
* finalColor.begin();
* finalColor.set(itemColor);
* finalColor.end();
* }
*
* function draw() {
* background(220);
* lights();
* noStroke();
* shader(instancesShader);
* instances(count).sphere(15);
* }
* ```
*
* You can also store a plain list of numbers by passing an array of numbers.
Expand Down Expand Up @@ -2242,23 +2240,21 @@ function renderer3D(p5, fn) {
* initial data. Connect your iteration function to the storage by passing the storage
* into <a href="#/p5/uniformStorage">`uniformStorage`</a>.
*
* Often, compute shaders are paired with <a href="#/p5/model">`model(myGeometry, count)`</a>
* Often, compute shaders are paired with <a href="#/p5/instances">`instances(count)`</a>
* to draw one instance per object in the storage, and a shader that uses
* <a href="#/p5/instanceID">`instanceID()`</a> to position each instance.
* <a href="#/p5/instanceIndex">`instanceIndex`</a> to position each instance.
*
* ```js example
* let particles;
* let computeShader;
* let displayShader;
* let instance;
* const numParticles = 100;
*
* async function setup() {
* await createCanvas(100, 100, WEBGPU);
* particles = createStorage(makeParticles(width / 2, height / 2));
* computeShader = buildComputeShader(simulate);
* displayShader = buildMaterialShader(display);
* instance = buildGeometry(drawParticle);
* describe('100 orange particles shooting outward.');
* }
*
Expand All @@ -2275,10 +2271,6 @@ function renderer3D(p5, fn) {
* return data;
* }
*
* function drawParticle() {
* sphere(2);
* }
*
* function simulate() {
* let data = uniformStorage(particles);
* let idx = index.x;
Expand All @@ -2288,7 +2280,7 @@ function renderer3D(p5, fn) {
* function display() {
* let data = uniformStorage(particles);
* worldInputs.begin();
* let pos = data[instanceID()].position;
* let pos = data[instanceIndex].position;
* worldInputs.position.xy += pos - [width / 2, height / 2];
* worldInputs.end();
* }
Expand All @@ -2302,15 +2294,14 @@ function renderer3D(p5, fn) {
* noStroke();
* fill(255, 200, 50);
* shader(displayShader);
* model(instance, numParticles);
* instances(numParticles).sphere(2);
* }
* ```
*
* ```js example
* let particles;
* let computeShader;
* let displayShader;
* let instance;
* const numParticles = 50;
*
* async function setup() {
Expand All @@ -2333,14 +2324,9 @@ function renderer3D(p5, fn) {
*
* computeShader = buildComputeShader(simulate);
* displayShader = buildMaterialShader(display);
* instance = buildGeometry(drawParticle);
* describe('50 white spheres bouncing around the canvas.');
* }
*
* function drawParticle() {
* sphere(3);
* }
*
* function simulate() {
* let r = 3;
* let data = uniformStorage(particles);
Expand All @@ -2363,7 +2349,7 @@ function renderer3D(p5, fn) {
* function display() {
* let data = uniformStorage(particles);
* worldInputs.begin();
* let pos = data[instanceID()].position;
* let pos = data[instanceIndex].position;
* worldInputs.position.xy += pos;
* worldInputs.end();
* }
Expand All @@ -2375,7 +2361,7 @@ function renderer3D(p5, fn) {
* fill(255);
* lights();
* shader(displayShader);
* model(instance, numParticles);
* instances(numParticles).sphere(3);
* }
* ```
*
Expand Down Expand Up @@ -2412,7 +2398,6 @@ function renderer3D(p5, fn) {
* let particles;
* let computeShader;
* let displayShader;
* let instance;
* const numParticles = 50;
*
* async function setup() {
Expand All @@ -2435,14 +2420,9 @@ function renderer3D(p5, fn) {
*
* computeShader = buildComputeShader(simulate);
* displayShader = buildMaterialShader(display);
* instance = buildGeometry(drawParticle);
* describe('50 white spheres bouncing around the canvas.');
* }
*
* function drawParticle() {
* sphere(3);
* }
*
* function simulate() {
* let r = 3;
* let data = uniformStorage(particles);
Expand All @@ -2465,7 +2445,7 @@ function renderer3D(p5, fn) {
* function display() {
* let data = uniformStorage(particles);
* worldInputs.begin();
* let pos = data[instanceID()].position;
* let pos = data[instanceIndex].position;
* worldInputs.position.xy += pos;
* worldInputs.end();
* }
Expand All @@ -2477,7 +2457,7 @@ function renderer3D(p5, fn) {
* fill(255);
* lights();
* shader(displayShader);
* model(instance, numParticles);
* instances(numParticles).sphere(3);
* }
* ```
*
Expand Down
17 changes: 13 additions & 4 deletions src/shape/vertex.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,11 +833,20 @@ function vertex(p5, fn){
* describe('A row of four squares. Their colors transition from purple on the left to red on the right');
* }
*/
fn.endShape = function(mode, count = 1) {
fn.endShape = function(mode, count) {
// p5._validateParameters('endShape', arguments);
if (count < 1) {
console.log('🌸 p5.js says: You can not have less than one instance');
count = 1;
if (typeof mode === 'number') {
count = mode;
mode = undefined;
}

if (count !== undefined) {
if (count < 1) {
console.log('🌸 p5.js says: You can not have less than one instance');
count = 1;
} else {
count = Math.round(count);
}
}

this._renderer.endShape(mode, count);
Expand Down
Loading
Loading