-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shader hooks #7149
Shader hooks #7149
Conversation
One pattern I've noticed so far: If you just wrap individual inputs in a hook, then users are forced to handle their inputs in the order the code executes. This is a problem if, for example, they want to adjust the color based on the texture coordinate, but your shader runs its The solution I've come to is to make a struct with all the inputs, and then make a single hook for all of them at once. Then users can use whichever they want to modify whichever others they want -- or store them to a global so then use in a later hook. |
I think rather than handling different GLSL versions, which would require some level of cross-compilation or asking the user to use our special macros, it's ok if shaders just declare what version they use, and it is the user's responsibility to adhere to that. For default p5 shaders, that means GLSL ES 300 if you're using WebGL 2 (the default), and GLSL ES 100 if you're using WebGL 1. |
Ok I think this is code-complete for this repo. So far, I think the best we can do for the inline docs is a bullet list explaining the possible hooks. That currently looks like this: While this is still rather imposing, I'm hoping that this will eventually serve as a reference, and tutorials will be the place that lays out information incrementally instead of everything all at once. The next step for me will be to start drafting some of that in the p5.js-website repo. Still left to do here: test this on older computers to make sure there hasn't been a major degradation in performance |
In this test https://editor.p5js.org/davepagurek/sketches/kSsPHuHY6 on my old 2015 Intel mac, Im getting:
These are all in the same ballpark so I feel safe assuming this won't affect performance. |
Try it out!On the p5 web editorHere's a web editor sketch you can fork to try it out! ManuallyHere's a zip of the built library you can add to a project. ReferenceI put up a build of the site with the shader hooks docs here. Check out Quick TutorialShaders provide a way to efficiently modify the color and position of shapes. You might think you haven't used shaders before, but p5.js is actually using them behind the scenes any time you use WebGL mode! While you can always create your own shader from scratch, it can be easier to start from a p5.js shader and make modifications to the parts of interest to you. Let's say you're drawing a circle in WebGL mode, and you'd like to make a custom material for it.
When you draw with solid colors, under the hood, p5.js is using its
Each one of these is called a hook because it lets you attach your own bits of code into the shader. The documentation for a p5.js shader will include a description of what each one does, and Let's say we want to wiggle the shape by adding a sine wave to every vertex. We can do that by filling one of the position hooks. We do that by calling
To animate that sine wave, we'll want to tell the shader what the current time is so that it can factor that in. You can add a
If you want a declaration to only be in a vertex shader (the one that edits positions) or a fragment shader (the one that colours the pixels), you can use
|
Hi Dave, your work looks amazing as always. I was experimenting with the shader hooks you created, and I think they’re going to be one of the standout features in version 2.0. There’s so much to appreciate in this implementation, but I’ll focus on giving my feedback and suggestions for further improvements. Everything looks great to me. I just reviewed the phase 2 ideas of shader hooks, and it already covers most of the ideas I had in mind.
Additionally, we have vertexDeclarations and fragmentDeclarations, which feel a bit odd. If a user passes a function to the fragment shader but doesn't want it in the vertex shader, they currently have to use fragmentDeclarations: yourFunction. Would it be possible to avoid declarations altogether, and instead streamline this process?
Or perhaps, if we're modifying color values that relate to fragment shader hooks and the user has a relevant function, we could automatically move that function to the fragment shader. Similarly, if something involves position, we could directly move that function to the vertex shader. Or maybe we could define it int both shaders. If not possible due to some reasons then we can add documentation for declaration (fragmentDeclerations, decleration and vertexDecleartion).
Rest, looks awesome. These are just some ideas, and they might be a bit off, so feel free to take them as you see fit. |
Co-authored-by: Perminder Singh <[email protected]>
Thanks @perminder-17! These are all interesting ideas. I'll comment a bit on the technical challenges we'd have to overcome, hopefully we can figure something out that addresses those points! Making uniforms easierIt's a little hard generating uniforms from Another thought: instead of removing the uniform declaration and shifting it to let myShader;
function setup() {
createCanvas(200, 200, WEBGL);
myShader = materialShader().modify({
uniforms: {
'float time': () => millis()
},
'vec3 getWorldPosition': `(vec3 pos) {
pos.y += 15.0 * sin(pos.x * 0.15);
return pos;
}`
});
}
function draw() {
background(255);
noStroke();
fill('red');
shader(myShader)
// no need to setUniform!
circle(0, 0, 50);
} ...and then maybe every time you call Making functions easierI really like the idea of being able to include other functions in with the hooks like that. I could see having addons that package useful functions, random and noise functions being the ones I'm copy-and-pasting into 99% of my shaders, and then you could mix them into your hooks like this:
The two consequences of this are:
|
I've updated the code with an implementation of that |
Thanks @davepagurek for considering my feedback on simplifying uniforms and functions. I'm looking forward to help on the phase 2 R&D, where we can work together to find effective solutions for the helper functions. Just a question, |
oops good catch, I fixed that bug on the main branch of the website repo but haven't updated my hooks fork to include that! |
Thanks for your input everyone! I'm going to merge this in as a beta API so that we can get more testers in the next 1.x release and so 2.0 projects can build off of it. Feel free to still give more feedback and open more issues so we can improve this feature! |
Resolves #7031
Changes
materialShader()
normalShader()
colorShader()
strokeShader()
modify()
method to shaders to pass in new hooks implementationsinspect()
method to show available hooksHandle different GLSL versionsScreenshots of the change
Wobbly material:
Custom normal material colors:
Fuzzy line rendering:
PR Checklist
npm run lint
passes