Description
Increasing access
Lines in WebGL right now are catered towards line drawings rather than 3D shape outlines. Many older sketches that treat them more as outlines currently run significantly slower than they used to in earlier versions. Ideally, there would be a way to make that use case work again so that earlier teaching materials work as intended without also breaking the sketches than now use lines and rely on the current behaviour.
Which types of changes would be made?
- Breaking change (Add-on libraries or sketches will work differently even if their code stays the same.)
- Systemic change (Many features or contributor workflows will be affected.)
- Overdue change (Modifications will be made that have been desirable for a long time.)
- Unsure (The community can help to determine the type of change.)
Most appropriate sub-area of p5.js?
- Accessibility
- Color
- Core/Environment/Rendering
- Data
- DOM
- Events
- Image
- IO
- Math
- Typography
- Utilities
- WebGL
- Build process
- Unit testing
- Internationalization
- Friendly errors
- Other (specify if possible)
What's the problem?
WebGL lines currently are too slow to be drawing them in large numbers in immediate mode shapes. Many older teaching examples do this because earlier lines were lighter, and those are now much slower. The use case of 3D shape outlines also does not need the high fidelity caps and joins that are required for smooth curves.
This particular example from The Coding Train keeps coming up, as one that slows down a lot in newer p5 versions https://editor.p5js.org/codingtrain/sketches/OPYPc4ueq but it also does not need complex lines to accomplish its visual goal.
What's the solution?
There are a few options I can think of currently, all with different compromises:
- As suggested by p5.js 2.0 RFC #6678 (comment), implement a line mode that uses
GL_LINES
to draw outlines. This will be much faster (we can pass start + end points directly to WebGL without any conversion in JS into quads). However, it will be limited to 1px thick lines, which also means that line thickness will look different when you change a sketch's pixel density, as 1px is smaller relative to the canvas size on a high-dpi display. - Previously, lines were faster, and did not include caps and joins, so we could try to keep the line system mostly the same but add an option that doesn't create caps and joins. This will mean that any retained geometry (e.g. from
buildGeometry
) created in this simpler lines mode will never be able to gain caps+joins later on, as it will just not include that info. We will also maybe need to revisit the design of the line drawing system to accommodate having less attributes for some shapes, since we now pass more data along with each line vertex in order to be able to handle caps+joins, even if we only add segments, and this extra data is likely partly responsible for the slowdown. Per-vertex stroke color also is partially to blame for the slowdown. - We could create outlines in a shader using depth information rather than doing it with geometry. Some more background on this technique, including interesting artistic variations, can be found here: https://lettier.github.io/3d-game-shaders-for-beginners/outlining.html I made a quick prototype (https://editor.p5js.org/davepagurek/sketches/aC--DvWmb) but updates will be required if we want to support variable thickness (which we maybe don't need.) This technique needs depth info, which only can be read from framebuffers, so we'd need to refactor the WebGL renderer to always have a main framebuffer (which might have side benefits, like being able to use depth in filters in general.) Being a filter shader, it would also apply to everything on canvas, so you couldn't control it and its color on a per-shape basis.
In addition to the above, we can maybe speed up some of the existing line drawing via the things mentioned in #7237.
Pros (updated based on community comments)
- Lines are currently the slowest part of the WebGL renderer, so if we default to something lighter, the perceived speed of p5 will have a big boost
Cons (updated based on community comments)
- Not sure that it's possible to be backwards compatible to both sketches that used lines as outlines for 3D shapes, and to sketches that use lines for high fidelity line drawings. We'll likely need a slightly different API for one use case or the other.
- Lines are already a pretty complicated system since vanilla WebGL does not offer any help. We'll need to be careful we don't turn this into an even more complex and brittle system
- Some of these solutions involve more complex refactors
Proposal status
Under review
Metadata
Metadata
Assignees
Type
Projects
Status