Skip to content

material.js shader() example #3720

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/yuidoc-p5-theme/assets/shader-gradient.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Code adopted from "Creating a Gradient Color in Fragment Shader"
// by Bahadır on stackoverflow.com
// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader

precision highp float; varying vec2 vPos;
uniform float pos;

void main() {

vec2 st = vPos.xy + vec2(0,pos);
Copy link
Member Author

@hsab hsab May 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stalgiag I agree, and yet the reason why I opted for the Mandel shader was exactly the familiarity of its reoccurrence throughout the reference manual. But the fact that it could seem like a blackbox for users/beginners is undeniable.

Perhaps I should change pos to offset. Then the shader could coherently be extended so that:
vec2 st = vPos.xy + vec2(xOffset,yOffset);

color1 and color2 could perhaps be uniforms as well. That way the shader could potentially be reused with a certain level of modularity that is visually distinguishable:

  • moves along X || moves along Y || moves on XY plane || static
  • full-color control

this could allow two instances of this shader to properly reflect the effects of shader() for this particular example/commit:
shader1: blue-orange moving vertically
shader2: red-green moving horizontally

what do yo think?

Copy link
Member Author

@hsab hsab May 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or even better uniform vec2 offset; rather than uniform float xOffset and uniform float yOffset, giving:
vec2 st = vPos.xy + offset.xy;

Copy link
Member Author

@hsab hsab May 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as for the quad() and rect() situation, we could perhaps opt in for something like this. Which as a solution, relies primarily on:
gl_FragCoord.xy / resolution.xy
This allows for eliminating +-1 values for the quad and simply using rect(0,0,width,height);
Yet ambiguity might arise from setUniform('resolution',[width,height]);

On a side note, I tried looking for docs on the webgl vs p2d coordinate differences and failed to find any. Are you aware of such in the codebase/references?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick response! I like the offset with two gradient shader instances idea. I understand the the impulse to repeat the Mandel shader. It might be a good idea for familiarity sake but it also seems like a good time to start moving away from it and maybe filing an issue to simplify the other examples away from the Mandel shader as well.

I'll leave it up to you as to whether to change the vertex shader. I don't have extremely strong feelings and it would be rect(-width/2, -height/2, width, height) which when combined with setting the resolution uniform doesn't provide the largest gains in terms of simplicity.

As for coordinate differences, the getting started with webgl wiki explains this a bit. This decision dates back to the first work on WebGL mode in 2015. There are pros and cons to doing this but I agree that maybe it makes sense to try to find another more prominent place for this in documentation. Not sure if there are other mentions that I am missing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the info, although I think it would have been rect(-width/2, -height/2, width*2, height*2), I decided to just opt in for quad().

I'm gonna close this pull req, and open another one with the latest commit.


vec3 color1 = vec3(1.9,0.55,0);
vec3 color2 = vec3(0.226,0.000,0.615);

float mixValue = distance(st,vec2(0,1));
vec3 color = mix(color1,color2,mixValue);

gl_FragColor = vec4(color,mixValue);
}
43 changes: 43 additions & 0 deletions src/webgl/material.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,49 @@ p5.prototype.createShader = function(vertSrc, fragSrc) {
* @chainable
* @param {p5.Shader} [s] the desired <a href="#/p5.Shader">p5.Shader</a> to use for rendering
* shapes.
*
* @example
* <div modernizr='webgl'>
* <code>
* // Click within the image to toggle
* // the shader used by the quad shape
*
* let mandel;
* let gradient;
* let useMandel = false;
*
* function preload() {
* // load the shader definitions from files
* mandel = loadShader('assets/shader.vert', 'assets/shader.frag');
* gradient = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');
* }
* function setup() {
* createCanvas(100, 100, WEBGL);
* // initially use the gradient shader
* shader(gradient);
* noStroke();
* }
*
* function draw() {
* mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));
* gradient.setUniform('pos', sin(millis() / 2000) + 1);
* quad(-1, -1, 1, -1, 1, 1, -1, 1);
* }
*
* function mouseClicked() {
* useMandel = !useMandel;
* if (useMandel === true) {
* shader(mandel);
* mandel.setUniform('p', [-0.74364388703, 0.13182590421]);
* } else {
* shader(gradient);
* }
* }
* </code>
* </div>
*
* @alt
* canvas toggles between a circular gradient of orange and blue moving up and down. and an infinitely detailed fractal with mouse click/press.
*/
p5.prototype.shader = function(s) {
this._assert3d('shader');
Expand Down