Skip to content

Commit f300db5

Browse files
Merge branch 'dev-2.0' into stencil_test
2 parents ed26828 + 8ce0269 commit f300db5

File tree

18 files changed

+686
-179
lines changed

18 files changed

+686
-179
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"node ./utils/sample-linter.mjs"
2323
]
2424
},
25-
"version": "2.0.0-beta.2",
25+
"version": "2.0.0-beta.3",
2626
"dependencies": {
2727
"@davepagurek/bezier-path": "^0.0.2",
2828
"acorn": "^8.12.1",

src/image/filterRenderer2D.js

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ import filterThresholdFrag from '../webgl/shaders/filters/threshold.frag';
1414
import filterShaderVert from '../webgl/shaders/filters/default.vert';
1515
import { filterParamDefaults } from "./const";
1616

17+
18+
import filterBaseFrag from "../webgl/shaders/filters/base.frag";
19+
import filterBaseVert from "../webgl/shaders/filters/base.vert";
20+
import webgl2CompatibilityShader from "../webgl/shaders/webgl2Compatibility.glsl";
21+
1722
class FilterRenderer2D {
1823
/**
1924
* Creates a new FilterRenderer2D instance.
@@ -27,7 +32,12 @@ class FilterRenderer2D {
2732
this.canvas.height = pInst.height;
2833

2934
// Initialize the WebGL context
30-
this.gl = this.canvas.getContext('webgl');
35+
let webglVersion = constants.WEBGL2;
36+
this.gl = this.canvas.getContext('webgl2');
37+
if (!this.gl) {
38+
webglVersion = constants.WEBGL;
39+
this.gl = this.canvas.getContext('webgl');
40+
}
3141
if (!this.gl) {
3242
console.error("WebGL not supported, cannot apply filter.");
3343
return;
@@ -38,7 +48,7 @@ class FilterRenderer2D {
3848
registerEnabled: new Set(),
3949
_curShader: null,
4050
_emptyTexture: null,
41-
webglVersion: 'WEBGL',
51+
webglVersion,
4252
states: {
4353
textureWrapX: this.gl.CLAMP_TO_EDGE,
4454
textureWrapY: this.gl.CLAMP_TO_EDGE,
@@ -54,6 +64,8 @@ class FilterRenderer2D {
5464
},
5565
};
5666

67+
this._baseFilterShader = undefined;
68+
5769
// Store the fragment shader sources
5870
this.filterShaderSources = {
5971
[constants.BLUR]: filterBlurFrag,
@@ -90,6 +102,45 @@ class FilterRenderer2D {
90102
this._bindBufferData(this.texcoordBuffer, this.gl.ARRAY_BUFFER, this.texcoords);
91103
}
92104

105+
_webGL2CompatibilityPrefix(shaderType, floatPrecision) {
106+
let code = "";
107+
if (this._renderer.webglVersion === constants.WEBGL2) {
108+
code += "#version 300 es\n#define WEBGL2\n";
109+
}
110+
if (shaderType === "vert") {
111+
code += "#define VERTEX_SHADER\n";
112+
} else if (shaderType === "frag") {
113+
code += "#define FRAGMENT_SHADER\n";
114+
}
115+
if (floatPrecision) {
116+
code += `precision ${floatPrecision} float;\n`;
117+
}
118+
return code;
119+
}
120+
121+
baseFilterShader() {
122+
if (!this._baseFilterShader) {
123+
this._baseFilterShader = new Shader(
124+
this._renderer,
125+
this._webGL2CompatibilityPrefix("vert", "highp") +
126+
webgl2CompatibilityShader +
127+
filterBaseVert,
128+
this._webGL2CompatibilityPrefix("frag", "highp") +
129+
webgl2CompatibilityShader +
130+
filterBaseFrag,
131+
{
132+
vertex: {},
133+
fragment: {
134+
"vec4 getColor": `(FilterInputs inputs, in sampler2D canvasContent) {
135+
return getTexture(canvasContent, inputs.texCoord);
136+
}`,
137+
},
138+
}
139+
);
140+
}
141+
return this._baseFilterShader;
142+
}
143+
93144
/**
94145
* Set the current filter operation and parameter. If a customShader is provided,
95146
* that overrides the operation-based shader.

src/image/image.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,13 @@ function image(p5, fn){
287287
const framebuffer = args[0];
288288
temporaryGraphics = this.createGraphics(framebuffer.width,
289289
framebuffer.height);
290-
temporaryGraphics.pixelDensity(pixelDensity());
290+
temporaryGraphics.pixelDensity(framebuffer.pixelDensity());
291291
framebuffer.loadPixels();
292292
temporaryGraphics.loadPixels();
293293
temporaryGraphics.pixels.set(framebuffer.pixels);
294294
temporaryGraphics.updatePixels();
295295

296-
htmlCanvas = temporaryGraphics.elt;
296+
htmlCanvas = temporaryGraphics._renderer.canvas;
297297
args.shift();
298298
} else {
299299
htmlCanvas = this._curElement && this._curElement.elt;

src/webgl/material.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,82 @@ function material(p5, fn){
15201520
return this._renderer.baseMaterialShader();
15211521
};
15221522

1523+
/**
1524+
* Get the base shader for filters.
1525+
*
1526+
* You can then call <a href="#/p5.Shader/modify">`baseFilterShader().modify()`</a>
1527+
* and change the following hook:
1528+
*
1529+
* <table>
1530+
* <tr><th>Hook</th><th>Description</th></tr>
1531+
* <tr><td>
1532+
*
1533+
* `vec4 getColor`
1534+
*
1535+
* </td><td>
1536+
*
1537+
* Output the final color for the current pixel. It takes in two parameters:
1538+
* `FilterInputs inputs`, and `in sampler2D canvasContent`, and must return a color
1539+
* as a `vec4`.
1540+
*
1541+
* `FilterInputs inputs` is a scruct with the following properties:
1542+
* - `vec2 texCoord`, the position on the canvas, with coordinates between 0 and 1. Calling
1543+
* `getTexture(canvasContent, texCoord)` returns the original color of the current pixel.
1544+
* - `vec2 canvasSize`, the width and height of the sketch.
1545+
* - `vec2 texelSize`, the size of one real pixel relative to the size of the whole canvas.
1546+
* This is equivalent to `1 / (canvasSize * pixelDensity)`.
1547+
*
1548+
* `in sampler2D canvasContent` is a texture with the contents of the sketch, pre-filter. Call
1549+
* `getTexture(canvasContent, someCoordinate)` to retrieve the color of the sketch at that coordinate,
1550+
* with coordinate values between 0 and 1.
1551+
*
1552+
* </td></tr>
1553+
* </table>
1554+
*
1555+
* Most of the time, you will need to write your hooks in GLSL ES version 300. If you
1556+
* are using WebGL 1, write your hooks in GLSL ES 100 instead.
1557+
*
1558+
* @method baseFilterShader
1559+
* @beta
1560+
* @returns {p5.Shader} The filter shader
1561+
*
1562+
* @example
1563+
* <div modernizr='webgl'>
1564+
* <code>
1565+
* let img;
1566+
* let myShader;
1567+
*
1568+
* async function setup() {
1569+
* img = await loadImage('assets/bricks.jpg');
1570+
* createCanvas(100, 100, WEBGL);
1571+
* myShader = baseFilterShader().modify({
1572+
* uniforms: {
1573+
* 'float time': () => millis()
1574+
* },
1575+
* 'vec4 getColor': `(
1576+
* FilterInputs inputs,
1577+
* in sampler2D canvasContent
1578+
* ) {
1579+
* inputs.texCoord.y +=
1580+
* 0.01 * sin(time * 0.001 + inputs.position.x * 5.0);
1581+
* return getTexture(canvasContent, inputs.texCoord);
1582+
* }`
1583+
* });
1584+
* }
1585+
*
1586+
* function draw() {
1587+
* image(img, -50, -50);
1588+
* filter(myShader);
1589+
* describe('an image of bricks, distorting over time');
1590+
* }
1591+
* </code>
1592+
* </div>
1593+
*/
1594+
fn.baseFilterShader = function() {
1595+
return (this._renderer.filterRenderer || this._renderer)
1596+
.baseFilterShader();
1597+
};
1598+
15231599
/**
15241600
* Get the shader used by <a href="#/p5/normalMaterial">`normalMaterial()`</a>.
15251601
*

0 commit comments

Comments
 (0)