View Full Version : How can I control my Tessellation factors?

09-27-2017, 07:28 PM
Hi again, I am trying to somehow control my tessellation factors using keyboard control keys. Here's my code:

The GPU side of things...

Vertex Shader

#version 430 core

layout (location = 0) in vec3 vertex_position;
layout (location = 1) in vec3 vertex_color;

out vec3 Color;
out vec3 controlpoint;

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;
uniform float tessLevelInner;
uniform float tessLevelOutter;

void main()
gl_Position = Projection * View * Model * vec4(vertex_position, 1.0f);

Tessellation Control Shader

#version 430 core
layout (vertices = 3) out;

in vec3 Color[];
uniform float tessLevelInner = 4.0f; // Default value of 4
uniform float tessLevelOutter = 4.0f; // Default value of 4

void main()
gl_TessLevelInner[0] = tessLevelInner;
gl_TessLevelOuter[0] = tessLevelOutter;
gl_TessLevelOuter[1] = tessLevelOutter;
gl_TessLevelOuter[2] = tessLevelOutter;
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

Tessellation Evaluation Shader

#version 430 core

layout (triangles, equal_spacing, cw) in;

void main()
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
gl_TessCoord.y * gl_in[1].gl_Position +
gl_TessCoord.z * gl_in[2].gl_Position);

CPU side of things...

I create the shader program and do all the lovely things...

Now I have this function that is supposed to send floats to the TCS:

void Shader::UpdateLevelOfDetails(float inner, float outter)
GLuint innerLoc = glGetUniformLocation(m_program, "tessLevelInner");
GLuint outterLoc = glGetUniformLocation(m_program, "tessLevelOutter");
glUniform1fv(innerLoc, 1, &inner);
glUniform1fv(outterLoc, 1, &outter);

Then somewhere within my update function in my demo, I do this:

ShaderWithTessellation.UpdateLevelOfDetails(inner, outter); // Variables inner and outter are of type float and assigned the numbers 6 and 3 respectively

Then somewhere else in my code (I still didn't write that part yet), I control the levels via input.

So, what's happening, my inner and outter values are not affecting the shape whatsoever, it's like they don't exist as far as the TCS is concerned. If I remove the default values for the uniforms in my TCS, the whole shape (which is just a triangle) disappears.

Why is this not working? :confused:

All the best.

Alfonse Reinheart
09-27-2017, 08:54 PM
Given your TES shader... what exactly do you expect to see here? You do linear interpolation between the three positions. Which means that along the edges of the triangle, you'll get... the edges of the triangle.

You're effectively computing the exact same positions that the rasterizer will when it scan converts the triangle. Given your TES, the values shouldn't affect the shape.

If you want to see if tessellation is actually working, use wireframe rendering (glPolygonMode(GL_LINES)).

09-27-2017, 09:19 PM
The tessellation is working fine, I know how to use wireframe mode and check for myself. I want to be able to control the tessellation factors for LOD purposes.

09-27-2017, 09:28 PM
Sorry if you don't understand what I'm trying to do, I'm not very good at writing threads and such...

Basically I just want to be able to re-assign tessLevelInner and tessLevelOutter in the CPU when I press a button or something for now. After that I plan to use an algorithm that does that based on the distance of the camera. All this is just practice because I'd like to create a tessellated terrain at some point in the future hopefully.

09-28-2017, 02:24 AM
Okay, I figured out the problem. It seems like glUniform1f isn't doing what it's meant to be doing, which is override the default uniform values with values passed to it. I know this because I queried the result of my uniform with glGetUniformfv and it returned the default values even though I am passing new values to it every frame.

Has anyone encountered this problem before?


09-28-2017, 02:42 AM
Okay, this is silly. I've forgotten to activate the shader program before call to glUniform1f as glUniform() only affects the currently bound program. Therefore I had to call glUseProgram() before making any calls to glUniform(). Everything seems to be working just fine now (FINALLY!), thank you!