Skip to content

Commit 96874e7

Browse files
committed
v0.10.2: Enhance applyEffects with support for FBO, image, and video inputs (image/video support added)
1 parent 7eeed45 commit 96874e7

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,17 @@ The `applyShader` function applies a `shader` to a given `scene` and `target`, i
182182

183183
## Post-effects
184184

185-
Post-effects[^1] play a key role in dynamic visual rendering, allowing for the interactive blending of various shader effects such as _bloom_, _motion blur_, _ambient occlusion_, and _color grading_, into a rendered scene. A user-space array of `effects` may be sequentially applied to a source `layer` with `applyEffects(layer, effects, [uniforms], [flip])`. Example usage:
185+
Post-effects[^1] play a key role in dynamic visual rendering, allowing for the interactive blending of various shader effects such as _bloom_, _motion blur_, _ambient occlusion_, and _color grading_, into a rendered scene. A user-space array of `effects` may be sequentially applied to a `source` with `applyEffects(source, effects, [uniforms], [flip])`. Example usage:
186186

187187
```glsl
188188
// noise_shader
189-
uniform sampler2D blender; // <- shared layer should be named 'blender'
189+
uniform sampler2D blender; // <- shared source should be named 'blender'
190190
uniform float time;
191191
```
192192

193193
```glsl
194194
// bloom_shader
195-
uniform sampler2D blender; // <- shared layer should be named 'blender'
195+
uniform sampler2D blender; // <- shared source should be named 'blender'
196196
uniform sampler2D depth;
197197
```
198198

@@ -238,7 +238,7 @@ function keyPressed() {
238238
}
239239
```
240240

241-
1. `applyEffects(layer, effects, [uniforms = {}], [flip = true])`: Sequentially applies all effects (in the order they were added) to the source [p5.Framebuffer](https://p5js.org/reference/#/p5.Framebuffer) `layer`. The `uniforms` param map shader `keys` to their respective uniform values, formatted as `{ uniform_1_name: value_1, ..., uniform_n_name: value_n }`, provided that a `sampler2D uniform blender` variable is declared in each shader effect as a common layer. The `flip` boolean indicates whether the final image should be vertically flipped. This method processes each effect, applying its shader with the corresponding uniforms (with `applyShader`), and returns the final processed layer, now modified by all effects.
241+
1. `applyEffects(source, effects, [uniforms = {}], [flip = true])`: Sequentially applies all effects (in the order they were added) to the source, which can be a [p5.Framebuffer](https://p5js.org/reference/p5/p5.Framebuffer), [p5.Image](https://p5js.org/reference/p5/p5.Image/), or [p5.MediaElement](https://p5js.org/reference/p5/p5.MediaElement/). The `uniforms` param maps shader `keys` to their respective uniform values, formatted as `{ uniform_1_name: value_1, ..., uniform_n_name: value_n }`, provided that a `sampler2D uniform blender` variable is declared in each shader effect as a common fbo layer. The `flip` boolean indicates whether the final image should be vertically flipped. This method processes each effect, applying its shader with the corresponding uniforms (using `applyShader`), and returns the final processed source, now modified by all effects.
242242
2. `createBlender(effects, [options={}])`: [Creates](https://p5js.org/reference/#/p5/createFramebuffer) and attaches an fbo layer with specified `options` to each shader in the `effects` array. If `createBlender` is not called, `applyEffects` automatically generates a blender layer for each shader, utilizing default options.
243243
3. `removeBlender(effects)`: Removes the individual fbo layers associated with each shader in the `effects` array, freeing up resources by invoking [remove](https://p5js.org/reference/#/p5.Framebuffer/remove).
244244

p5.treegl.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
var Tree = (function (ext) {
1212
const INFO = {
1313
LIBRARY: 'p5.treegl',
14-
VERSION: '0.10.1',
14+
VERSION: '0.10.2',
1515
HOMEPAGE: 'https://github.com/VisualComputing/p5.treegl'
1616
};
1717
Object.freeze(INFO);
@@ -1193,6 +1193,10 @@ void main() {
11931193
}
11941194
}
11951195

1196+
// TODO decide what uniforms applyShader and applyEffect should emit (particularly flip stuff )
1197+
// Define also uniform and function names (should be the same) to those of uniforms,
1198+
// resolution may be refactored (as uniform with this name is already taken by p5)
1199+
11961200
/**
11971201
* Applies a shader to a specified rendering `target`, sets shader `uniforms`, and optionally
11981202
* executes a `scene` function with provided `options`. If no `scene` is specified, a default
@@ -1217,6 +1221,8 @@ void main() {
12171221
}
12181222
});
12191223
const { target, uniforms = {}, scene, options = {} } = config;
1224+
// TODO decide whether to emit this:
1225+
//uniforms.uMouse = this.mousePosition(options.flip); // TODO needs fine-tuning
12201226
target instanceof p5.Framebuffer && target.begin();
12211227
const context = target instanceof p5.Graphics ? target : this;
12221228
context === this ? context.push() : context._rendererState = context.push();
@@ -1240,13 +1246,13 @@ void main() {
12401246
}
12411247

12421248
p5.prototype.applyEffects = function (...args) {
1243-
let layer;
1249+
let source;
12441250
let effects;
12451251
let uniformsMapping = {};
12461252
let flip = true;
12471253
args.forEach(arg => {
1248-
if (arg instanceof p5.Framebuffer) {
1249-
layer = arg;
1254+
if (arg instanceof p5.Framebuffer || arg instanceof p5.Image || arg instanceof p5.MediaElement) {
1255+
source = arg;
12501256
} else if (Array.isArray(arg) && arg.every(e => e instanceof p5.Shader)) {
12511257
effects = arg;
12521258
} else if (typeof arg === 'object' && !Array.isArray(arg)) {
@@ -1255,17 +1261,15 @@ void main() {
12551261
flip = arg;
12561262
}
12571263
});
1258-
if (!(layer instanceof p5.Framebuffer)) {
1259-
console.log('The layer param should be a p5.Framebuffer in applyEffects(layer, effects).');
1260-
return layer;
1264+
if (!(source instanceof p5.Framebuffer || source instanceof p5.Image || source instanceof p5.MediaElement)) {
1265+
console.log('The source param should be either a p5.Framebuffer, p5.Image, or p5.MediaElement in applyEffects(source, effects).');
1266+
return source;
12611267
}
12621268
if (!Array.isArray(effects)) {
1263-
console.log('The effects param should be an array in applyEffects(layer, effects).');
1264-
return layer;
1269+
console.log('The effects param should be an array in applyEffects(source, effects).');
1270+
return source;
12651271
}
1266-
let blender = layer;
1267-
// TODO: a duplicate effect produces: WebGL warning: drawElementsInstance
1268-
// decide whether to include the avoid duplicates using appliedEffects set fix below
1272+
let blender = source;
12691273
const appliedEffects = new Set();
12701274
effects.forEach((effect, index) => {
12711275
if (!(effect instanceof p5.Shader)) {
@@ -1293,6 +1297,9 @@ void main() {
12931297
}
12941298
!effect._blender && console.log(`Skipping effect '${index}' due to '${effect.key}' shader missed uniform sampler2D blender variable.`);
12951299
uniforms.blender = blender;
1300+
// TODO decide whether to emit these:
1301+
// (source instanceof p5.Image || source instanceof p5.MediaElement) &&
1302+
// (uniforms.uOffset = this.texOffset(source), uniforms.uResolution = this.resolution());
12961303
blender = this.applyShader(effect, { target: effect.blender, scene: () => this.overlay(flip), uniforms });
12971304
});
12981305
return blender;

0 commit comments

Comments
 (0)