0
\$\begingroup\$

I recently took an interest in sphere topologies to find which one is the best. The most popular one seems to be the fibonacci sphere. So I went and did some research and found some C code online that generates a fibonacci sphere. enter image description here

enter image description here

Obviously at the moment it doesn't look like a sphere, but when I normalize the vertices, it forms this enter image description here

enter image description here

It does form a sphere, but as you can see, there are a bunch of gaps in the sphere.

This is the function that generates the sphere

#include <math.h> #include <stdio.h> #define MAX_POINTS 1000 void fibonacci_sphere(int samples, float points[][3]) { /* Generates points on a sphere using Fibonacci spiral sampling. :param samples: Number of points to generate. :type samples: int :param points: Array to store generated points. :type points: list of lists :raises TypeError: If samples is not an integer or points is not a list of lists. :return: None */ // Validate inputs if (samples <= 0) { printf("Number of samples must be a positive integer.\n"); return; } if (points == NULL) { printf("Points array cannot be NULL.\n"); return; } // Calculate golden angle in radians float phi = M_PI * (sqrtf(5.0) + 1.0); // Generate points on sphere for (int i = 0; i < samples; i++) { // Calculate y coordinate float y = 1.0 - ((float)i / (float)(samples - 1)) * 2.0; // Calculate radius at y float radius = sqrtf(1.0 - y * y); // Calculate golden angle increment float theta = phi * i; // Calculate x, y, and z coordinates of point float x = cosf(theta) * radius; float z = sinf(theta) * radius; // Store point in points array points[i][0] = x; points[i][1] = y; points[i][2] = z; } // Log number of points generated printf("%d points generated on sphere.\n", samples); } 

And here is where I apply the function

float vertices[100][3]; fibonacci_sphere(100, vertices); unsigned int vbo, vao; glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); // upload vertex data to gpu glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) * sizeof(double), &vertices[0], GL_STATIC_DRAW); // position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // normal attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // amount of tessellation to do per triangle glPatchParameteri(GL_PATCH_VERTICES, 3); glBindVertexArray(vao); glDrawArrays(GL_PATCHES, 0, 100); 

Here are my tessellation shaders

#version 450 core // tessellation control // specify control points per output per patch // control size of input and output arrays layout(vertices=3) out; // input from vertex shader in vec3 vert_coord[]; // output to evaluation shader out vec3 vertex_coord[]; // for dynamic LOD (level of detail) uniform mat4 view; uniform mat4 model; void main() { // pass attributes through gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; vertex_coord[gl_InvocationID] = vert_coord[gl_InvocationID]; // control tessellation if(gl_InvocationID==0) { // dynamic LOD (from the learnopengl.com website) // first: define rendering constants to control tessellation const float MIN_TESS_LEVEL = 4; const float MAX_TESS_LEVEL = 64; const float MIN_DISTANCE = 20; const float MAX_DISTANCE = 800; // second: transform each vertex into each eye vec4 eye_space_pos_1 = view * model * gl_in[0].gl_Position; vec4 eye_space_pos_2 = view * model * gl_in[1].gl_Position; vec4 eye_space_pos_3 = view * model * gl_in[2].gl_Position; // third: distance from camera scaled between 0 and 1 float distance_1 = clamp((abs(eye_space_pos_1.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0); float distance_2 = clamp((abs(eye_space_pos_2.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0); float distance_3 = clamp((abs(eye_space_pos_3.z)-MIN_DISTANCE)/(MAX_DISTANCE-MIN_DISTANCE), 0.0, 1.0); // fourth: interpolate edge tessellation level based on closer vertex float tess_level_1 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_3, distance_1)); float tess_level_2 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_1, distance_2)); float tess_level_3 = mix(MAX_TESS_LEVEL, MIN_TESS_LEVEL, min(distance_2, distance_1)); // fifth: set the corresponding outer tessellation levels gl_TessLevelOuter[0] = tess_level_1; gl_TessLevelOuter[1] = tess_level_2; gl_TessLevelOuter[2] = tess_level_3; // sixth: set the inner tessellation levels gl_TessLevelInner[0] = max(tess_level_2, tess_level_1); gl_TessLevelInner[1] = max(tess_level_1, tess_level_3); } } // tessellation evaluation #version 450 core // determines what type of tessellation to do layout(triangles, equal_spacing, cw) in; // input from control shader in vec3 vertex_coord[]; // output vec out vec3 vert; // allows for object transformations uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { // gets barycentric coordinates from the triangles vec3 u = gl_TessCoord.x * vertex_coord[0]; vec3 v = gl_TessCoord.y * vertex_coord[1]; vec3 w = gl_TessCoord.z * vertex_coord[2]; // makes every triangle an equal distance from the center (that's how spheres are formed) vec3 pos = normalize(u + v + w); // output tessellated shape gl_Position = projection * view * model * vec4(pos, 1.0); } 
\$\endgroup\$
3
  • \$\begingroup\$ Let's try to isolate the problem by minimizing moving parts. Do you observe any difference if you remove tessellation entirely? From your screenshots, it looks like the vertices are correct, but the indices used to select which three vertices to join for each triangle are incorrect. \$\endgroup\$ Commented Jun 7, 2023 at 14:41
  • \$\begingroup\$ The first two images show what happens when tessellation is off \$\endgroup\$ Commented Jun 7, 2023 at 14:46
  • 1
    \$\begingroup\$ Then to isolate the problem, delete the rest. Solve the issue with the base mesh before you try to tessellate it. Once you get rendering of the base mesh working, if tessellation is still giving you trouble, you can post a new question just about the tessellation part. \$\endgroup\$ Commented Jun 7, 2023 at 20:26

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.