# 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);
}

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);
}

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

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…

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!