Need Help Implementing a Billboard Effect for a Circle

Hey guys! This is my first post here so let me know if I need to change anything.

I’ve almost finished a project and I’ve hit a pretty big hurdle (for me anyway haha). I wanted to write some code that will outline a sphere regardless of its position on a 3d canvas, as if I am applying the stroke() method to it. I’ve done some research and found that the technique to use is called Billboarding and is a lot more complicated than I had realised.

Basically I want every sphere that is drawn on the canvas to have a circle that is a little bigger than the sphere intersecting it through the center, which then gives the effect of the sphere having an outline. This circle needs to have specific rotations applied to it in order for it to face the camera and successfully outline the sphere and I am not able to figure out the solution. Even after finding some other examples and tutorials, it’s all a little advanced for me so I’m at a loss. I would really appreciate any help!

I’ve included a little helper program here to show what I mean by outlining a sphere.

Sphere s;
float a = 0;

void setup(){
  size(900, 900, P3D);
  background(255);
  
  s = new Sphere(0, 0, 0, 100);
}

void draw(){
  translate(width/2, height/2);
  background(255);
  rotateY(a);
  s.display();
  a+=0.009;
}

class Sphere{
  PVector pos;
  float r;
  
  Sphere(float ox, float oy, float oz, float rad){
    pos = new PVector(ox, oy, oz); 
    r = rad;
  }
  
  void display(){       
    push();
      translate(pos.x, pos.y, pos.z); 
      noStroke();
      fill(130);
      sphere(r);

      // billboard effect goes here :(
      
      int w = 5;
      fill(0);
      circle(0, 0, (r*2)+w);
    pop();
  }
}

In your simple example you simply need to rotate by -a before drawing your circle:

Sphere s;
float a = 0;

void setup(){
  size(900, 900, P3D);
  background(255);
  
  s = new Sphere(0, 0, 0, 100);
}

void draw(){
  translate(width/2, height/2);
  background(255);
  rotateY(a);
  s.display();
  a+=0.009;
}

class Sphere{
  PVector pos;
  float r;
  
  Sphere(float ox, float oy, float oz, float rad){
    pos = new PVector(ox, oy, oz); 
    r = rad;
  }
  
  void display(){       
    push();
      translate(pos.x, pos.y, pos.z); 
      noStroke();
      fill(130);
      sphere(r);

      // billboard effect goes here :(
      
      push();
      rotateY(-a);
      int w = 5;
      fill(0);
      circle(0, 0, (r*2)+w);
      pop();
    pop();
  }
}

For something more complex I would create a dedicated function to display the outline that takes the camera transform as an input and “undo” them to display the circle in the proper position and orientation.

1 Like

This simple solution only works for when a sphere is directly in front of the camera. You’re right that I’d need a more complex function that calculates the correct orientation etc. but this is exactly where I’m stumped haha! Also, my project is not an animation, so perhaps the small demo I included wasn’t an excellent example to give.

hello,

can you give a link to a text for a Billboard Effect for a Circle please?

What is it?

Question

Is it pure decoration or does it have a meaning in your Sketch?

Remark 1

You can use stroke() to make a full grid on your sphere

I guess you can draw a sphere with stroke(0) and then draw a 2nd sphere at same position slightly smaller with noStroke()

Remark 2

you can use screenX, screenY command to get the 2D coordinates of your sphere. Now you can draw a 2D circle there.

  float theX = screenX(x, y, z);
  float theY = screenY(x, y, z);

  circle(theX , theY, 100 );

BUT what is the radius? It changes when the Z changes!

I guess you can try this:

  float theX2 = screenX(x-radius, y, z);
  float theY2 = screenY(x-radius, y, z);

and then

circle(theX , theY, theX - theX2 );

(not tested)

Chrisir

1 Like

always use lights()

looks much cooler

1 Like

Thanks for the reply!

Here’s a link to what I’m looking for, but instead of blue text boxes, it’d be a circle that is placed in the middle of a sphere, giving the effect of an outline! I wasn’t able to re-construct this code for my project though…

Answer to your question
This is purely for decoration, but it’s a fairly important decoration in the project I’m working on.

Remark 1
I’m aware that you can stroke() a sphere but I don’t want to see all of the grid, I’m unsure how making a smaller sphere inside would solve the issue.

Remark 2
I wasn’t aware of these functions, thanks for bringing them up! But I don’t see how they can solve my issue as the circle will need to be rotated towards the camera, and these functions don’t deal with that.

Thank you so much for the suggestions though!

Thanks for your feedback. I accept your statement.

I am not sure about this. The circle is a 2D entity. When you isolate it from the sphere using pushMatrix/popMatrix it is always on the monitor surface and thus facing the camera, no?

You’re definitely right that it will be facing the camera, but if I’m understanding correctly, this would just mean that the circle has no X or Y rotations applied, meaning the circle will just be parallel with the Y-plane. The rotations are what make the intersecting circle outline the sphere! Without rotations the circle will just cut through the centerof the sphere, and the edges of the sphere can be seen past the ‘outline’ that the circle is creating. (this depends on the camera’s perspective of course, if the sphere was directly in front of the camera it would work, but if the sphere is off center and closer to the camera, i don’t think it would work)

1 Like