jvolker
February 16, 2023, 7:44am
1
Hi,
I’m trying to create a fading effect on a masked image/graphics. I’ve implemented it here: p5.js Web Editor
I’m trying to slow down the effect even more. Unfortunately, the shader behaves a little strangely when increasing the multiplier even further in gl_FragColor.a = color.a * 0.997;
, say 0.999
, the alpha seems to become 1.0.
I’ve already tried to increase precision using highp
.
Help with this would be highly appreciated. Thanks.
jvolker
February 16, 2023, 9:06am
2
As described in the Frambuffer p5 library, it seems to be a texture precision issue: GitHub - davepagurek/p5.Framebuffer: A library for efficiently drawing to a texture in p5 WebGL mode.
The library seems to solve the issue giving this example: p5.js Web Editor
Unfortunately, there is no example of implementing a custom shader yet. I’ve posted an issue on Github: How to implement a custom shader? · Issue #28 · davepagurek/p5.Framebuffer · GitHub
Some more information that might be related:
glsl, textures, p5.js
opened 02:04PM - 14 Feb 23 UTC
Feature Request
Area:WebGL
### Increasing Access
`createGraphics` is currently the recommended way to cr… eate a texture and use it elsewhere in a sketch. While this is very flexible and approachable, it unfortunately comes with inherent performance implications (https://github.com/processing/p5.js/issues/5128) that are currently are hard to work around within p5. Framebuffers are the native WebGL solution to this task with the best potential performance.
Giving users access to better performance with, ideally, a simple and familiar interface would let their sketches take better advantage of hardware capabilities and give viewers with lower-end hardware a much smoother viewing experience.
### Most appropriate sub-area of p5.js?
- [ ] Accessibility
- [ ] Color
- [ ] Core/Environment/Rendering
- [ ] Data
- [ ] DOM
- [ ] Events
- [ ] Image
- [ ] IO
- [ ] Math
- [ ] Typography
- [ ] Utilities
- [X] WebGL
- [ ] Build Process
- [ ] Unit Testing
- [ ] Internalization
- [ ] Friendly Errors
- [ ] Other (specify if possible)
### Feature request details
While for technical reasons it will not be feasible to make all graphics used as textures use Framebuffers under the hood, we believe creating an interface for Framebuffers that fits well with existing p5 features will still be beneficial.
## Inspiration
- [p5.Framebuffer](https://github.com/davepagurek/p5.Framebuffer)
- [p5Fbo](https://github.com/aferriss/p5Fbo)
- [openFrameworks ofFbo](https://openframeworks.cc/documentation/gl/ofFbo/)
## High level features
- A Framebuffer class can be created with `createFramebuffer()`
- It may only be used in WebGL environments
- [If WebGL2 is enabled](https://github.com/processing/p5.js/issues/2536), antialiasing is supported
- We have decided, at first at least, we will not try to provide an antialiasing fallback on WebGL1
- The most practical fallback option would be to render at 2x pixel density. However, this has a noticeable performance impact which is especially large on the sorts of older devices that don't have WebGL2 support. For that reason, we believe a more reasonable option is to degrade gracefully to a 1x density non-antialiased Framebuffer if only WebGL1 is available.
- The Framebuffer can be passed into `texture()` or `setUniform()` or `image()` like a graphic can
## Implementation details
- Things that aren't part of the main motivation but we would get as a side effect:
- Writing in floating point format
- This has been [asked](https://github.com/processing/p5.js/issues/5556) [for](https://stackoverflow.com/questions/66334783/is-it-possible-to-use-floating-point-texture-with-p5-js-glsl) directly, but also indirectly after people notice [artifacts in feedback sketches](https://github.com/davepagurek/p5.Framebuffer#floating-point-textures)
- Readable depth information (not essential for v1)
- p5.Framebuffer allows this to be read via the `.depth` property of a framebuffer
- How does one choose a framebuffer to draw to?
- Prior art:
- p5.Framebuffer: `fbo.draw(() => /* ... */)`
- p5Fbo, ofFbo: `fbo.begin(); /* ... */ fbo.end();`
- Probably the `begin`/`end` version is more similar to `push`/`pop` and is what we should go with
- The callback function version could also potentially be added on top of this as a way to avoid accidental improper nesting of begin/end, but this is not essential
- Different size support
- Each fbo has to come with its own camera in order to be able to properly render to a size different from the main canvas
- We probably do not want to (at least initially) support all texture formats
- By making users ask for either `UNSIGNED_BYTE` (default) or `FLOAT`, this lets us pick the appropriate mode for the environment (WebGL1, WebGL2, etc)
- Antialiasing support will need lots of testing (p5.Framebuffer supports this but runs into cross-browser version issues often) so letting us pick texture modes that work will give us an avenue for resolving these sorts of issues
opened 03:35AM - 15 Jan 22 UTC
closed 11:04PM - 28 Mar 22 UTC
Enhancement
Area:WebGL
### Feature enhancement details:
I'd like to add an additional argument to th… e p5.Texture constructor that would allow more of the internal settings to be changed. I'm working on [p5Fbo](https://github.com/aferriss/p5Fbo), and one thing I'd like to enable is floating point textures. Float textures would allow more complex general purpose GPU programming, by allowing the texture to store values outside of a normalized [0,1] range. Currently, p5.Texture has [UNSIGNED_BYTE as it's data type hard coded in](https://github.com/processing/p5.js/blob/196d3afbf44de116c84936ff20cf4a5b8056ccb7/src/webgl/p5.Texture.js#L113).
I'm proposing that we add an optional settings argument to the p5.Texture constructor that would allow the user some additional control over the texture settings. The settings that I'm currently including in that object are:
- format: defaults to gl.RGBA, but could also be gl.RGB, or gl.ALPHA, or gl.LUMINANCE
- minFilter: either gl.LINEAR or gl.NEAREST
- magFilter: either gl.LINEAR or gl.NEAREST
- wrapS: one of gl.CLAMP_TO_EDGE, gl.MIRROR, or gl.MIRROR_REPEAT
- wrapR: one of gl.CLAMP_TO_EDGE, gl.MIRROR, or gl.MIRROR_REPEAT
- dataType: gl.UNSIGNED_BYTE or gl.FLOAT (there are more types but they are not very common)
So if someone wanted to use p5.Texture with this new argument they could write something like:
```
const renderer = createCanvas(100, 100, WEBGL);
const tex = new p5.Texture(renderer, new p5.Image(100, 100), {dataType: renderer.GL.FLOAT });
```
I'm open to suggestions about other ways to accomplish this, or if there's a way anyone can think of that doesn't require altering p5.Texture, I'm open to that as well. I'd also be fine with simplifying this change to just include the dataType as an optional argument, since that's really the thing I care about here.
One thing I'm not sure about is how this would fit into p5.Graphics. I believe currently p5.Graphics just makes a regular texture as it's backing canvas, but it might be possible to allow that canvas to be backed by a float texture as well.
[I've opened a draft PR](https://github.com/processing/p5.js/pull/5557), if anyone has some time to take a quick look :)
### How would this new feature help [increase access]
(https://github.com/processing/p5.js/blob/main/contributor_docs/access.md) to p5.js?
This is mainly a change geared towards making the webGL functions slightly more extensible, especially for people looking to extend p5 with their own add-ons and libraries. Since p5.Texture is mainly used under the hood by the renderer, it's unlikely that most folks would ever end up touching this. However for those that wish to extend the library, this makes it possible to access and alter some of the settings that were previously hard coded in.
In general it seems like the recommendation for adding more niche features to p5 is to make your own add on. But in this case, the add on is blocked by hard coded values in p5.
#### Most appropriate sub-area of p5.js?
- [ ] Accessibility (Web Accessibility)
- [ ] Build tools and processes
- [ ] Color
- [ ] Core/Environment/Rendering
- [ ] Data
- [ ] DOM
- [ ] Events
- [ ] Friendly error system
- [ ] Image
- [ ] IO (Input/Output)
- [ ] Localization
- [ ] Math
- [ ] Unit Testing
- [ ] Typography
- [ ] Utilities
- [X] WebGL
- [ ] Other (specify if possible)
opened 03:50AM - 02 Feb 23 UTC
Discussion
### Topic
Hi, I was trying to make GPU particle system, and wondering if there'… s a way to create 16bit texture for the shader to render?
The idea of GPU particle is storing particle position data into a texture's RGB channel, and accessing those data through shader. I had succeed make this particle system by storing the data on a graphic (with createGraphic). But 256 for each channel is not precise enough.
I had try modifying the p5.js source code, changing gl.texImage2D's format parameter from gl.RGBA to gl.RGBA16F kind of thing, but it didn't work.
Since I had no real experiences on raw WebGL, wondering if there's anyway to make this work.
Thanks!
1 Like
jvolker
February 16, 2023, 12:31pm
3
I’ve managed to implement it somehow: p5.js Web Editor
The effect is still not working the way I like, though. I don’t seem to have control of the fade duration beyond a certain point, even with very small numbers.
jvolker
February 17, 2023, 3:23am
4
This is another improved version without using the library:
A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.
It’s not ideal since it’s using a slow if-then statement in the shader, and I guess could be even smoother.
I would still love to know how to solve the issue with the library, as it would be more flexible and potentially faster. Any help is very much appreciated!
jvolker
February 18, 2023, 10:30am
5
Here are two more versions working towards my goal, that I would like to share. Both without using the library.
With a transparent source, using more passes to have more control over the fade duration:
A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.
Using a gradient brush, which is pretty close to what I want: p5.js Web Editor
Thanks to @diroru for all of his help with this.