You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.1 KiB

4 months ago
#version 450
#extension GL_EXT_shader_atomic_float : enable
4 months ago
layout (local_size_x = 256) in;
4 months ago
struct Vertex {
vec3 position;
vec3 color;
uvec3 normal;
};
struct Face {
uint a;
uint b;
uint c;
};
layout (std430, set = 0, binding = 0) buffer VertexBuffer {
Vertex vertices[];
};
4 months ago
layout (std430, set = 0, binding = 1) buffer FaceBuffer {
4 months ago
Face faces[];
};
4 months ago
layout (std140, set = 0, binding = 5) uniform Sizes {
uint vertexCount;
uint faceCount;
};
4 months ago
4 months ago
layout (push_constant) uniform PushConstants {
4 months ago
uint state;
};
void atomicAddVec3(uint vID, vec3 add){
for (int i = 0; i < 3; i++) {
uint expected_memory = vertices[vID].normal[i];
float floatInput = uintBitsToFloat(vertices[vID].normal[i]) + add[i];
uint actual_content = atomicCompSwap(vertices[vID].normal[i], expected_memory, floatBitsToUint(floatInput));
while (actual_content != expected_memory) {
expected_memory = actual_content;
floatInput = uintBitsToFloat(expected_memory) + add[i];
actual_content = atomicCompSwap(vertices[vID].normal[i], expected_memory, floatBitsToUint(floatInput));
}
}
}
4 months ago
void reset(uint vID){
4 months ago
vertices[vID].normal = floatBitsToUint(vec3(0, 0, 0));
}
4 months ago
void accumulate(uint fID){
4 months ago
Face f = faces[fID];
Vertex v1 = vertices[f.a];
Vertex v2 = vertices[f.b];
Vertex v3 = vertices[f.c];
vec3 weightedNormal = cross(v3.position - v1.position, v2.position - v1.position);
atomicAddVec3(f.a, weightedNormal);
atomicAddVec3(f.b, weightedNormal);
atomicAddVec3(f.c, weightedNormal);
}
4 months ago
void norm(uint vID){
4 months ago
vertices[vID].normal = floatBitsToUint(normalize(uintBitsToFloat(vertices[vID].normal)));
}
void main() {
4 months ago
uint id = gl_GlobalInvocationID.x;
4 months ago
switch (state){
4 months ago
case 0:
if (id < vertexCount){
reset(id);
}
break;
case 1:
if (id < faceCount){
accumulate(id);
}
break;
case 2:
if (id < vertexCount){
norm(id);
}
break;
4 months ago
}
}