Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

  • Implementing a gooey effect with a shader

    Hi Jeremy, thank you for taking the time to answer my question.

    ...now you want create a hard threshold on your alpha mask by multiplying the alpha() of each pixel by 18, then subtract 7. Is that right?

    It is right: multiplying by 19 to 60 (alpha contrast), then subtracting 9 (alpha offset).

    A shader is not the only way to manipulate color information -- you can use red(), green(), blue(), alpha(), or use bit fiddling and shifting of the ARGB color information

    I know, that's exactly what I tried previously (see our last discussion). Overall, I think this approach (loadPixels() / updatePixels()) is not appropriate when dealing with multiple moving objects, even with bit-shifting (good for pictures though).

    Based on the example you provided, my sketch runs at 5 fps with 5 bouncing balls and for some reason they do not "melt" when colliding (no gooey effect).

    With a shader, the same sketch runs at 60 fps with 700 bouncing balls and I get that metaball sort of effect. (Not exactly the one I'm looking for, obviously, but something quite close I came up with by fiddling with the color matrix).

    test with 100 balls

    I really believe the solution lies in a shader implementation. Let's hope someone can help me find a way to play with that alpha contrast channel in GLSL.

  • Smoothed Hull around random shapes

    @digitalmartyn -- How are the shapes defined? Boxes / voxels? A collection of vertices and edges?

    The nature of your shape data is going to affect how you discover / define the bounds that the metaball must enclose. For example, you could define a sphere whose radius is the corner radius of each box, then use the collection of spheres to define the metaball.

    Lots of metaball algorithm discussion recently:

    https://forum.processing.org/two/search?Search=metaball

  • Smoothed Hull around random shapes

    Has anyone seen examples or references for creating a smoothed hull around randomly placed shapes?

    Essentially a metaball algorithm

    thanks in advance.

  • How to draw colored 3D metaballs with toxiclibs ?

    Hi,

    Following this thread (where I was trying to gather informations on metaballs) I decided to use the toxiclibs library in order to draw one myself.

    Here is the kind of result I would like to achieve:

    from Zach Lieberman (see full motion here)

    from Wenzy Yang (see full motion here)

    Here's what I could do so far:

    see HD here

    Questions:

    • How to give each metaball a specific color like in the first picture ? I tried here but to no avail. It seems toxiclibs doesn't allow to assign different colors to multiple objects within a for loop.
    • How to apply linear interpolations to the mesh vertices (with the toxiclibs library) in order to get smoother contours ?
    • How can I improve the script to make the sketch run faster ? When I draw each face individually with coordinates-based colors (see GIF above) (from line 42 to 51 below) the sketch is running very slow (8 fps vs 60 fps without coordinates-based colors).

    Alternatively, what I would like to know:

    • How did Wenzy Yang draw live such smooth contours (second picture) without experiencing any lag ? With toxiclibs, drawing colored metaballs from an equally dense VolumetricSpaceArray would be too computer intensive. (Hence my question on linear interpolations).

    If @amnon or @toxmeister or anyone familiar with the toxiclibs library happen to read this question, I would be immensely grateful for your help !

    PS: PLEASE do not move this thread to the "Python mode" category since all the questions are about the toxiclibs library !

    full code:

        add_library('toxiclibs_p5')
        add_library('toxiclibscore')
        add_library('volumeutils')
        add_library('peasycam')
        from toxi.processing import ToxiclibsSupport
    
        mesh = TriangleMesh("mesh")
        iso, grid, dim = .3, 70, 700
        scl = Vec3D(dim, dim, dim)
        volume = VolumetricSpaceArray(scl, grid, grid, grid)
        surface, brush = ArrayIsoSurface(volume), RoundBrush(volume, scl.x() / 2)
    
        def setup():
            global balls, gfx, a, cam
            size(720, 720, P3D)
            smooth(8)
    
            cam, gfx, a = PeasyCam(this, 700), ToxiclibsSupport(this), Attractor(0, 0, 0, 1, 100)
            balls = []    
            [balls.append(Ball()) for e in range(10)]
            noStroke()
            beginShape(TRIANGLES)
    
    
        def draw():
            background(0)
            print frameRate
    
            volume.clear()
            for i, b in enumerate(balls):
                force = a.attract(b)
                b.applyForce(force)
                b.update()
                b.display()
            volume.closeSides()
    
            surface.reset()
            surface.computeSurfaceMesh(mesh,iso)
            mesh.computeVertexNormals()
            gfx.mesh(mesh, True)
    
            num = mesh.getNumFaces()
            for i in range(num):
                f = mesh.faces[i]
                fill(180 + f.a.x(), 180 + f.a.y(), 180 - f.a.z())
                vertex(f.a.x(), f.a.y(), f.a.z())
                fill(180 + f.b.x(), 180 + f.b.y(), 180 - f.b.z())
                vertex(f.b.x(), f.b.y(), f.b.z())
                fill(180 + f.c.x(), 180 + f.c.y(), 180 - f.c.z())
                vertex(f.c.x(), f.c.y(), f.c.z()) 
            endShape()
    
            cam.rotateY(.03)
    
    
        class Ball(object):
            def __init__(self):
                self.r = random(10, 220)
                self.pos = PVector(random(-100,100), random(-100,100), random(-100, 100))
                self.vel = PVector(0, 0, 0)
                self.acceleration = PVector(0, 0, 0)
                self.mass = 1 + (self.r * .01)
    
            def display(self):
                v = Vec3D(self.pos.x, self.pos.y, self.pos.z)
                brush.setSize(self.r)
                brush.drawAtAbsolutePos(v, 1)       
    
            def applyForce(self, f):
                f = f / self.mass
                self.acceleration += f *.5
    
            def update(self):
                self.vel += self.acceleration
                self.pos += self.vel
                self.acceleration *= 0
                self.vel.limit(10)
    
        class Attractor():
            def __init__(self, x, y, z, m, g):
                self.location = PVector(x, y, z)
                self.mass = m
                self.G = g
    
            def attract(self, m):
                force = PVector.sub(self.location, m.pos)
                d = force.mag()
                d = constrain(d, 5, 25)
                force.normalize()
                strength = (self.G * self.mass * m.mass) / (d * d)
    
                if keyPressed and m.mass < 1.5:
                        force.mult(-strength*2)
    
            return force
    
  • How to code a 3d metaball ?

    @kfrajer @jeremydouglass Since my script is heavily depending on the tocixlibs library, would you guys mind if I post a question related to this metaball in the Library Questions" category ? I was hoping that maybe amnon or toxmeister would help even though they both don't seem to be very active on this forum anymore.

  • How to code a 3d metaball ?

    Update: I've managed to make a bloby metaball (sort of fusion of several metaballs) using the toxclibs library.

    But there's still one major thing I can't figure out:

    • How to give each ball a distinct color ?

    On a similar issue with the toxiclibs library, @amnon replied:

    TriangleMesh does not support colored faces. You have to either extend the class or store this information externally and then draw each face individually with it's connected color.

    Following this answer I tried to draw each face individually:

     beginShape(TRIANGLES)
        num = mesh.getNumFaces()
        for e in range(num):
            f = mesh.faces[e]
            fill(e * .01 , 82 , e*.03) 
            vertex(f.a.x(), f.a.y(), f.a.z())
            vertex(f.b.x(), f.b.y(), f.b.z())
            vertex(f.c.x(), f.c.y(), f.c.z())
        endShape()
    

    It becomes then possible to draw different colors depending on the face's index, however it still doesn't tell me how to give each ball a different color

    Do you guys have any idea how to solve this problem ?

    Full code:

    add_library('toxiclibs_p5')
    add_library('toxiclibscore')
    add_library('volumeutils')
    add_library('peasycam')
    from toxi.processing import ToxiclibsSupport
    
    mesh = TriangleMesh("mesh")
    iso, grid, dim = .5, 50, 800
    scl = Vec3D(dim, dim, dim)
    volume = VolumetricSpaceArray(scl, grid, grid, grid)
    surface, brush = ArrayIsoSurface(volume), RoundBrush(volume, scl.x() / 2)
    
    def setup():
        global points, gfx, a
        size(720, 720, OPENGL)
    
        cam, gfx, a = PeasyCam(this, 800), ToxiclibsSupport(this), Attractor(0, 0, 0, 1, 100)
        cam.rotateY(4)
        points = []    
        [points.append(Point()) for e in range(10)]
        noStroke()
    
    def draw():
        background(0)
        lights()
    
        volume.clear()
        for i, p in enumerate(points):
            force = a.attract(p)
            p.applyForce(force)
            p.update()
            p.display()
        volume.closeSides()
    
        surface.reset()
        surface.computeSurfaceMesh(mesh,iso)
        mesh.computeVertexNormals()
        gfx.mesh(mesh, True)
    
        # beginShape(TRIANGLES)
        # num = mesh.getNumFaces()
        # for i in range(num):
        #     f = mesh.faces[i]
        #     fill(100 + i * .01 , 182 , 100 + i*.03) 
        #     vertex(f.a.x(), f.a.y(), f.a.z())
        #     vertex(f.b.x(), f.b.y(), f.b.z())
        #     vertex(f.c.x(), f.c.y(), f.c.z())
        # endShape()
    
    
    class Point(object):
        def __init__(self):
            self.r = random(15, 140)
            self.pos = PVector(random(-100,100), random(-100,100), random(-100, 100))
            self.vel = PVector(0, 0, 0)
            self.acceleration = PVector(0, 0, 0)
            self.mass = 1 + (self.r * .006)
    
        def display(self):
            v = Vec3D(self.pos.x, self.pos.y, self.pos.z)
            brush.setSize(self.r)
            brush.drawAtAbsolutePos(v, 1)
    
        def applyForce(self, f):
            f = f / self.mass
            self.acceleration += f
    
        def update(self):
            self.vel += self.acceleration
            self.pos += self.vel
            self.acceleration *= 0
            self.vel.limit(10)
    
    class Attractor():
        def __init__(self, x, y, z, m, g):
            self.location = PVector(x, y, z)
            self.mass = m
            self.G = g
    
        def attract(self, m):
            force = PVector.sub(self.location, m.pos)
            d = force.mag()
            force.normalize()
            strength = (self.G * self.mass * m.mass) / (d * d)
    
            if keyPressed:
                force.mult(-strength*2)
    
            return force
    
  • How to code a 3d metaball ?

    @kfrajer @jeremydouglass sorry for not replying I'm doing some research. I'll comment back as soon as I'm finished with this metaball thing. (Thank you both for the links. It seems the ray marching technique is more widespread than I thought. Not sure yet if I'll implement it in a shader)

  • How to code a 3d metaball ?

    Of course I've read it but it seems that coding a 3d metaball is slightly more complicated than just adding another dimension to the 2d version.

    The solution you suggest is computationnally very expensive and doesn't take into account the tracing of the metaball edges.

    Quoting Zack Lieberman:

    Metaballs is an old school computer graphics algorithm where you define shapes via an implicit functions and use a technique like marching cubes to trace the edges of those functions on some sort of grid.

    Quoting Mike Walczyk:

    The trick is to use signed distance functions or SDF. These are mathematical functions that take a point in space and tell you how far that point is from a surface.

    In order to render the scene, we are going to use a technique called ray marching. At a high level, we will shoot out a bunch of imaginary rays from a virtual camera that is looking at our world. For each of these rays, we are going to "march" along the direction of the ray, and at each step, evaluate our SDF. This will tell us: "from where I currently stand, how far am I from the closest point on the surface of our sphere?"

    More on his blog post

  • How to code a 3d metaball ?

    Did you read the 2D metaball? It’s essentially a heat map of summing up distances to the balls.

    if you think this in 3D you would have a 3D heat map. That means triple nested for loop over a section of space and adding up colors following distance to balls.

  • How to code a 3d metaball ?

    Hi everyone,

    Among the various coding challenges I set for myself there's one at the top of my list that still remains obscure and rather complex to me: coding a 3d metaball.

    Since I first saw Zack Lieberman's work on 3d blobs and metaballs I've been obssessed with them.

    made by Zack Lieberman with OpenFrameworks

    made by Satoshi Horii (Rhizomatics) probably with OpenFrameworks

    made by Mike Walczyk with OpenFrameworks and rendered in TouchDesigner (? not sure)

    made by Martin Meurin with Processing

    I've read the wikipedia page, I know from other sources that it may involve Ray Marching shaders and Signed distance Functions but the problem is I haven't been able to find a source code, even a snippet, to work on. I'm relatively new to Processing and starting from scratch for this challenge seems really tough.

    I would love to read your suggestions and advices. If you have any link to tutorials, step-by-step roadmaps or even code in Java, Python or even C++ I would really appreciate if you could share it here.

    Thank you !

  • 2d Metaball sketch running super slow in Python mode

    Hi guys,

    I made several Python versions of 2d metaball sketches I found here on the forum or on the CodingTrain Github.

    Problem: It runs super slow (<1fps !) while all Java versions run very smoothly (60fps).

    Questions:

    • Why such a difference in the framerates ?

    • Is is possible to improve the Python code or am i for ever doomed for having chosen Python mode over Java mode ?

    original JAVA code

    main tab:

    Blob[] blobs = new Blob[10];
    
    void setup() {
      size(640, 360);
      colorMode(HSB);
      for (int i = 0; i < blobs.length; i++) {
        blobs[i] = new Blob(random(width), random(height));
      }
    }
    
    void draw() {
      background(51);
    
    
      println(frameRate);
    
      loadPixels();
      for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          int index = x + y * width;
          float sum = 0;
          for (Blob b : blobs) {
            float d = dist(x, y, b.pos.x, b.pos.y);
            sum += 10 * b.r / d;
          }
          pixels[index] = color(sum, 255, 255);
        }
      }
    
      updatePixels();
    
      for (Blob b : blobs) {
        b.update();
        //b.show();
      }
    }
    

    blob class

    class Blob {
      PVector pos;
      float r;
      PVector vel;
    
      Blob(float x, float y) {
        pos = new PVector(x, y);
        vel = PVector.random2D();
        vel.mult(random(2, 5));
        r = random(120, 400);
      }
    
      void update() {
        pos.add(vel); 
        if (pos.x > width || pos.x < 0) {
          vel.x *= -1;
        }
        if (pos.y > height || pos.y < 0) {
          vel.y *= -1;
        }
      }
    
      void show() {
        noFill();
        stroke(0);
        strokeWeight(4);
        ellipse(pos.x, pos.y, r*2, r*2);
      }
    }
    

    PYTHON code

    liste = []
    
    def setup():
        size(640, 360, FX2D)
        colorMode(HSB)
        [liste.append(Blob(random(width), random(height))) for e in range(10)]
    
    def draw():
        loadPixels()
        for x in range(width):
            for y in range(height):
                index = x + y * width
                sum = 0
                for e in liste:
                    d = dist(x, y, e.pos.x, e.pos.y)
                    try:
                        sum += 10 * e.r / d
                    except ZeroDivisionError:
                        return 1
                pixels[index] = color(sum, 255, 255)
        updatePixels()
    
        for e in liste:
            e.update()
    
    class Blob(object):
        def __init__(self, x, y):
            self.pos = PVector(x, y)
            self.velocity = PVector.random2D()
            self.velocity.mult(random(2, 5))
            self.r = random(120, 400)
    
        def update(self):
            self.pos.add(self.velocity)
    
            if self.pos.x > width or self.pos.x < 0:
                self.velocity.x *= -1
            if self.pos.y > height or self.pos.y < 0:
                self.velocity.y *= -1
    
  • How to create objects with the BlobDetection library that 'live and die' with the blobs

    For every Blob detected by the library I create a new object of my class Metaball.

    void createMetaballs() 
    {
      Blob blob;
      Metaball mettball;
      int numberOfBlobs = theBlobDetection.getBlobNb(); 
      int numberOfMetaballs = 0;
      float blobX, blobY;
      for (int n=0; n<numberOfBlobs; n++)
      {
        blob=theBlobDetection.getBlob(n);
        blobX=blob.x*width;
        blobY=blob.y*height;
        if (blob != null && numberOfMetaballs <= numberOfBlobs) 
        {
          mettball = new Metaball(blobX, blobY);
          mettball.id = blob.id;
          metaballs.add(mettball);
          numberOfMetaballs++;
        }
      }
      text("Mettbälle: " + metaballs.size() + " / Blobs: " + numberOfBlobs, 10, height-10);
    } 
    

    The problem for which I didn't manage to come up with a solution is how to kill the Metaball when a blob 'dies'. I tried to remove them from the arraylist when a blob is null but I didn't worked and the method just creates more metaballs... Somehow I have to compare the metaball with the blob I guess. Any ideas? Highly appreciated

  • Can I extend my Metaball class with theBlobDetection.Blob-Class?

    I am trying to extend the Blob-class of v3ga blobDetection library but I get an error saying: implicit super constructor Blob() is undefined. must explicitly invoke another constructor

    Calling super() in the constructor did not help because it says that class Blob does not have a constructor Blob(). Does anybody have experience in extending this class?