<p>When doing it inside shader stages, one possibility is the following using vertex- and  tessellation-shader (only one triangle (3 lines) are needed):</p>
<p>Within the vertex shader you can calculate the NDC by the following code:</p>
<pre><code>vec4 NDC = mvp_matrix * vertexPosition;
NDC = NDC / NDC.a;
</code></pre>
<p>The NDC coordinate need to be handled over to the tessellation-control shader. There you can check, how far are the two connected vertices away from each other. Only test the x/y coordinates, because we want to know the distance of the pixels.</p>
<pre><code>vec2 len = abs(NDC[0].xy - NDC[1].xy);
</code></pre>
<p>Finally, the screen resolution must be taken into account:</p>
<pre><code>float numberOfDivisions = length(len * 0.5 * screenResolution); // the multiplication by 0.5 is required, because NDC range in x/y dimension is [-1, 1].
</code></pre>
<p><strong>Pro:</strong></p>
<ol>
<li>No vertex buffer object is needed... you can execute the shader for a minimum of three lines.</li>
<li>No uploading of vertex data. So except the draw command there is no CPU-&gt;GPU communication.</li>
</ol>
<p><strong>Contra:</strong></p>
<ol>
<li>In case the circle lies partly outside the view frustum or partly behind the camera, the output will be not like expected. So you need to do some clipping before.</li>
<li>when having high screen resolution, the input of only 3 lines (1 triangle) can be not enough, because the maximum subdivision of the tessellation stage can be too poor.</li>
</ol>

CC BY-SA 4.0
2023-05-05T09:20:46.930Z
2023-05-05T10:11:01.483Z
2023-05-05T10:11:01.483Z
Thomas
<p>I want to draw a circle in 3D from line segments. There are plenty of examples how to do this with an even number of subdivisions in 3D space, but I want the minimum number of subdivisions to produce a smooth circle after projection, without under- or over-subdividing. So a small circle (after projection) should require few subdivisions, a large circle should require more.</p>
<p>I could just calculate a fixed subdivision based on camera field-of-view and screen resolution, but that will only be correct for circles directly facing the camera.</p>
<p>Before I dig into the maths to figure this out I want to ask if there is already a well-known solution to this, because searches didn't come up with anything useful so far.</p>
<p>I have the feeling this is either solvable by stepping around the conic section projection of the circle in screen space, or by adjusting the step size based on the projection matrix.</p>
<p>Edit: I think subdivision methods are good solutions, especially for arbitrary curves. I was wondering if there is a closed solution exploiting symmetries of the circle. I'll need to have a think, but at least I doesn't look like I'm missing an existing solution.</p>

CC BY-SA 4.0
2023-05-05T08:12:03.653Z
Welcome to computer graphics stack exchange! I've a few questions: 
1: Which API are you using?
2: When rendering, are you using the tessellation stages?
3: Have you tried the following: Inside Vertex-shader calculate the NDS position of the vertex, then within your Tessellation-control-shader calculate how far are the connected vertices away from each other (only use the x/y coordinates)... and subdivide them regarding to the distance.
Thomas
CC BY-SA 4.0
2023-05-05T08:33:15.787Z
1: Doesn't matter, the solution will be the same for DirectX, Metal, OpenGL, Vulkan, Glide, etc. In my case it is on a high level adding the segments to a vertex buffer.  2: Not done in the shader, though the maths would be the same. Though I guess you would just look at a segment to decide if it needs to be subdivided? 3: Interesting idea, though I guess you'd need an initial subdivision of segments... maybe from a triangle? I'll have to think about that.
user1387
<projections><subdivision>
How do I evenly subdivide the projection of a circle in 3D?
user1387
# How do I evenly subdivide the projection of a circle in 3D?

(Asked by: username_0 on 2023-05-05)

I want to draw a circle in 3D from line segments. There are plenty of examples how to do this with an even number of subdivisions in 3D space, but I want the minimum number of subdivisions to produce a smooth circle after projection, without under- or over-subdividing. So a small circle (after projection) should require few subdivisions, a large circle should require more.

I could just calculate a fixed subdivision based on camera field-of-view and screen resolution, but that will only be correct for circles directly facing the camera.

Before I dig into the maths to figure this out I want to ask if there is already a well-known solution to this, because searches didn't come up with anything useful so far.

I have the feeling this is either solvable by stepping around the conic section projection of the circle in screen space, or by adjusting the step size based on the projection matrix.

Edit: I think subdivision methods are good solutions, especially for arbitrary curves. I was wondering if there is a closed solution exploiting symmetries of the circle. I'll need to have a think, but at least I doesn't look like I'm missing an existing solution.

**Tags:** projections, subdivision

> **Comments:**
> **username_1**: Welcome to computer graphics stack exchange! I've a few questions:  1: Which API are you using? 2: When rendering, are you using the tessellation stages? 3: Have you tried the following: Inside Vertex-shader calculate the NDS position of the vertex, then within your Tessellation-control-shader calculate how far are the connected vertices away from each other (only use the x/y coordinates)... and subdivide them regarding to the distance.  
> **username_0**: 1: Doesn't matter, the solution will be the same for DirectX, Metal, OpenGL, Vulkan, Glide, etc. In my case it is on a high level adding the segments to a vertex buffer.  2: Not done in the shader, though the maths would be the same. Though I guess you would just look at a segment to decide if it needs to be subdivided? 3: Interesting idea, though I guess you'd need an initial subdivision of segments... maybe from a triangle? I'll have to think about that.  

---

## 1 answers

### Answer by username_1 on 2023-05-05. Score: 1

When doing it inside shader stages, one possibility is the following using vertex- and tessellation-shader (only one triangle (3 lines) are needed):

Within the vertex shader you can calculate the NDC by the following code:

```
vec4 NDC = mvp_matrix * vertexPosition;
NDC = NDC / NDC.a;

```

The NDC coordinate need to be handled over to the tessellation-control shader. There you can check, how far are the two connected vertices away from each other. Only test the x/y coordinates, because we want to know the distance of the pixels.

```
vec2 len = abs(NDC[0].xy - NDC[1].xy);

```

Finally, the screen resolution must be taken into account:

```
float numberOfDivisions = length(len * 0.5 * screenResolution); // the multiplication by 0.5 is required, because NDC range in x/y dimension is [-1, 1].

```

**Pro:**

1. No vertex buffer object is needed... you can execute the shader for a minimum of three lines.
2. No uploading of vertex data. So except the draw command there is no CPU->GPU communication.

**Contra:**

1. In case the circle lies partly outside the view frustum or partly behind the camera, the output will be not like expected. So you need to do some clipping before.
2. when having high screen resolution, the input of only 3 lines (1 triangle) can be not enough, because the maximum subdivision of the tessellation stage can be too poor.


---

