<p>The tessellation limit is GPU dependent..Any number above the GPU limit is technically an error but most gpu's just clamp to the upper limit. To get beyond the limit either use a Level Of Detail (LOD) approach where you have different models that are used based on distance, or save and recompute like you suggest.</p>
<p>To get the max just set all the edges to the limit AND set all the internals to the limit in the tessellation control shader:</p>
<pre><code>#version 460 core

  layout(vertices = 4) out;

void main(void)
{
   gl_TessLevelOuter[0] = 64.0;
   gl_TessLevelOuter[1] = 64.0;
   gl_TessLevelOuter[2] = 64.0;
   gl_TessLevelOuter[3] = 64.0;

   gl_TessLevelInner[0] = 64.0;
   gl_TessLevelInner[1] = 64.0;

   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}
</code></pre>
<blockquote>
<p>And how can I ask for the maximum division on CPU?</p>
</blockquote>
<p>Yes use glGetInteger. At the bottom of this page is all the values you would be intrested in: <a href="https://www.khronos.org/opengl/wiki/GLAPI/glGet" rel="nofollow noreferrer">Khoronos Tessellation limits, search for tessellation on the page</a></p>

CC BY-SA 4.0
2020-10-08T15:05:20.833Z
Thanks a lot! GL_MAX_TESS_GEN_LEVEL is what I was looking for.
Thomas
CC BY-SA 4.0
2020-10-08T14:04:48.023Z
2020-10-08T14:04:48.023Z
pmw1234
<p>I have a low-poly mesh and I want to add structure on the surface.</p>
<p><strong>The setup:</strong>
The mesh consists of triangles.
Within the TCS the pixel-length for each of the three edges will be calculated and subdivided according to the given allowed u_MAX_LENGTH_TRIANGLE_EDGE. This will be done in the following way:</p>
<pre><code>vec4 vertexPosScreen[3];                                           
for (int i = 0; i &lt; 3; i++)                                   
{                                                            
    vertexPosScreen[i] = vec4(mvp * gl_in[i].gl_Position);          
    vertexPosScreen[i] = vertexPosScreen[i] / vertexPosScreen[i].w; 
    vertexPosScreen[i].x *= u_viewportWidth;                     
    vertexPosScreen[i].y *= u_viewportHeight;                    
}         
float edgeLength[3];                                                                                                  
edgeLength[2] = length(vertexPosScreen[0].xy - vertexPosScreen[1].xy);
edgeLength[1] = length(vertexPosScreen[0].xy - vertexPosScreen[2].xy);
edgeLength[0] = length(vertexPosScreen[1].xy - vertexPosScreen[2].xy);           

float edgeLod[3];                                         
for (int i = 0; i &lt; 3; ++i)                           
{                                                       
    edgeLod[i] = max(1.0, edgeLength[i] / u_MAX_LENGTH_TRIANGLE_EDGE;
}                                                           
                                                                       
gl_TessLevelOuter[0] = edgeLod[0];                        
gl_TessLevelOuter[1] = edgeLod[1];                      
gl_TessLevelOuter[2] = edgeLod[2];                      
                                                                       
gl_TessLevelInner[0] = max(edgeLod[0], max(edgeLod[1], edgeLod[2]));
</code></pre>
<p>This guarantees, that in the final image all triangles edges are smaller than u_MAX_LENGTH_TRIANGLE_EDGE.</p>
<p><strong>But:</strong><br />
The GPU is not able to subdivide as mush as wanted. So if we are too close to a triangle, or a triangle is too tall at all, the TCS will subdivide it as mush as possible, but not enough.</p>
<p><strong>My Idea:</strong><br />
After tessellation is done, the new generated triangles should be stored into a new VBO during the TES step. Afterwards the fresh stored triangles in the new VBO will be rendered again and subdivided as well until all of them are small enough.</p>
<p><strong>Now the big question</strong><br />
How are the tessellation limits defined? per edge division? And how can I ask for the maximum division on CPU? glGetInteger? Or is it limited during the number of generated vertices?</p>
<p>I think the easiest solution would be check directly after &quot;edgeLod&quot; is calculated, if edgeLod is too high. If this is the case, write something into a SSBO and loop the shaderprogram again.</p>

<opengl><tesselation>
Tessellation Controll Shader how to get maximum subdivisions limit?
Thomas
# Tessellation Controll Shader how to get maximum subdivisions limit?

(Asked by: username_0 on 2020-10-08)

I have a low-poly mesh and I want to add structure on the surface.

**The setup:**
The mesh consists of triangles.
Within the TCS the pixel-length for each of the three edges will be calculated and subdivided according to the given allowed u\_MAX\_LENGTH\_TRIANGLE\_EDGE. This will be done in the following way:

```
vec4 vertexPosScreen[3];                                           
for (int i = 0; i < 3; i++)                                   
{                                                            
    vertexPosScreen[i] = vec4(mvp * gl_in[i].gl_Position);          
    vertexPosScreen[i] = vertexPosScreen[i] / vertexPosScreen[i].w; 
    vertexPosScreen[i].x *= u_viewportWidth;                     
    vertexPosScreen[i].y *= u_viewportHeight;                    
}         
float edgeLength[3];                                                                                                  
edgeLength[2] = length(vertexPosScreen[0].xy - vertexPosScreen[1].xy);
edgeLength[1] = length(vertexPosScreen[0].xy - vertexPosScreen[2].xy);
edgeLength[0] = length(vertexPosScreen[1].xy - vertexPosScreen[2].xy);           

float edgeLod[3];                                         
for (int i = 0; i < 3; ++i)                           
{                                                       
    edgeLod[i] = max(1.0, edgeLength[i] / u_MAX_LENGTH_TRIANGLE_EDGE;
}                                                           
                                                                       
gl_TessLevelOuter[0] = edgeLod[0];                        
gl_TessLevelOuter[1] = edgeLod[1];                      
gl_TessLevelOuter[2] = edgeLod[2];                      
                                                                       
gl_TessLevelInner[0] = max(edgeLod[0], max(edgeLod[1], edgeLod[2]));

```

This guarantees, that in the final image all triangles edges are smaller than u\_MAX\_LENGTH\_TRIANGLE\_EDGE.

**But:**  
The GPU is not able to subdivide as mush as wanted. So if we are too close to a triangle, or a triangle is too tall at all, the TCS will subdivide it as mush as possible, but not enough.

**My Idea:**  
After tessellation is done, the new generated triangles should be stored into a new VBO during the TES step. Afterwards the fresh stored triangles in the new VBO will be rendered again and subdivided as well until all of them are small enough.

**Now the big question**  
How are the tessellation limits defined? per edge division? And how can I ask for the maximum division on CPU? glGetInteger? Or is it limited during the number of generated vertices?

I think the easiest solution would be check directly after "edgeLod" is calculated, if edgeLod is too high. If this is the case, write something into a SSBO and loop the shaderprogram again.

**Tags:** opengl, tesselation


---

## 1 answers

### Answer by username_1 on 2020-10-08. Score: 1 | Accepted answer

The tessellation limit is GPU dependent..Any number above the GPU limit is technically an error but most gpu's just clamp to the upper limit. To get beyond the limit either use a Level Of Detail (LOD) approach where you have different models that are used based on distance, or save and recompute like you suggest.

To get the max just set all the edges to the limit AND set all the internals to the limit in the tessellation control shader:

```
#version 460 core

  layout(vertices = 4) out;

void main(void)
{
   gl_TessLevelOuter[0] = 64.0;
   gl_TessLevelOuter[1] = 64.0;
   gl_TessLevelOuter[2] = 64.0;
   gl_TessLevelOuter[3] = 64.0;

   gl_TessLevelInner[0] = 64.0;
   gl_TessLevelInner[1] = 64.0;

   gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

```

> And how can I ask for the maximum division on CPU?

Yes use glGetInteger. At the bottom of this page is all the values you would be intrested in: [Khoronos Tessellation limits, search for tessellation on the page](https://www.khronos.org/opengl/wiki/GLAPI/glGet)

> **Comments:**
> **username_0**: Thanks a lot! GL_MAX_TESS_GEN_LEVEL is what I was looking for.  

---

