Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
Next Next commit
added stroke shader, currently not working
  • Loading branch information
lukeplowden committed Jun 14, 2025
commit 77a9733d418918e8032db02f09372135fbf66a17
33 changes: 10 additions & 23 deletions preview/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,19 @@
let sh;
p.setup = async function () {
await p.createCanvas(400, 400, p.WEBGPU);
sh = p.baseColorShader().modify({
uniforms: {
'f32 time': () => p.millis(),
},
'Vertex getWorldInputs': `(inputs: Vertex) {
var result = inputs;
result.position.y += 40.0 * sin(uniforms.time * 0.01);
return result;
}`,
})
};

p.disableFriendlyErrors = true;
p.draw = function () {
p.orbitControl()
const t = p.millis() * 0.008;
p.background(200);
p.noStroke();
p.shader(sh);
for (const [i, c] of ['red', 'lime', 'blue'].entries()) {
p.push();
p.background(0);
// p.noStroke();
for (const [i, c] of ['red'].entries()) {
p.stroke(0);
p.strokeWeight(10);
p.push();
p.fill(c);
p.translate(
p.width/3 * p.sin(t + i * Math.E),
0, //p.width/3 * p.sin(t * 0.9 + i * Math.E + 0.2),
p.width/3 * p.sin(t * 1.2 + i * Math.E + 0.3),
)
p.sphere(30);
p.sphere(60, 4, 2);
p.pop();
}
};
Expand All @@ -62,4 +49,4 @@
</script>
</body>

</html>
</html>
22 changes: 3 additions & 19 deletions src/core/p5.Renderer3D.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,13 +557,12 @@ export class Renderer3D extends Renderer {
geometry.hasFillTransparency()
);

this._drawBuffers(geometry, { mode, count });
this._drawBuffers(geometry, { mode, count }, false);

shader.unbindShader();
}

_drawStrokes(geometry, { count } = {}) {
const gl = this.GL;

this._useLineColor = geometry.vertexStrokeColors.length > 0;

Expand All @@ -584,22 +583,7 @@ export class Renderer3D extends Renderer {
geometry.hasStrokeTransparency()
);

if (count === 1) {
gl.drawArrays(gl.TRIANGLES, 0, geometry.lineVertices.length / 3);
} else {
try {
gl.drawArraysInstanced(
gl.TRIANGLES,
0,
geometry.lineVertices.length / 3,
count
);
} catch (e) {
console.log(
"🌸 p5.js says: Instancing is only supported in WebGL2 mode"
);
}
}
this._drawBuffers(geometry, {count}, true)

shader.unbindShader();
}
Expand Down Expand Up @@ -1430,7 +1414,7 @@ export class Renderer3D extends Renderer {
this.scratchMat3.inverseTranspose4x4(this.states.uViewMatrix);
shader.setUniform("uCameraRotation", this.scratchMat3.mat3);
}
shader.setUniform("uViewport", this._viewport);
shader.setUniform("uViewport", [0, 0, 400, 400]);
}

_setStrokeUniforms(strokeShader) {
Expand Down
32 changes: 28 additions & 4 deletions src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,33 @@ class RendererGL extends Renderer3D {
}
}

// Stroke version for now:
//
// {
// const gl = this.GL;
// // move this to _drawBuffers ?
// if (count === 1) {
// gl.drawArrays(gl.TRIANGLES, 0, geometry.lineVertices.length / 3);
// } else {
// try {
// gl.drawArraysInstanced(
// gl.TRIANGLES,
// 0,
// geometry.lineVertices.length / 3,
// count
// );
// } catch (e) {
// console.log(
// "🌸 p5.js says: Instancing is only supported in WebGL2 mode"
// );
// }
// }
// }

_drawBuffers(geometry, { mode = constants.TRIANGLES, count }) {
const gl = this.GL;
const glBuffers = this.geometryBufferCache.getCached(geometry);
//console.log(glBuffers);

if (!glBuffers) return;

Expand Down Expand Up @@ -1157,7 +1181,7 @@ class RendererGL extends Renderer3D {

if (indices) {
const buffer = gl.createBuffer();
this.renderer._bindBuffer(buffer, gl.ELEMENT_ARRAY_BUFFER, indices, indexType);
this._bindBuffer(buffer, gl.ELEMENT_ARRAY_BUFFER, indices, indexType);

buffers.indexBuffer = buffer;

Expand Down Expand Up @@ -1478,9 +1502,9 @@ class RendererGL extends Renderer3D {
createTexture({ width, height, format, dataType }) {
const gl = this.GL;
const tex = gl.createTexture();
this.gl.bindTexture(gl.TEXTURE_2D, tex);
this.gl.texImage2D(gl.TEXTURE_2D, 0, this.gl.RGBA, width, height, 0,
gl.RGBA, this.gl.UNSIGNED_BYTE, null);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
// TODO use format and data type
return { texture: tex, glFormat: gl.RGBA, glDataType: gl.UNSIGNED_BYTE };
}
Expand Down
1 change: 1 addition & 0 deletions src/webgl/shaders/line.vert
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ void main() {
}
} else {
vec2 tangent = aTangentIn == vec3(0.) ? tangentOut : tangentIn;

vTangent = tangent;
vec2 normal = vec2(-tangent.y, tangent.x);

Expand Down
51 changes: 38 additions & 13 deletions src/webgpu/p5.RendererWebGPU.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Renderer3D } from '../core/p5.Renderer3D';
import { Shader } from '../webgl/p5.Shader';
import * as constants from '../core/constants';
import { colorVertexShader, colorFragmentShader } from './shaders/color';
import { lineVertexShader, lineFragmentShader} from './shaders/line';

class RendererWebGPU extends Renderer3D {
constructor(pInst, w, h, isMainCanvas, elt) {
Expand Down Expand Up @@ -248,7 +249,6 @@ class RendererWebGPU extends Renderer3D {
.filter(u => !u.isSampler)
.reduce((sum, u) => sum + u.alignedBytes, 0);
shader._uniformData = new Float32Array(uniformSize / 4);

shader._uniformBuffer = this.device.createBuffer({
size: uniformSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
Expand Down Expand Up @@ -453,7 +453,6 @@ class RendererWebGPU extends Renderer3D {
for (const attrName in shader.attributes) {
const attr = shader.attributes[attrName];
if (!attr || attr.location === -1) continue;

// Get the vertex buffer info associated with this attribute
const renderBuffer =
this.buffers[shader.shaderType].find(buf => buf.attr === attrName) ||
Expand All @@ -477,7 +476,6 @@ class RendererWebGPU extends Renderer3D {
],
});
}

return layouts;
}

Expand Down Expand Up @@ -512,7 +510,9 @@ class RendererWebGPU extends Renderer3D {

_useShader(shader, options) {}

_updateViewport() {}
_updateViewport() {
this._viewport = [0, 0, this.width, this.height];
}

zClipRange() {
return [0, 1];
Expand Down Expand Up @@ -548,13 +548,14 @@ class RendererWebGPU extends Renderer3D {
// Rendering
//////////////////////////////////////////////

_drawBuffers(geometry, { mode = constants.TRIANGLES, count = 1 }) {
_drawBuffers(geometry, { mode = constants.TRIANGLES, count = 1 }, stroke) {
const buffers = this.geometryBufferCache.getCached(geometry);
if (!buffers) return;

const commandEncoder = this.device.createCommandEncoder();
const currentTexture = this.drawingContext.getCurrentTexture();
const colorAttachment = {
view: this.drawingContext.getCurrentTexture().createView(),
view: currentTexture.createView(),
loadOp: "load",
storeOp: "store",
};
Expand All @@ -578,7 +579,6 @@ class RendererWebGPU extends Renderer3D {

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(this._curShader.getPipeline(this._shaderOptions({ mode })));

// Bind vertex buffers
for (const buffer of this._getVertexBuffers(this._curShader)) {
passEncoder.setVertexBuffer(
Expand All @@ -587,9 +587,9 @@ class RendererWebGPU extends Renderer3D {
0
);
}

// Bind uniforms
this._packUniforms(this._curShader);
console.log(this._curShader);
this.device.queue.writeBuffer(
this._curShader._uniformBuffer,
0,
Expand Down Expand Up @@ -621,18 +621,21 @@ class RendererWebGPU extends Renderer3D {
layout,
entries: bgEntries,
});

passEncoder.setBindGroup(group, bindGroup);
}

if (buffers.lineVerticesBuffer && geometry.lineVertices && stroke) {
passEncoder.draw(geometry.lineVertices.length / 3, count, 0, 0);
}
// Bind index buffer and issue draw
if (!stroke) {
if (buffers.indexBuffer) {
const indexFormat = buffers.indexFormat || "uint16";
passEncoder.setIndexBuffer(buffers.indexBuffer, indexFormat);
passEncoder.drawIndexed(geometry.faces.length * 3, count, 0, 0, 0);
} else {
passEncoder.draw(geometry.vertices.length, count, 0, 0);
}
}}

passEncoder.end();
this.queue.submit([commandEncoder.finish()]);
Expand All @@ -644,6 +647,7 @@ class RendererWebGPU extends Renderer3D {

_packUniforms(shader) {
let offset = 0;
let i = 0;
for (const name in shader.uniforms) {
const uniform = shader.uniforms[name];
if (uniform.isSampler) continue;
Expand All @@ -661,7 +665,7 @@ class RendererWebGPU extends Renderer3D {
new RegExp(`struct\\s+${structName}\\s*\\{([^\\}]+)\\}`)
);
if (!structMatch) {
throw new Error(`Can't find a struct definition for ${structName}`);
throw new Error(`Can't find a struct defnition for ${structName}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a character got lost in here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm true sorry, growing pains from switching text editor

}

const structBody = structMatch[1];
Expand Down Expand Up @@ -716,7 +720,6 @@ class RendererWebGPU extends Renderer3D {
}
const structType = uniformVarMatch[2];
const uniforms = this._parseStruct(shader.vertSrc(), structType);

// Extract samplers from group bindings
const samplers = [];
const samplerRegex = /@group\((\d+)\)\s*@binding\((\d+)\)\s*var\s+(\w+)\s*:\s*(\w+);/g;
Expand Down Expand Up @@ -835,6 +838,28 @@ class RendererWebGPU extends Renderer3D {
return this._defaultColorShader;
}

_getLineShader() {
if (!this._defaultLineShader) {
this._defaultLineShader = new Shader(
this,
lineVertexShader,
lineFragmentShader,
{
vertex: {
"void beforeVertex": "() {}",
"Vertex getObjectInputs": "(inputs: Vertex) { return inputs; }",
"Vertex getWorldInputs": "(inputs: Vertex) { return inputs; }",
"Vertex getCameraInputs": "(inputs: Vertex) { return inputs; }",
},
fragment: {
"vec4<f32> getFinalColor": "(color: vec4<f32>) { return color; }"
},
}
);
}
return this._defaultLineShader;
}

//////////////////////////////////////////////
// Setting
//////////////////////////////////////////////
Expand Down Expand Up @@ -921,7 +946,7 @@ class RendererWebGPU extends Renderer3D {
}
}

console.log(preMain + '\n' + defines + hooks + main + postMain)
//console.log(preMain + '\n' + defines + hooks + main + postMain)
return preMain + '\n' + defines + hooks + main + postMain;
}
}
Expand Down
Loading