1

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.

Community
  • 1
  • 1
R00t
  • 186
  • 1
  • 2
  • 14

1 Answers1

0

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);
Dimo Markov
  • 422
  • 2
  • 9
  • Hi, I'm assuming you wanted to say `gl_in[n].gl_Position` ? I'm going to try it, thanks for you answer. I'll let you know for the result – R00t Apr 14 '15 at 17:24
  • Yes, sorry, I'm a bit in a hurry. Hope you get the idea :) I will edit my answer – Dimo Markov Apr 14 '15 at 17:26
  • Additionally, you may have errors on the poles, because usually, there are degenerate quads. It's not a good idea to generate spheres based on quads. A better approach would be to have an icosahedron for base, and subdivide the triangles. – Dimo Markov Apr 14 '15 at 17:28
  • [Here's something on that](http://sarvanz.blogspot.com/2013/07/sphere-triangulation-using-icosahedron.html) - that is called a geosphere. – Dimo Markov Apr 14 '15 at 17:29
  • When I used your solution, it produced some weird coordinates on the Z axis, so I thought it wasn't mapped to the good `gl_in`. `gl_in[2]` is for the `y` and `gl_in[3]` for the `z` and `gl_in[0]`or`[1]` for the x axis, and now it's producing this : http://imgur.com/11VYcTC It's almost it ! I'm gessing it has something to do with the indices, do you have any idea ? Thank you for you help – R00t Apr 14 '15 at 17:50
  • Hm, seems I've misguided you on one part. [Look at this code](https://github.com/adamlwgriffiths/GLETools/blob/master/examples/tesselation/lod.shader). Notice the part: `vec4 a = mix(gl_in[1].gl_Position, gl_in[0].gl_Position, u); vec4 b = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, u); gl_Position = projection * modelview * mix(a, b, v);` That is your solution. I'll edit my answer – Dimo Markov Apr 14 '15 at 18:00
  • Indeed, that was the correct solution, thanks again for your help. – R00t Apr 14 '15 at 19:33