Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
17 changes: 15 additions & 2 deletions preview/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
const sketch = function (p) {
let fbo;
let sh;
let ssh;

p.setup = async function () {
await p.createCanvas(400, 400, p.WEBGPU);
sh = p.baseMaterialShader().modify({
Expand All @@ -37,18 +39,29 @@
return result;
}`,
})
ssh = p.baseStrokeShader().modify({
uniforms: {
'f32 time': () => p.millis(),
},
'StrokeVertex getWorldInputs': `(inputs: StrokeVertex) {
var result = inputs;
result.position.y += 40.0 * sin(uniforms.time * 0.01);
return result;
}`,
})
};

p.draw = function () {
const t = p.millis() * 0.008;
p.background(200);
p.noStroke();
p.shader(sh);
p.strokeShader(ssh)
p.ambientLight(50);
p.directionalLight(100, 100, 100, 0, 1, -1);
p.pointLight(155, 155, 155, 0, -200, 500);
p.specularMaterial(255);
p.shininess(300);
p.stroke('white')
for (const [i, c] of ['red', 'lime', 'blue'].entries()) {
p.push();
p.fill(c);
Expand All @@ -67,4 +80,4 @@
</script>
</body>

</html>
</html>
26 changes: 5 additions & 21 deletions src/core/p5.Renderer3D.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import { RenderBuffer } from "../webgl/p5.RenderBuffer";
import { Image } from "../image/p5.Image";
import { Texture } from "../webgl/p5.Texture";

export function getStrokeDefs() {
export function getStrokeDefs(shaderConstant) {
const STROKE_CAP_ENUM = {};
const STROKE_JOIN_ENUM = {};
let lineDefs = "";
const defineStrokeCapEnum = function (key, val) {
lineDefs += `#define STROKE_CAP_${key} ${val}\n`;
lineDefs += shaderConstant(`STROKE_CAP_${key}`, `${val}`, 'u32');
STROKE_CAP_ENUM[constants[key]] = val;
};
const defineStrokeJoinEnum = function (key, val) {
lineDefs += `#define STROKE_JOIN_${key} ${val}\n`;
lineDefs += shaderConstant(`STROKE_JOIN_${key}`, `${val}`, 'u32');
STROKE_JOIN_ENUM[constants[key]] = val;
};

Expand All @@ -41,7 +41,7 @@ export function getStrokeDefs() {
return { STROKE_CAP_ENUM, STROKE_JOIN_ENUM, lineDefs };
}

const { STROKE_CAP_ENUM, STROKE_JOIN_ENUM } = getStrokeDefs();
const { STROKE_CAP_ENUM, STROKE_JOIN_ENUM } = getStrokeDefs(()=>"");

export class Renderer3D extends Renderer {
constructor(pInst, w, h, isMainCanvas, elt) {
Expand Down Expand Up @@ -563,7 +563,6 @@ export class Renderer3D extends Renderer {
}

_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})

shader.unbindShader();
}
Expand Down
31 changes: 24 additions & 7 deletions src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import filterInvertFrag from "./shaders/filters/invert.frag";
import filterThresholdFrag from "./shaders/filters/threshold.frag";
import filterShaderVert from "./shaders/filters/default.vert";

const { lineDefs } = getStrokeDefs();
const { lineDefs } = getStrokeDefs((n, v) => `#define ${n} ${v};\n`);

const defaultShaders = {
normalVert,
Expand Down Expand Up @@ -276,7 +276,24 @@ class RendererGL extends Renderer3D {

if (!glBuffers) return;

if (glBuffers.indexBuffer) {
if (this._curShader.shaderType === 'stroke'){
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"
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be missing a } here

}
} else if (glBuffers.indexBuffer) {
this._bindBuffer(glBuffers.indexBuffer, gl.ELEMENT_ARRAY_BUFFER);

// If this model is using a Uint32Array we need to ensure the
Expand Down Expand Up @@ -1157,7 +1174,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 +1495,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 Expand Up @@ -1659,7 +1676,7 @@ class RendererGL extends Renderer3D {
//////////////////////////////////////////////
// Shader hooks
//////////////////////////////////////////////
fillHooks(shader, src, shaderType) {
populateHooks(shader, src, shaderType) {
const main = 'void main';
if (!src.includes(main)) return src;

Expand Down
2 changes: 1 addition & 1 deletion src/webgl/p5.Shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class Shader {
}

shaderSrc(src, shaderType) {
return this._renderer.fillHooks(this, src, shaderType);
return this._renderer.populateHooks(this, src, shaderType);
}

/**
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
90 changes: 63 additions & 27 deletions src/webgpu/p5.RendererWebGPU.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Renderer3D } from '../core/p5.Renderer3D';
import { Renderer3D, getStrokeDefs } 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';
import { materialVertexShader, materialFragmentShader } from './shaders/material';

const { lineDefs } = getStrokeDefs((n, v, t) => `const ${n}: ${t} = ${v};\n`);

class RendererWebGPU extends Renderer3D {
constructor(pInst, w, h, isMainCanvas, elt) {
super(pInst, w, h, isMainCanvas, elt)
Expand Down Expand Up @@ -457,7 +462,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 @@ -481,7 +485,6 @@ class RendererWebGPU extends Renderer3D {
],
});
}

return layouts;
}

Expand Down Expand Up @@ -516,7 +519,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 @@ -557,8 +562,9 @@ class RendererWebGPU extends Renderer3D {
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 @@ -581,34 +587,33 @@ class RendererWebGPU extends Renderer3D {
};

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

const currentShader = this._curShader;
passEncoder.setPipeline(currentShader.getPipeline(this._shaderOptions({ mode })));
// Bind vertex buffers
for (const buffer of this._getVertexBuffers(this._curShader)) {
for (const buffer of this._getVertexBuffers(currentShader)) {
passEncoder.setVertexBuffer(
this._curShader.attributes[buffer.attr].location,
currentShader.attributes[buffer.attr].location,
buffers[buffer.dst],
0
);
}

// Bind uniforms
this._packUniforms(this._curShader);
this.device.queue.writeBuffer(
this._curShader._uniformBuffer,
currentShader._uniformBuffer,
0,
this._curShader._uniformData.buffer,
this._curShader._uniformData.byteOffset,
this._curShader._uniformData.byteLength
currentShader._uniformData.buffer,
currentShader._uniformData.byteOffset,
currentShader._uniformData.byteLength
);

// Bind sampler/texture uniforms
for (const [group, entries] of this._curShader._groupEntries) {
for (const [group, entries] of currentShader._groupEntries) {
const bgEntries = entries.map(entry => {
if (group === 0 && entry.binding === 0) {
return {
binding: 0,
resource: { buffer: this._curShader._uniformBuffer },
resource: { buffer: currentShader._uniformBuffer },
};
}

Expand All @@ -620,22 +625,27 @@ class RendererWebGPU extends Renderer3D {
};
});

const layout = this._curShader._bindGroupLayouts[group];
const layout = currentShader._bindGroupLayouts[group];
const bindGroup = this.device.createBindGroup({
layout,
entries: bgEntries,
});

passEncoder.setBindGroup(group, bindGroup);
}

// Bind index buffer and issue draw
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);
if (currentShader.shaderType === "fill") {
// Bind index buffer and issue draw
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);
}
}

if (buffers.lineVerticesBuffer && currentShader.shaderType === "stroke") {
passEncoder.draw(geometry.lineVertices.length / 3, count, 0, 0);
}

passEncoder.end();
Expand Down Expand Up @@ -788,7 +798,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 @@ -941,6 +950,33 @@ class RendererWebGPU extends Renderer3D {
return this._defaultColorShader;
}

_getLineShader() {
if (!this._defaultLineShader) {
this._defaultLineShader = new Shader(
this,
lineDefs + lineVertexShader,
lineDefs + lineFragmentShader,
{
vertex: {
"void beforeVertex": "() {}",
"StrokeVertex getObjectInputs": "(inputs: StrokeVertex) { return inputs; }",
"StrokeVertex getWorldInputs": "(inputs: StrokeVertex) { return inputs; }",
"StrokeVertex getCameraInputs": "(inputs: StrokeVertex) { return inputs; }",
"void afterVertex": "() {}",
},
fragment: {
"void beforeFragment": "() {}",
"Inputs getPixelInputs": "(inputs: Inputs) { return inputs; }",
"vec4<f32> getFinalColor": "(color: vec4<f32>) { return color; }",
"bool shouldDiscard": "(outside: bool) { return outside; };",
"void afterFragment": "() {}",
},
}
);
}
return this._defaultLineShader;
}

//////////////////////////////////////////////
// Setting
//////////////////////////////////////////////
Expand All @@ -956,7 +992,7 @@ class RendererWebGPU extends Renderer3D {
//////////////////////////////////////////////
// Shader hooks
//////////////////////////////////////////////
fillHooks(shader, src, shaderType) {
populateHooks(shader, src, shaderType) {
if (!src.includes('fn main')) return src;

// Apply some p5-specific preprocessing. WGSL doesn't have preprocessor
Expand Down
Loading
Loading