Search code examples
opengltessellation

Sphere Tessellation wrong coordinates


I'm trying to apply a tessellation on the GPU for a simple Sphere. This tessellation is working perfectly for a simple plan, but it's not working for the sphere. Of course, I know the coordinates mapping aren't the same, I tried many ways to do it. For example, I tried to use the gl_TessCoord (x and y) in the tessellation Evaluation as longitude et latitude mapped into a plane. Then convert them to a spherical coordinates, but it 'really' didn't work.

For the tessellation control, I'm just splitting all patches into 2 for the outer and 2 as well for the inner level.

Here is my code to draw the sphere :

glBindVertexArray(vertexArrayObject);
glPatchParameteri(GL_PATCH_VERTICES, 4);


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glDrawElements(GL_PATCHES, indices.length, GL_UNSIGNED_INT, 0);


glBindVertexArray(0);

Here my current code in the tessellation Evaluation :

#version 430 


layout(quads, fractional_even_spacing, ccw) in;


uniform mat4 u_projectionMatrix; 
uniform mat4 u_viewMatrix; 
uniform mat4 u_transformMatrix;
uniform float u_radius;  
uniform vec3 u_cameraPosition; 




void main(void){
vec4 position = gl_in[0].gl_Position;
position.xz += gl_TessCoord.xy * 2.0 - 1.0; 
gl_Position = u_projectionMatrix * u_viewMatrix * u_transformMatrix * position; 
}

Here are the indices :

int indPtr = 0;

for(int r=0; r< mRings-1; r++)
for(int s=0; s<mSectors-1; s++){
indices[indPtr++] = r * mSectors + s; 
indices[indPtr++] = r * mSectors + (s+1); 
indices[indPtr++] = (r+1) * mSectors + (s+1); 
indices[indPtr++] = (r+1) * mSectors + s; 
}

To draw the sphere, I followed this example : Creating a 3D sphere in Opengl using Visual C++ so all credits go to him (And thank you by the way !).

Here are two images showing the result :

Fist image enter image description here

If you have any hint that could help me solve this problem, It'd be really cool. Thank you. Note : If you need any other informations, please ask me and I'll post them.


Solution

  • Seems like you're only taking the first vertex (which lies on the sphere) and then offset it only horizontally (on the xz plane) by gl_TessCoord.xy:

    vec4 position = gl_in[0].gl_Position;
    position.xz += gl_TessCoord.xy * 2.0 - 1.0; 
    

    Since you're producing quads, you take gl_in of size 4 points. You're interrested in only the first three. So your final position can be interpolated by this:

    vec4 a = mix(gl_in[1].gl_Position, gl_in[0].gl_Position, gl_TessCoord.x);
    vec4 b = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, gl_TessCoord.x);
    gl_Position = projectionMatrix * viewMatrix * transformMatrix * mix(a, b, gl_TessCoord.y);
    

    (source)

    That should fix your problem.

    P.S. For normals, do the following (if your sphere is generated around the origin):

    vec3 normal = mat3x3(viewMatrix*transformMatrix) * normalize(position.xyz);