skeleton.glsl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #[compute]
  2. #version 450
  3. #VERSION_DEFINES
  4. layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
  5. layout(set = 0, binding = 1, std430) buffer restrict writeonly DstVertexData {
  6. uint data[];
  7. }
  8. dst_vertices;
  9. layout(set = 0, binding = 2, std430) buffer restrict readonly BlendShapeWeights {
  10. float data[];
  11. }
  12. blend_shape_weights;
  13. layout(set = 1, binding = 0, std430) buffer restrict readonly SrcVertexData {
  14. uint data[];
  15. }
  16. src_vertices;
  17. layout(set = 1, binding = 1, std430) buffer restrict readonly BoneWeightData {
  18. uint data[];
  19. }
  20. src_bone_weights;
  21. layout(set = 1, binding = 2, std430) buffer restrict readonly BlendShapeData {
  22. uint data[];
  23. }
  24. src_blend_shapes;
  25. layout(set = 2, binding = 0, std430) buffer restrict readonly SkeletonData {
  26. vec4 data[];
  27. }
  28. bone_transforms;
  29. layout(push_constant, std430) uniform Params {
  30. bool has_normal;
  31. bool has_tangent;
  32. bool has_skeleton;
  33. bool has_blend_shape;
  34. uint vertex_count;
  35. uint vertex_stride;
  36. uint skin_stride;
  37. uint skin_weight_offset;
  38. uint blend_shape_count;
  39. bool normalized_blend_shapes;
  40. uint normal_tangent_stride;
  41. uint pad1;
  42. vec2 skeleton_transform_x;
  43. vec2 skeleton_transform_y;
  44. vec2 skeleton_transform_offset;
  45. vec2 inverse_transform_x;
  46. vec2 inverse_transform_y;
  47. vec2 inverse_transform_offset;
  48. }
  49. params;
  50. vec2 uint_to_vec2(uint base) {
  51. uvec2 decode = (uvec2(base) >> uvec2(0, 16)) & uvec2(0xFFFF, 0xFFFF);
  52. return vec2(decode) / vec2(65535.0, 65535.0) * 2.0 - 1.0;
  53. }
  54. vec3 oct_to_vec3(vec2 oct) {
  55. vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y));
  56. float t = max(-v.z, 0.0);
  57. v.xy += t * -sign(v.xy);
  58. return normalize(v);
  59. }
  60. vec3 decode_uint_oct_to_norm(uint base) {
  61. return oct_to_vec3(uint_to_vec2(base));
  62. }
  63. vec4 decode_uint_oct_to_tang(uint base) {
  64. vec2 oct_sign_encoded = uint_to_vec2(base);
  65. // Binormal sign encoded in y component
  66. vec2 oct = vec2(oct_sign_encoded.x, abs(oct_sign_encoded.y) * 2.0 - 1.0);
  67. return vec4(oct_to_vec3(oct), sign(oct_sign_encoded.y));
  68. }
  69. vec2 signNotZero(vec2 v) {
  70. return mix(vec2(-1.0), vec2(1.0), greaterThanEqual(v.xy, vec2(0.0)));
  71. }
  72. uint vec2_to_uint(vec2 base) {
  73. uvec2 enc = uvec2(clamp(ivec2(base * vec2(65535, 65535)), ivec2(0), ivec2(0xFFFF, 0xFFFF))) << uvec2(0, 16);
  74. return enc.x | enc.y;
  75. }
  76. vec2 vec3_to_oct(vec3 e) {
  77. e /= abs(e.x) + abs(e.y) + abs(e.z);
  78. vec2 oct = e.z >= 0.0f ? e.xy : (vec2(1.0f) - abs(e.yx)) * signNotZero(e.xy);
  79. return oct * 0.5f + 0.5f;
  80. }
  81. uint encode_norm_to_uint_oct(vec3 base) {
  82. return vec2_to_uint(vec3_to_oct(base));
  83. }
  84. uint encode_tang_to_uint_oct(vec4 base) {
  85. vec2 oct = vec3_to_oct(base.xyz);
  86. // Encode binormal sign in y component
  87. oct.y = oct.y * 0.5f + 0.5f;
  88. oct.y = base.w >= 0.0f ? oct.y : 1 - oct.y;
  89. return vec2_to_uint(oct);
  90. }
  91. void main() {
  92. uint index = gl_GlobalInvocationID.x;
  93. if (index >= params.vertex_count) {
  94. return;
  95. }
  96. uint src_offset = index * params.vertex_stride;
  97. #ifdef MODE_2D
  98. vec2 vertex = uintBitsToFloat(uvec2(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1]));
  99. if (params.has_blend_shape) {
  100. float blend_total = 0.0;
  101. vec2 blend_vertex = vec2(0.0);
  102. for (uint i = 0; i < params.blend_shape_count; i++) {
  103. float w = blend_shape_weights.data[i];
  104. if (abs(w) > 0.0001) {
  105. uint base_offset = (params.vertex_count * i + index) * params.vertex_stride;
  106. blend_vertex += uintBitsToFloat(uvec2(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1])) * w;
  107. base_offset += 2;
  108. blend_total += w;
  109. }
  110. }
  111. if (params.normalized_blend_shapes) {
  112. vertex = (1.0 - blend_total) * vertex;
  113. }
  114. vertex += blend_vertex;
  115. }
  116. if (params.has_skeleton) {
  117. uint skin_offset = params.skin_stride * index;
  118. uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  119. uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 2; //pre-add xform offset
  120. uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 2;
  121. skin_offset += params.skin_weight_offset;
  122. uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  123. vec2 weights_01 = unpackUnorm2x16(weights.x);
  124. vec2 weights_23 = unpackUnorm2x16(weights.y);
  125. mat4 m = mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x;
  126. m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y;
  127. m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x;
  128. m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
  129. mat4 skeleton_matrix = mat4(vec4(params.skeleton_transform_x, 0.0, 0.0), vec4(params.skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.skeleton_transform_offset, 0.0, 1.0));
  130. mat4 inverse_matrix = mat4(vec4(params.inverse_transform_x, 0.0, 0.0), vec4(params.inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.inverse_transform_offset, 0.0, 1.0));
  131. m = skeleton_matrix * transpose(m) * inverse_matrix;
  132. vertex = (m * vec4(vertex, 0.0, 1.0)).xy;
  133. }
  134. uint dst_offset = index * params.vertex_stride;
  135. uvec2 uvertex = floatBitsToUint(vertex);
  136. dst_vertices.data[dst_offset + 0] = uvertex.x;
  137. dst_vertices.data[dst_offset + 1] = uvertex.y;
  138. #else
  139. vec3 vertex;
  140. vec3 normal;
  141. vec4 tangent;
  142. vertex = uintBitsToFloat(uvec3(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1], src_vertices.data[src_offset + 2]));
  143. uint src_normal = params.vertex_count * params.vertex_stride + index * params.normal_tangent_stride;
  144. if (params.has_normal) {
  145. normal = decode_uint_oct_to_norm(src_vertices.data[src_normal]);
  146. src_normal++;
  147. }
  148. if (params.has_tangent) {
  149. tangent = decode_uint_oct_to_tang(src_vertices.data[src_normal]);
  150. }
  151. if (params.has_blend_shape) {
  152. float blend_total = 0.0;
  153. vec3 blend_vertex = vec3(0.0);
  154. vec3 blend_normal = vec3(0.0);
  155. vec3 blend_tangent = vec3(0.0);
  156. for (uint i = 0; i < params.blend_shape_count; i++) {
  157. float w = blend_shape_weights.data[i];
  158. if (abs(w) > 0.0001) {
  159. uint base_offset = params.vertex_count * i * (params.vertex_stride + params.normal_tangent_stride) + index * params.vertex_stride;
  160. blend_vertex += uintBitsToFloat(uvec3(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1], src_blend_shapes.data[base_offset + 2])) * w;
  161. uint base_normal = params.vertex_count * i * (params.vertex_stride + params.normal_tangent_stride) + params.vertex_count * params.vertex_stride + index * params.normal_tangent_stride;
  162. if (params.has_normal) {
  163. blend_normal += decode_uint_oct_to_norm(src_blend_shapes.data[base_normal]) * w;
  164. base_normal++;
  165. }
  166. if (params.has_tangent) {
  167. blend_tangent += decode_uint_oct_to_tang(src_blend_shapes.data[base_normal]).rgb * w;
  168. }
  169. blend_total += w;
  170. }
  171. }
  172. if (params.normalized_blend_shapes) {
  173. vertex = (1.0 - blend_total) * vertex;
  174. normal = (1.0 - blend_total) * normal;
  175. tangent.rgb = (1.0 - blend_total) * tangent.rgb;
  176. }
  177. vertex += blend_vertex;
  178. normal = normalize(normal + blend_normal);
  179. tangent.rgb = normalize(tangent.rgb + blend_tangent);
  180. }
  181. if (params.has_skeleton) {
  182. uint skin_offset = params.skin_stride * index;
  183. uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  184. uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset
  185. uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3;
  186. skin_offset += params.skin_weight_offset;
  187. uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  188. vec2 weights_01 = unpackUnorm2x16(weights.x);
  189. vec2 weights_23 = unpackUnorm2x16(weights.y);
  190. mat4 m = mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], bone_transforms.data[bones_01.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x;
  191. m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], bone_transforms.data[bones_01.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y;
  192. m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], bone_transforms.data[bones_23.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x;
  193. m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], bone_transforms.data[bones_23.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
  194. if (params.skin_weight_offset == 4) {
  195. //using 8 bones/weights
  196. skin_offset = params.skin_stride * index + 2;
  197. bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  198. bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset
  199. bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3;
  200. skin_offset += params.skin_weight_offset;
  201. weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]);
  202. weights_01 = unpackUnorm2x16(weights.x);
  203. weights_23 = unpackUnorm2x16(weights.y);
  204. m += mat4(bone_transforms.data[bones_01.x], bone_transforms.data[bones_01.x + 1], bone_transforms.data[bones_01.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.x;
  205. m += mat4(bone_transforms.data[bones_01.y], bone_transforms.data[bones_01.y + 1], bone_transforms.data[bones_01.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_01.y;
  206. m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], bone_transforms.data[bones_23.x + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x;
  207. m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], bone_transforms.data[bones_23.y + 2], vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y;
  208. }
  209. //reverse order because its transposed
  210. vertex = (vec4(vertex, 1.0) * m).xyz;
  211. normal = normalize((vec4(normal, 0.0) * m).xyz);
  212. tangent.xyz = normalize((vec4(tangent.xyz, 0.0) * m).xyz);
  213. }
  214. uint dst_offset = index * params.vertex_stride;
  215. uvec3 uvertex = floatBitsToUint(vertex);
  216. dst_vertices.data[dst_offset + 0] = uvertex.x;
  217. dst_vertices.data[dst_offset + 1] = uvertex.y;
  218. dst_vertices.data[dst_offset + 2] = uvertex.z;
  219. uint dst_normal = params.vertex_count * params.vertex_stride + index * params.normal_tangent_stride;
  220. if (params.has_normal) {
  221. dst_vertices.data[dst_normal] = encode_norm_to_uint_oct(normal);
  222. dst_normal++;
  223. }
  224. if (params.has_tangent) {
  225. dst_vertices.data[dst_normal] = encode_tang_to_uint_oct(tangent);
  226. }
  227. #endif
  228. }