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.
78 lines
1.9 KiB
78 lines
1.9 KiB
#version 450
|
|
#extension GL_EXT_shader_atomic_float : enable
|
|
|
|
|
|
|
|
layout (local_size_x = 256) in;
|
|
|
|
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[];
|
|
};
|
|
layout (std430, set = 0, binding = 1) buffer FaceBuffer {
|
|
Face faces[];
|
|
};
|
|
layout (std140, set = 0, binding = 2) uniform UniformBuffer {
|
|
uint vertexCount;
|
|
uint faceCount;
|
|
};
|
|
|
|
layout (push_constant) uniform PushConstants {
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
void reset(){
|
|
uint vID = gl_GlobalInvocationID.x;
|
|
vertices[vID].normal = floatBitsToUint(vec3(0, 0, 0));
|
|
}
|
|
|
|
void accumulate(){
|
|
uint fID = gl_GlobalInvocationID.x;
|
|
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);
|
|
}
|
|
|
|
void norm(){
|
|
uint vID = gl_GlobalInvocationID.x;
|
|
vertices[vID].normal = floatBitsToUint(normalize(uintBitsToFloat(vertices[vID].normal)));
|
|
}
|
|
|
|
void main() {
|
|
switch (state){
|
|
case 0: reset(); break;
|
|
case 1: accumulate(); break;
|
|
case 2: norm(); break;
|
|
}
|
|
} |