Skip to content

Commit 292d181

Browse files
committed
Use 2x resolution in WebGL 1 mode
1 parent dad2ae0 commit 292d181

File tree

3 files changed

+70
-19
lines changed

3 files changed

+70
-19
lines changed

README.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ Add the library to your source code, *after* loading p5 but *before* loading you
1818

1919
### Via CDN
2020
```html
21-
<script src="https://cdn.jsdelivr.net/npm/@davepagurek/[email protected]/p5.Framebuffer.min.js"></script>
21+
<script src="https://cdn.jsdelivr.net/npm/@davepagurek/[email protected]/p5.Framebuffer.min.js"></script>
22+
```
23+
24+
On OpenProcessing, paste this link into a new library slot:
25+
```
26+
https://cdn.jsdelivr.net/npm/@davepagurek/[email protected]/p5.Framebuffer.min.js
2227
```
2328

2429
### Self-hosted
@@ -82,13 +87,51 @@ Methods:
8287
- `options.size: { width: number; height: number; pixelDensity: number | undefined }`
8388
- Optionally specify a size and pixel density separate from the main canvas or graphic
8489
- If unspecified, the Framebuffer will resize when its canvas does
90+
- `options.antialias: boolean`
91+
- Turn on antialiasing by passing `true`
92+
- WebGL2 (the default, if available) will use multisampled antialiasing
93+
- WebGL1 will render at 2x the pixel density of the canvas for pseudo-antialiasing
8594

8695
Notes:
8796
- `draw()` uses the same p5 context as the rest of your sketch! Make sure to wrap your callback code in a `push()` and `pop()` to ensure your settings don't leak out into your non-Framebuffer code.
8897
- When you `resizeCanvas`, the Framebuffer will automatically resize accordingly. You probably will want to clear it and redraw to it if you had a texture cached.
8998

9099
A live example: https://davepagurek.github.io/p5.Framebuffer/examples/simple
91100

101+
### Framebuffer objects
102+
103+
Methods:
104+
- `Framebuffer.prototype.resizeCanvas(width: number, height: number)`
105+
- Resizes the Framebuffer to the specified size
106+
- This turns off autosizing to match the canvas size
107+
- `Framebuffer.prototype.autiSized()`
108+
- Returns whether or not the framebuffer will automatically match the canvas's size
109+
- `Framebuffer.prototype.autiSized(shouldAutoSize: boolean)`
110+
- Sets whether or not the framebuffer should automatically match the canvas's size
111+
- `Framebuffer.prototype.pixelDensity()`
112+
- Returns the current pixel density of the framebuffer
113+
- `Framebuffer.prototype.pixelDensity(targetDensity: number)`
114+
- Sets the pixel density of the framebuffer
115+
- This also turns off autosizing
116+
- `Framebuffer.prototype.defaultCamera()`
117+
- Returns the camera associated with the framebuffer by default
118+
- `Framebuffer.prototype.createCamera()`
119+
- Returns a new `p5.Camera` that matches the current dimensions of the framebuffer
120+
121+
An example of changing the size: https://davepagurek.github.io/p5.Framebuffer/examples/sizes
122+
123+
### WebGL 1
124+
125+
By default, this library will use WebGL 2 instead of WebGL 1. To use WebGL 1 mode, add this to the top of your sketch:
126+
127+
```js
128+
Framebuffer.forceWebGL1 = true
129+
```
130+
131+
Note: Antialiasing in WebGL 1 mode works by rendering at 2x resolution instead of using a multisampled texture at 1x resolution.
132+
133+
Compare the resulting quality using WebGL 1 vs 2 in this example: https://davepagurek.github.io/p5.Framebuffer/examples/formats
134+
92135
### Floating point textures
93136

94137
Sometimes, you want to write code that adds on to or modifies the previous frame. You may notice weird artifacts that show up due to the fact that colors are internally stored as integers: sometimes if you overlay a color with a very small alpha, the change in color is too small to round the resulting color up to the next integer value, so it doesn't change at all.

p5.Framebuffer.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class Framebuffer {
165165
throw new Error('Unable to create a framebuffer')
166166
}
167167
this.framebuffer = framebuffer
168-
if (this.antialias) {
168+
if (this.antialias && this._renderer.hasWebGL2) {
169169
this.aaFramebuffer = gl.createFramebuffer()
170170
if (!this.aaFramebuffer) {
171171
throw new Error('Unable to create a framebuffer')
@@ -187,6 +187,10 @@ class Framebuffer {
187187
return cam;
188188
}
189189

190+
defaultCamera() {
191+
return this.cam
192+
}
193+
190194
resizeCanvas(width, height) {
191195
this.autoSized = false
192196
this.width = width
@@ -226,7 +230,9 @@ class Framebuffer {
226230
return gl.UNSIGNED_INT
227231
}
228232
glInternalFormat(hasAlpha) {
229-
if (this.antialias) return this.glInternalRenderbufferFormat(hasAlpha)
233+
if (this.antialias && this._renderer.hasWebGL2) {
234+
return this.glInternalRenderbufferFormat(hasAlpha)
235+
}
230236
const gl = this._renderer.GL
231237
if (this._renderer.hasWebGL2 && this.colorFormat === gl.FLOAT) {
232238
return hasAlpha ? gl.RGBA16F : gl.RGB16F
@@ -306,8 +312,8 @@ class Framebuffer {
306312
gl.TEXTURE_2D,
307313
0,
308314
this.glInternalFormat(hasAlpha),
309-
this.width * this.density,
310-
this.height * this.density,
315+
this.width * this.density * this.aaDensity,
316+
this.height * this.density * this.aaDensity,
311317
0,
312318
this.glFormat(hasAlpha),
313319
this.colorFormat,
@@ -328,8 +334,8 @@ class Framebuffer {
328334
gl.TEXTURE_2D,
329335
0,
330336
this.glDepthInternalFormat(),
331-
this.width * this.density,
332-
this.height * this.density,
337+
this.width * this.density * this.aaDensity,
338+
this.height * this.density * this.aaDensity,
333339
0,
334340
gl.DEPTH_COMPONENT,
335341
this.depthFormat,
@@ -353,7 +359,7 @@ class Framebuffer {
353359
)
354360

355361
// Create separate framebuffer for antialiasing
356-
if (this.antialias) {
362+
if (this.antialias && this._renderer.hasWebGL2) {
357363
this.colorRenderbuffer = gl.createRenderbuffer()
358364
gl.bindRenderbuffer(gl.RENDERBUFFER, this.colorRenderbuffer)
359365
if (this._renderer.hasWebGL2) {
@@ -365,6 +371,7 @@ class Framebuffer {
365371
this.height * this.density,
366372
)
367373
} else {
374+
// TODO: use this in WebGL 1
368375
gl.renderbufferStorage(
369376
gl.RENDERBUFFER,
370377
gl.getParameter(gl.MAX_SAMPLES),
@@ -385,6 +392,7 @@ class Framebuffer {
385392
this.height * this.density,
386393
)
387394
} else {
395+
// TODO: use this in WebGL 1
388396
gl.renderbufferStorage(
389397
gl.RENDERBUFFER,
390398
gl.getParameter(gl.MAX_SAMPLES),
@@ -416,8 +424,8 @@ class Framebuffer {
416424
minFilter: 'nearest',
417425
magFilter: 'nearest',
418426
},
419-
this.width * this.density,
420-
this.height * this.density,
427+
this.width * this.density * this.aaDensity,
428+
this.height * this.density * this.aaDensity,
421429
)
422430
this._renderer.textures.push(depthP5Texture)
423431

@@ -428,8 +436,8 @@ class Framebuffer {
428436
glMinFilter: 'nearest',
429437
glMagFilter: 'nearest',
430438
},
431-
this.width * this.density,
432-
this.height * this.density,
439+
this.width * this.density * this.aaDensity,
440+
this.height * this.density * this.aaDensity,
433441
)
434442
this._renderer.textures.push(colorP5Texture)
435443

@@ -449,15 +457,15 @@ class Framebuffer {
449457
const p5TextureIdx = this._renderer.textures.findIndex(
450458
(t) => t.src === texture,
451459
)
452-
if (p5TextureIdx !== -1) {
453-
this._renderer.textures.splice(p5TextureIdx, 1)
454-
}
460+
if (p5TextureIdx !== -1) {
461+
this._renderer.textures.splice(p5TextureIdx, 1)
462+
}
455463
}
456464

457465
draw(cb) {
458466
const gl = this._renderer.GL
459467
const prevFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING)
460-
if (this.antialias) {
468+
if (this.antialias && this._renderer.hasWebGL2) {
461469
gl.bindFramebuffer(gl.FRAMEBUFFER, this.aaFramebuffer)
462470
} else {
463471
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer)
@@ -490,15 +498,15 @@ class Framebuffer {
490498
this._renderer._curCamera.cameraMatrix.mat4[15]
491499
)
492500
cb()
493-
if (this.antialias) {
501+
if (this.antialias && this._renderer.hasWebGL2) {
494502
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.aaFramebuffer)
495503
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.framebuffer)
496504
for (const [flag, filter] of [[gl.COLOR_BUFFER_BIT, gl.LINEAR, gl.DEPTH_BUFFER_BIT, gl.NEAREST]]) {
497505
gl.blitFramebuffer(
498506
0, 0,
499507
this.width * this.density * this.aaDensity, this.height * this.density * this.aaDensity,
500508
0, 0,
501-
this.width * this.density, this.height * this.density,
509+
this.width * this.density * this.aaDensity, this.height * this.density * this.aaDensity,
502510
flag,
503511
filter,
504512
)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@davepagurek/p5.framebuffer",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"main": "p5.Framebuffer.js",
55
"author": "Dave Pagurek <[email protected]>",
66
"license": "MIT",

0 commit comments

Comments
 (0)