For a game I'm making, I have to tessellate an octahedron into a sphere on the GPU (shaders). What I've done is I've successfully tessellated the faces, but I'm having trouble subdividing more spaces, or in better terms, create more faces on the shape. I'm using tessellation shaders to help with this. I would use geometry shaders, but from what I learned, I shouldn't because it makes the program performance worse, and it isn't worth using because tessellation shaders can already created new geometry like geometry shaders. TES (Tessellation Evaluation Shader)
#version 450 core
// from control shader
layout(triangles, equal_spacing, ccw) in;
// input from control shader
in vec3 vertex_coord[];
// output vec
out vec3 vert;
// allows for object transformations and for movement
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
// patch coords
float u = gl_TessCoord.x;
float v = gl_TessCoord.y;
float w = gl_TessCoord.z;
// retrieve control point vertex coordinates
vec3 t00 = vertex_coord[0];
vec3 t01 = vertex_coord[1];
vec3 t10 = vertex_coord[2];
// bi-linearly interpolate vertex coordinate across patch
vec3 t0 = (t01 - t00) * w + t00;
vec3 t1 = (t00 - t10) * v + t01;
vec3 t2 = (t10 - t01) * u + t10;
vec3 vert = (t1 - t0 - t2) * v + t0;
// retrieve control point position coordinates
vec4 p00 = gl_in[0].gl_Position;
vec4 p01 = gl_in[1].gl_Position;
vec4 p10 = gl_in[2].gl_Position;
// compute patch surface normal
vec4 u_vec = p01 - p00;
vec4 v_vec = p10 - p00;
vec4 w_vec = p10 - p01;
vec4 normal = normalize( vec4(cross(u_vec.xyz, v_vec.xyz), 0) );
// bi-linearly interpolate position coordinate across patch
vec4 p0 = (p01 - p00) * u + p00;
vec4 p1 = (p00 - p10) * v + p10;
vec4 p2 = (p01 - p00) * w + p01;
vec4 p = (p1 - p0) * w + p0;
// displace point along normal
//p += normal;
// output patch point position in clip space
gl_Position = projection * view * model * p;
}
For a reference, this is the type of subdivision I'm trying to go for, except it's not conducted on the CPU, it's on the GPU, for better performance, and because it seems to be easier to do than on the CPU.
After modifying the tessellation variables above, I came a little bit closer to what I was going for but still not quite (captured in wireframe mode)
As per @user253751's suggestion, I normalized the vertex coordinates and it didn't work as well as before. A birds eye view of the result:
Here are the original vertices that created the octahedron in case that might help someone better understand the problem.
float vertices[] = {
//top-north-east
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 0.0, 0.0,
//top-north-west
0.0, 1.0, 0.0,
-1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
//top-south-west
0.0, 1.0, 0.0,
0.0, 0.0, -1.0,
-1.0, 0.0, 0.0,
//top-south-east
0.0, 1.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, -1.0,
//bottom-north-east
0.0, -1.0, 0.0,
1.0, 0.0, 0.0,
0.0, 0.0, 1.0,
//bottom-north-west
0.0, -1.0, 0.0,
0.0, 0.0, 1.0,
-1.0, 0.0, 0.0,
//bottom-south-west
0.0, -1.0, 0.0,
-1.0, 0.0, 0.0,
0.0, 0.0, -1.0,
//bottom-south-east
0.0, -1.0, 0.0,
0.0, 0.0, -1.0,
1.0, 0.0, 0.0,
};
I also found these Wikipedia articles and a youtube video to help visualize my desired outcome for the program.
https://en.wikipedia.org/wiki/Geodesic_polyhedron
p
in the evaluation shader), observe how that varies the result and work backwards from there to track down which input/calculation isn't working as expected. \$\endgroup\$