-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Adds createFilterShader() and custom shader support to the webGL filter() function #6237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 49 commits
16def01
c7abb8c
9dbe595
a096914
87f347a
e0126bf
cb1979b
644e61a
628fc18
359d16b
e857d5b
a762869
2eb64a0
0c5d0ff
10d85ff
f324437
7f39f69
fc50e52
f3a41e7
7888ad4
b52a467
02113bb
be7c01c
aa1f048
5d50053
4e52976
590d025
f2e69ae
6e4c04e
f23d072
034ebb5
7bfa2f2
f6fbdc2
86cb79d
bf282f3
25424c7
d1dd620
fa178ba
68ad8ae
c039991
c476759
4b1e56e
ec76701
8220071
44ad94f
a532146
479aca3
4250399
5abd47d
51aa874
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import './p5.Shader'; | |
import './p5.Camera'; | ||
import '../core/p5.Renderer'; | ||
import './p5.Matrix'; | ||
import './p5.Framebuffer'; | ||
import { readFileSync } from 'fs'; | ||
import { join } from 'path'; | ||
|
||
|
@@ -577,6 +578,10 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
// set of framebuffers in use | ||
this.framebuffers = new Set(); | ||
|
||
// for post processing step | ||
this.filterShader = undefined; | ||
this.filterGraphicsLayer = undefined; | ||
|
||
this.textureMode = constants.IMAGE; | ||
// default wrap settings | ||
this.textureWrapX = constants.CLAMP; | ||
|
@@ -873,12 +878,61 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
this.curStrokeJoin = join; | ||
} | ||
|
||
filter(filterType) { | ||
// filter can be achieved using custom shaders. | ||
// https://github.com/aferriss/p5jsShaderExamples | ||
// https://itp-xstory.github.io/p5js-shaders/#/ | ||
p5._friendlyError('filter() does not work in WEBGL mode'); | ||
filter(args) { | ||
// Couldn't create graphics in RendererGL constructor | ||
// (led to infinite loop) | ||
// so it's just created here once on the initial filter call. | ||
if (!this.filterGraphicsLayer) { | ||
// the real _pInst is buried when this is a secondary p5.Graphics | ||
const pInst = | ||
this._pInst instanceof p5.Graphics ? this._pInst._pInst : this._pInst; | ||
// create secondary layer | ||
this.filterGraphicsLayer = | ||
new p5.Graphics( | ||
this.width, | ||
this.height, | ||
constants.WEBGL, | ||
pInst | ||
); | ||
} | ||
let pg = this.filterGraphicsLayer; | ||
|
||
if (typeof args[0] === 'string') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this the right check? I think we need to know if args[0] is a p5.shader, or a filter constant ( BLUR, INVERT, etc), and if not, we print an error. Aren't the filter constants strings? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's the check. Although there shouldn't need to be a third case handling errors, since the args get validated in the parent Right now the string / filter constant case has an error placeholder. It will be replaced in the next PR that implements the shader versions of filter constants. And the current code handles the p5.Shader case. |
||
// TODO, handle filter constants: | ||
// this.filterShader = map(args[0], {GRAYSCALE: grayscaleShader, ...}) | ||
// filterOperationParameter = undefined or args[1] | ||
p5._friendlyError('webgl filter implementation in progress'); | ||
return; | ||
} | ||
let userShader = args[0]; | ||
|
||
// Copy the user shader once on the initial filter call, | ||
// since it has to be bound to pg and not main | ||
let isSameUserShader = ( | ||
this.filterShader !== undefined && | ||
userShader._vertSrc === this.filterShader._vertSrc && | ||
userShader._fragSrc === this.filterShader._fragSrc | ||
); | ||
if (!isSameUserShader) { | ||
this.filterShader = | ||
new p5.Shader(pg._renderer, userShader._vertSrc, userShader._fragSrc); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're supplying a shader created with createFilterShader() can we skip this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed to skip this tiny optimization for now |
||
this.filterShader.parentShader = userShader; | ||
} | ||
|
||
// apply shader to pg | ||
pg.shader(this.filterShader); | ||
this.filterShader.setUniform('tex0', this); | ||
pg.rect(0,0,this.width,this.height); | ||
|
||
// draw pg contents onto main renderer | ||
this._pInst.push(); | ||
this._pInst.noStroke(); // don't draw triangles for plane() geometry | ||
this._pInst.scale(1, -1); // vertically flip output | ||
this._pInst.texture(pg); | ||
this._pInst.plane(this.width, this.height); | ||
this._pInst.pop(); | ||
} | ||
|
||
blendMode(mode) { | ||
if ( | ||
mode === constants.DARKEST || | ||
|
@@ -1104,6 +1158,11 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
// can also update their size | ||
framebuffer._canvasSizeChanged(); | ||
} | ||
|
||
// resize filter graphics layer | ||
if (this.filterGraphicsLayer) { | ||
p5.Renderer.prototype.resize.call(this.filterGraphicsLayer, w, h); | ||
} | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<title></title> | ||
<link rel="stylesheet" href="../../styles.css"> | ||
<script language="javascript" type="text/javascript" src="../../../../lib/p5.js"></script> | ||
<script language="javascript" type="text/javascript" src="sketch.js"></script> | ||
<script src="../stats.js"></script> | ||
</head> | ||
|
||
<body> | ||
</body> | ||
|
||
</html> |
Uh oh!
There was an error while loading. Please reload this page.