Jump to content
  • Advertisement
Sign in to follow this  
ramirofages

Projective circle clipping

This topic is 509 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to do projective clipping using a circle as the clipping mask. I'm aware that I could use the stencil buffer or other methods, but at this point I'm just curious to know why my approach isn't working as expected. But first, a screenshot of the problem:

[attachment=35801:circle.png]

I'm creating a circle at position 0,0,0 with radious 3, what I want to do is to use that circle as a clipping mask, by clipping (using  discard on the fragment shader) everything  that is outside of the circle in normalized device coordinates. Looking at the picture you can see that at the borders there are a few bits left outside that shouldn't be there (where the blue lines are).

Here's what I'm doing:

In the vertex shader, I calculate the world position of the vertex (w_pos) and pass that to the fragment shader.

In the fragment shader:

// p_pos = the projected position of the world point
float4 p_pos                = mul(MATRIX_VP, float4(w_pos, 1));

// circle_border = the closest border point of the circle to the p_pos
float3 circle_border_w_pos  = normalize(float3(w_pos.x, 0 , w_pos.z)) * _Radius;
float4 circle_border_p_pos  = mul(MATRIX_VP, float4(circle_w_pos, 1));

// circle_center = the center point of the circle, already in world space
float4 circle_center_p_pos  = mul(MATRIX_VP, float4(0,0,0,1));
float4 circle_center_p_pos  = mul(MATRIX_VP, float4(circle_center_w_pos,1));

// perspective divide
float3 n_pos                      = p_pos.xyz/p_pos.w;
float3 circle_border_n_pos        = circle_border_p_pos.xyz/circle_border_p_pos.w;
float3 circle_center_n_pos        = circle_center_p_pos.xyz/circle_center_p_pos.w;

if(distance(circle_center_n_pos.xy, n_pos.xy) > distance(circle_center_n_pos.xy, circle_border_n_pos))
{
  discard;
}

So as you can see, what I'm doing is projecting each point to the screen(current point, circle's border point closest to the current point, and center point of the circle) and measuring distances between them. If the distance from the center of the circle to the current point is greater than the distance from the center to the border (meaning, greater than the radius) then it's outside of the projected circle, and we clip it.

Below I leave an image (edited with ms paint :P) of the result that I'm trying to achieve:

[attachment=35802:Screenshot_6.png]

 

Cheers

Edited by ramiro_fages

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!