# Rendering many objects with a shader

**URL:** https://discourse.processing.org/t/rendering-many-objects-with-a-shader/33286
**Category:** Coding Questions
**Created:** [November 3, 2021, 4:39pm UTC](https://discourse.processing.org/t/rendering-many-objects-with-a-shader/33286 "2021-11-03T16:39:19Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Brahvim](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/brahvim/32/14756_2.png) [@Brahvim](https://discourse.processing.org/u/Brahvim)
#### Post date: [November 3, 2021, 4:39pm UTC](https://discourse.processing.org/t/rendering-many-objects-with-a-shader/33286/1 "2021-11-03T16:39:20Z")

</div>

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:**

```auto
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…? -\_-)

```glsl
// 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..?
}

```

---

<div class="post-metadata">

### Author: ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)
#### Post date: [November 4, 2021, 8:59am UTC](https://discourse.processing.org/t/rendering-many-objects-with-a-shader/33286/2 "2021-11-04T08:59:28Z")

</div>

Hi 🙂

The default light shader does use an array of vec, see

> <https://github.com/processing/processing/blob/master/core/src/processing/opengl/shaders/LightVert.glsl#L28>

and you can indeed use

`shdr.set("myUniform[" + i + "]", 3.5);`

But I would ask… why do that? 🙂 Why not use also the vertex shader and send actual circles to the GPU?

Because if you draw a lot of circles using just the fragment shader it’s going to be much slower, or? Each pixel in the shader will have to be aware of all the existing circles (stored in an array) and the GLSL code will have to iterate over all the circles even if it will just draw one pixel belonging to one circle.

---

<div class="post-metadata">

### Author: ![Brahvim](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/brahvim/32/14756_2.png) [@Brahvim](https://discourse.processing.org/u/Brahvim)
#### Post date: [November 5, 2021, 10:39am UTC](https://discourse.processing.org/t/rendering-many-objects-with-a-shader/33286/3 "2021-11-05T10:39:28Z")

</div>

Thank you so much for answering! I should’ve been more thoughtful. Using Processing’s built-in `function`s, which already do this for me is good enough 👍.

Although I wonder if there is a way to get it to work with `NDC`s…  
I’ll open another thread for that, perhaps.
