Skip to content

[p5.js 2.0 RFC Proposal]: Make shaders define what they get used for #6759

Closed
@davepagurek

Description

@davepagurek

Increasing access

Shaders are arguably the part of p5 with the biggest barrier to entry. There's some existing confusion about why they get applied some times rather than others. Resolving this confusion would help to make shaders easier for users to learn and grasp.

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?

Currently, p5 tries to determine if a shader should be used for fills, strokes, images, and more based on what uniforms/attributes they include. This is currently documented like so:
image

If a shader doesn't need these properties, adding it into a shader unused is an unreliable solution, as some browsers optimize away unused shader properties.

Additionally, this doesn't fully address other open issues (#6327, #6564) as there are other scenarios where p5 will opt instead for a default shader, such as when using image(...).

What's the solution?

I propose simplifying the scenarios where user shaders can be applied to just fills and strokes.

  • Fill shaders will apply regardless of whether there is a current texture or lights.
  • Stroke shaders apply to all strokes.
  • Neither affects calls to image(...): if one wants to send an image to a shader, one must call texture(...) or set a uniform, and then draw a rectangle.

To define what a shader applies to, I suggest adding an options object to createShader and loadShader that looks like this (in Typescript syntax):

createShader(
  vertSrc: string,
  fragSrc: string,
  { strokes = false, fills = true }: { strokes: boolean; fills: boolean } = {}
)

This means that every shader you create must define what it should be applied to upon creation. By default, shaders just apply to fills and not strokes, as I think this is the most common use case. If one wants, one can specify a different combination of strokes and fills.

This also means that rather than having a single user shader set, one can possibly have a separate stroke and fill shader set.

Pros (updated based on community comments)

  • Simplifies documentation and requires the user to understand less about p5's internal material system
  • Reduces fewer discrepancies across browsers by no longer relying on the presence of uniforms that may be optimized away on some but not others
  • Allows a separate fill + stroke shader to be applied at once rather than trying to handle both in the same shader

Cons (updated based on community comments)

  • If a user shader has been set that does not handle lights or textures, and then one tries to add that in, it will make no visual difference

Proposal status

Under review

Metadata

Metadata

Type

No type

Projects

Status

Completed

Relationships

None yet

Development

No branches or pull requests

Issue actions