subdivision-vertex.compute 1.41 KB
#version 430 core

#define M_PI    3.14159265358979323846

layout  (local_size_x  =  1)  in;

struct Vertex {
    vec3 pos;
    vec3 norm;
    vec2 uv;
};

layout(std430, binding=0) readonly buffer Vertices {
    Vertex vertices[];
};

layout(std430, binding=1) readonly buffer VertexIndices {
    unsigned int indices[];
};

layout(std430, binding=2) readonly buffer VertexOffsets {
    unsigned int offsets[];
};

layout(std430, binding=3) writeonly buffer Output {
    Vertex new_vertices[];
};

void main(){
    unsigned int size = offsets[gl_GlobalInvocationID.x + 1] - offsets[gl_GlobalInvocationID.x];

    new_vertices[gl_GlobalInvocationID.x].uv = vec2(0.0f, 0.0f);

    // FIXME: size or size - 1?
    float t = 3.0f/8.0f + 2.0f/8.0f * cos(2.0f * M_PI / (float(size) - 1.0f));
    float alpha = 5.0f/8.0f - t * t;

    vec3 pos = vec3(0.0f, 0.0f, 0.0f);
    vec3 norm = vec3(0.0f, 0.0f, 0.0f);
    for (unsigned int i = 1; i < size; i++) {
        pos += vertices[indices[offsets[gl_GlobalInvocationID.x] + i]].pos;
        norm += vertices[indices[offsets[gl_GlobalInvocationID.x] + i]].norm;
    }

    new_vertices[gl_GlobalInvocationID.x].pos = (1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].pos + alpha / (float(size) - 1.0f) * pos;
    new_vertices[gl_GlobalInvocationID.x].norm = normalize((1.0f - alpha) * vertices[indices[offsets[gl_GlobalInvocationID.x]]].norm + alpha / (float(size) - 1.0f) * norm);
}