<p>If you want to prevent cracks between the tessellated lines in a single curve, what you need to know is how to <a href="https://en.wikipedia.org/wiki/Miter_joint" rel="nofollow noreferrer">miter the quads</a> correctly. Your GS's extrusion is presumably based on taking the 2D perpendicular to the line direction and extending the quad in that direction. Well, don't do that.</p>

<p>Instead, have the TES compute the perpendicular direction for each vertex in the tessellation. You can compute this by taking the first derivative of the Bezier curve (its tangent), which can be computed exactly, and then finding the perpendicular of that. Each vertex will have its own perpendicular value.</p>

<p>It should be this perpendicular which you feed to the GS to do the quad extrusion. And you should be guaranteed to have invariant results. The TES's computation of the position and perpendicular will be based solely on the positions of the control points and the tessellation coordinates. The control points are fixed for all invocations of a TES over a patch, and the tessellator guarantees the invariance of <code>gl_TessCoord</code> for the "same vertex".</p>

<p>Invariance <em>between</em> patches will be something of a problem. That is, invariance between the end of one set of 4 control points and the beginning of an attached one. The tessellation system only guarantees invariance at edges between patches if the computations that lead to the positions of the vertices are all based <em>solely</em> on data that is binary identical between the two edge vertices. And that's not generally the case for bezier curves; you achieve C1 continuity by ensuring that the slope between boundary control points is the same. And that slope is <em>not</em> passed as a parameter; it is computed. And thus, two edge vertices on different patches could have slightly different slope computations, which leads to different vertices, which leads to invariance.</p>

<p>The only way to handle this is to have your Bezier spline defined by <em>six</em> control points rather than four. You pass as the first and last control points the previous/next control points for the Bezier spline (you'll have to make something up at the edges). This allows your computations to be invariant, since at the edges, you will be doing computations based on the exact same data.</p>

CC BY-SA 4.0
2018-11-18T16:22:55.583Z
2018-11-18T16:22:55.583Z
Nicol Bolas
<p>I'm trying to render thick cubic Bezier curves using the whole OpenGL 4.5 pipeline:</p>

<ol>
<li>I render a patch with 4 control points.  </li>
<li>Vertex shader is simply pass-through to tessellation control shader.  </li>
<li>TCS - sendng 4 vertices to tessalator with <code>gl_TessLevelOuter[1] = 10</code> </li>
<li>TES - calculating position for every of those 10 tessellated isoline points using Bezier curve equation  </li>
<li>Geometry shader - making quads out of every line it receives extruding vertices along line's normal vector.</li>
</ol>

<p>So far so good but this will obviously lead to cracks between adjacent quads. To solve this problem I would need to know the position of adjacent lines in TES or GS to correct edges. Is this information available?</p>

<opengl><glsl>
Is it possible to access adjacent vertex data in tessellation evaluation shader?
SurpriseQuestion
# Is it possible to access adjacent vertex data in tessellation evaluation shader?

(Asked by: username_0 on 2018-11-18)

I'm trying to render thick cubic Bezier curves using the whole OpenGL 4.5 pipeline:

1. I render a patch with 4 control points.
2. Vertex shader is simply pass-through to tessellation control shader.
3. TCS - sendng 4 vertices to tessalator with `gl_TessLevelOuter[1] = 10`
4. TES - calculating position for every of those 10 tessellated isoline points using Bezier curve equation
5. Geometry shader - making quads out of every line it receives extruding vertices along line's normal vector.

So far so good but this will obviously lead to cracks between adjacent quads. To solve this problem I would need to know the position of adjacent lines in TES or GS to correct edges. Is this information available?

**Tags:** opengl, glsl


---

## 1 answers

### Answer by username_1 on 2018-11-18. Score: 2

If you want to prevent cracks between the tessellated lines in a single curve, what you need to know is how to [miter the quads](https://en.wikipedia.org/wiki/Miter_joint) correctly. Your GS's extrusion is presumably based on taking the 2D perpendicular to the line direction and extending the quad in that direction. Well, don't do that.

Instead, have the TES compute the perpendicular direction for each vertex in the tessellation. You can compute this by taking the first derivative of the Bezier curve (its tangent), which can be computed exactly, and then finding the perpendicular of that. Each vertex will have its own perpendicular value.

It should be this perpendicular which you feed to the GS to do the quad extrusion. And you should be guaranteed to have invariant results. The TES's computation of the position and perpendicular will be based solely on the positions of the control points and the tessellation coordinates. The control points are fixed for all invocations of a TES over a patch, and the tessellator guarantees the invariance of `gl_TessCoord` for the "same vertex".

Invariance *between* patches will be something of a problem. That is, invariance between the end of one set of 4 control points and the beginning of an attached one. The tessellation system only guarantees invariance at edges between patches if the computations that lead to the positions of the vertices are all based *solely* on data that is binary identical between the two edge vertices. And that's not generally the case for bezier curves; you achieve C1 continuity by ensuring that the slope between boundary control points is the same. And that slope is *not* passed as a parameter; it is computed. And thus, two edge vertices on different patches could have slightly different slope computations, which leads to different vertices, which leads to invariance.

The only way to handle this is to have your Bezier spline defined by *six* control points rather than four. You pass as the first and last control points the previous/next control points for the Bezier spline (you'll have to make something up at the edges). This allows your computations to be invariant, since at the edges, you will be doing computations based on the exact same data.


---

