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 :
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.
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);