Hello there! I made a fragment shader that can render circles, and would like to use it inside Processing as a replacement for Processing’s own functions
.
An extra question, if it is appropriate to ask this much in one thread:
In the future, I would like to render many of these at once. How do I approach this? Can the shader()
function be called repetitively? Do I make a uniform
in my shader which is just an array of vec2
s of a large size, then specify an int
to specify how many are being sent? (I would also send the radius of each circle in another array, …or whatever else is necessary along). Is there another way of doing it? Does Processing not allow for something like this…? (There is no mention of sending a PVector
array in the reference, or any other way to pass many vec
-n
s in, unless of course, I am allowed to do something like: shaderProgram.set("vec2array[" + i + ']')
), where i
is an index generated using a for
loop. As far as I know, arrays in C
and C++
need to have their sizes specified at compile time, and that GLSL
does NOT allow for memory allocation in any way.)
Finally, here is all the code I’ve used:
PShader circles;
void setup() {
size(640, 480, P2D);
circles = loadShader("circ.glsl");
}
void draw() {
background(0);
circles.set("resolution", new float[]{(float) width, (float)height});
circles.set("time", millis() * 0.001f);
shader(circles);
}
(Those notes…is this too informal…? -_-)
// Everything but the last
// `9` minutes of:
// [ https://youtu.be/xf7Y988cPRk ]
//@TODO: Make this an "`API`"
// which stores data in arrays
// and renders using some other
// `function`..I dunno.
// Also, PARTICLE PHYSICS ANYONE!? :D?
// (..you still need the CPU's
// batch data -_-)
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
// Data being transferred:
uniform vec2 resolution;
uniform float time;
// Actual variables:
float scr; // Aspect ratio.
vec2 uv; //..."vec2 uv;". Yeah. :rofl:
// Function definitions:
void circle(float _radius, vec2 _pos);
void main(void) {
uv = gl_FragCoord.xy /
resolution.xy * 2.0 - 1.0;
scr = resolution.x / resolution.y;
// gl_FragColor += vec4(uv, 1.0, 1.0);
// gl_FragColor = vec4(0.25, .0, .0, .0);
gl_FragColor = vec4(.0, .0, .0, 1.);
circle(.1, vec2(.5, .1));
circle(.3, vec2(.1, .1));
/*gl_FragColor.xyz *= mat3(
1., 2., 1.,
2., 1., 1.,
2., 1., 1.);*/
// gl_FragColor.a = dist;
// ^^^ Remove background
}
// PLEASE NOTE: The screen's aspect
// ratio, "`scr`" MUST be available
// as a **global** variable in the
// shader program you use this
// function in! Pass it in as
// an argument to this function,
// otherwise.
// ..calling it `scr`, of course.
void circle(float circle_r, vec2 circle_pos) {
vec2 circle_uv = gl_FragCoord.xy /
resolution.xy * 2.0 - 1.0;
// I know that these variables are a
// nightmare to type, but this is `C`.
// What now?
circle_uv.x *= scr;
circle_uv.x -= circle_pos.x;
circle_uv.y += circle_pos.y;
float circle_dist = circle_r - length(circle_uv);
// ^^^ Again, you can use
// `dot(uv, uv)` here.
circle_dist = step(.0, circle_dist);
gl_FragColor.rgb +=
vec3(circle_dist);
// gl_FragColor.a = circle_dist;
// ^^^ Remove background..?
}