skeleton.glsl 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* clang-format off */
  2. #[modes]
  3. mode_base_pass =
  4. mode_blend_pass = #define MODE_BLEND_PASS
  5. #[specializations]
  6. MODE_2D = true
  7. USE_BLEND_SHAPES = false
  8. USE_SKELETON = false
  9. USE_NORMAL = false
  10. USE_TANGENT = false
  11. FINAL_PASS = false
  12. USE_EIGHT_WEIGHTS = false
  13. #[vertex]
  14. #include "stdlib_inc.glsl"
  15. #ifdef MODE_2D
  16. #define VFORMAT vec2
  17. #else
  18. #define VFORMAT vec3
  19. #endif
  20. #ifdef FINAL_PASS
  21. #define OFORMAT vec2
  22. #else
  23. #define OFORMAT uvec2
  24. #endif
  25. // These come from the source mesh and the output from previous passes.
  26. layout(location = 0) in highp VFORMAT in_vertex;
  27. #ifdef MODE_BLEND_PASS
  28. #ifdef USE_NORMAL
  29. layout(location = 1) in highp uvec2 in_normal;
  30. #endif
  31. #ifdef USE_TANGENT
  32. layout(location = 2) in highp uvec2 in_tangent;
  33. #endif
  34. #else // MODE_BLEND_PASS
  35. #ifdef USE_NORMAL
  36. layout(location = 1) in highp vec2 in_normal;
  37. #endif
  38. #ifdef USE_TANGENT
  39. layout(location = 2) in highp vec2 in_tangent;
  40. #endif
  41. #endif // MODE_BLEND_PASS
  42. #ifdef USE_SKELETON
  43. #ifdef USE_EIGHT_WEIGHTS
  44. layout(location = 10) in highp uvec4 in_bone_attrib;
  45. layout(location = 11) in highp uvec4 in_bone_attrib2;
  46. layout(location = 12) in mediump vec4 in_weight_attrib;
  47. layout(location = 13) in mediump vec4 in_weight_attrib2;
  48. #else
  49. layout(location = 10) in highp uvec4 in_bone_attrib;
  50. layout(location = 11) in mediump vec4 in_weight_attrib;
  51. #endif
  52. uniform highp sampler2D skeleton_texture; // texunit:0
  53. #endif
  54. /* clang-format on */
  55. #ifdef MODE_BLEND_PASS
  56. layout(location = 3) in highp VFORMAT blend_vertex;
  57. #ifdef USE_NORMAL
  58. layout(location = 4) in highp vec2 blend_normal;
  59. #endif
  60. #ifdef USE_TANGENT
  61. layout(location = 5) in highp vec2 blend_tangent;
  62. #endif
  63. #endif // MODE_BLEND_PASS
  64. out highp VFORMAT out_vertex; //tfb:
  65. #ifdef USE_NORMAL
  66. flat out highp OFORMAT out_normal; //tfb:USE_NORMAL
  67. #endif
  68. #ifdef USE_TANGENT
  69. flat out highp OFORMAT out_tangent; //tfb:USE_TANGENT
  70. #endif
  71. #ifdef USE_BLEND_SHAPES
  72. uniform highp float blend_weight;
  73. uniform lowp float blend_shape_count;
  74. #endif
  75. #ifdef USE_SKELETON
  76. uniform mediump vec2 skeleton_transform_x;
  77. uniform mediump vec2 skeleton_transform_y;
  78. uniform mediump vec2 skeleton_transform_offset;
  79. uniform mediump vec2 inverse_transform_x;
  80. uniform mediump vec2 inverse_transform_y;
  81. uniform mediump vec2 inverse_transform_offset;
  82. #endif
  83. vec2 signNotZero(vec2 v) {
  84. return mix(vec2(-1.0), vec2(1.0), greaterThanEqual(v.xy, vec2(0.0)));
  85. }
  86. vec3 oct_to_vec3(vec2 oct) {
  87. oct = oct * 2.0 - 1.0;
  88. vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y));
  89. if (v.z < 0.0) {
  90. v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
  91. }
  92. return normalize(v);
  93. }
  94. vec2 vec3_to_oct(vec3 e) {
  95. e /= abs(e.x) + abs(e.y) + abs(e.z);
  96. vec2 oct = e.z >= 0.0f ? e.xy : (vec2(1.0f) - abs(e.yx)) * signNotZero(e.xy);
  97. return oct * 0.5f + 0.5f;
  98. }
  99. vec4 oct_to_tang(vec2 oct_sign_encoded) {
  100. // Binormal sign encoded in y component
  101. vec2 oct = vec2(oct_sign_encoded.x, abs(oct_sign_encoded.y) * 2.0 - 1.0);
  102. return vec4(oct_to_vec3(oct), sign(oct_sign_encoded.y));
  103. }
  104. vec2 tang_to_oct(vec4 base) {
  105. vec2 oct = vec3_to_oct(base.xyz);
  106. // Encode binormal sign in y component
  107. oct.y = oct.y * 0.5f + 0.5f;
  108. oct.y = base.w >= 0.0f ? oct.y : 1.0 - oct.y;
  109. return oct;
  110. }
  111. // Our original input for normals and tangents is 2 16-bit floats.
  112. // Transform Feedback has to write out 32-bits per channel.
  113. // Octahedral compression requires normalized vectors, but we need to store
  114. // non-normalized vectors until the very end.
  115. // Therefore, we will compress our normals into 16 bits using signed-normalized
  116. // fixed point precision. This works well, because we know that each normal
  117. // is no larger than |1| so we can normalize by dividing by the number of blend
  118. // shapes.
  119. uvec2 vec4_to_vec2(vec4 p_vec) {
  120. return uvec2(packSnorm2x16(p_vec.xy), packSnorm2x16(p_vec.zw));
  121. }
  122. vec4 vec2_to_vec4(uvec2 p_vec) {
  123. return vec4(unpackSnorm2x16(p_vec.x), unpackSnorm2x16(p_vec.y));
  124. }
  125. void main() {
  126. #ifdef MODE_2D
  127. out_vertex = in_vertex;
  128. #ifdef USE_BLEND_SHAPES
  129. #ifdef MODE_BLEND_PASS
  130. out_vertex = in_vertex + blend_vertex * blend_weight;
  131. #else
  132. out_vertex = in_vertex * blend_weight;
  133. #endif
  134. #ifdef FINAL_PASS
  135. out_vertex = normalize(out_vertex);
  136. #endif
  137. #endif // USE_BLEND_SHAPES
  138. #ifdef USE_SKELETON
  139. #define TEX(m) texelFetch(skeleton_texture, ivec2(m % 256u, m / 256u), 0)
  140. #define GET_BONE_MATRIX(a, b, w) mat2x4(TEX(a), TEX(b)) * w
  141. uvec4 bones = in_bone_attrib * uvec4(2u);
  142. uvec4 bones_a = bones + uvec4(1u);
  143. highp mat2x4 m = GET_BONE_MATRIX(bones.x, bones_a.x, in_weight_attrib.x);
  144. m += GET_BONE_MATRIX(bones.y, bones_a.y, in_weight_attrib.y);
  145. m += GET_BONE_MATRIX(bones.z, bones_a.z, in_weight_attrib.z);
  146. m += GET_BONE_MATRIX(bones.w, bones_a.w, in_weight_attrib.w);
  147. mat4 skeleton_matrix = mat4(vec4(skeleton_transform_x, 0.0, 0.0), vec4(skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(skeleton_transform_offset, 0.0, 1.0));
  148. mat4 inverse_matrix = mat4(vec4(inverse_transform_x, 0.0, 0.0), vec4(inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(inverse_transform_offset, 0.0, 1.0));
  149. mat4 bone_matrix = mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
  150. bone_matrix = skeleton_matrix * transpose(bone_matrix) * inverse_matrix;
  151. out_vertex = (bone_matrix * vec4(out_vertex, 0.0, 1.0)).xy;
  152. #endif // USE_SKELETON
  153. #else // MODE_2D
  154. #ifdef USE_BLEND_SHAPES
  155. #ifdef MODE_BLEND_PASS
  156. out_vertex = in_vertex + blend_vertex * blend_weight;
  157. #ifdef USE_NORMAL
  158. vec3 normal = vec2_to_vec4(in_normal).xyz * blend_shape_count;
  159. vec3 normal_blend = oct_to_vec3(blend_normal) * blend_weight;
  160. #ifdef FINAL_PASS
  161. out_normal = vec3_to_oct(normalize(normal + normal_blend));
  162. #else
  163. out_normal = vec4_to_vec2(vec4(normal + normal_blend, 0.0) / blend_shape_count);
  164. #endif
  165. #endif // USE_NORMAL
  166. #ifdef USE_TANGENT
  167. vec4 tangent = vec2_to_vec4(in_tangent) * blend_shape_count;
  168. vec4 tangent_blend = oct_to_tang(blend_tangent) * blend_weight;
  169. #ifdef FINAL_PASS
  170. out_tangent = tang_to_oct(vec4(normalize(tangent.xyz + tangent_blend.xyz), tangent.w));
  171. #else
  172. out_tangent = vec4_to_vec2(vec4((tangent.xyz + tangent_blend.xyz) / blend_shape_count, tangent.w));
  173. #endif
  174. #endif // USE_TANGENT
  175. #else // MODE_BLEND_PASS
  176. out_vertex = in_vertex * blend_weight;
  177. #ifdef USE_NORMAL
  178. vec3 normal = oct_to_vec3(in_normal);
  179. out_normal = vec4_to_vec2(vec4(normal * blend_weight / blend_shape_count, 0.0));
  180. #endif
  181. #ifdef USE_TANGENT
  182. vec4 tangent = oct_to_tang(in_tangent);
  183. out_tangent = vec4_to_vec2(vec4(tangent.rgb * blend_weight / blend_shape_count, tangent.w));
  184. #endif
  185. #endif // MODE_BLEND_PASS
  186. #else // USE_BLEND_SHAPES
  187. // Make attributes available to the skeleton shader if not written by blend shapes.
  188. out_vertex = in_vertex;
  189. #ifdef USE_NORMAL
  190. out_normal = in_normal;
  191. #endif
  192. #ifdef USE_TANGENT
  193. out_tangent = in_tangent;
  194. #endif
  195. #endif // USE_BLEND_SHAPES
  196. #ifdef USE_SKELETON
  197. #define TEX(m) texelFetch(skeleton_texture, ivec2(m % 256u, m / 256u), 0)
  198. #define GET_BONE_MATRIX(a, b, c, w) mat4(TEX(a), TEX(b), TEX(c), vec4(0.0, 0.0, 0.0, 1.0)) * w
  199. uvec4 bones = in_bone_attrib * uvec4(3);
  200. uvec4 bones_a = bones + uvec4(1);
  201. uvec4 bones_b = bones + uvec4(2);
  202. highp mat4 m;
  203. m = GET_BONE_MATRIX(bones.x, bones_a.x, bones_b.x, in_weight_attrib.x);
  204. m += GET_BONE_MATRIX(bones.y, bones_a.y, bones_b.y, in_weight_attrib.y);
  205. m += GET_BONE_MATRIX(bones.z, bones_a.z, bones_b.z, in_weight_attrib.z);
  206. m += GET_BONE_MATRIX(bones.w, bones_a.w, bones_b.w, in_weight_attrib.w);
  207. #ifdef USE_EIGHT_WEIGHTS
  208. bones = in_bone_attrib2 * uvec4(3);
  209. bones_a = bones + uvec4(1);
  210. bones_b = bones + uvec4(2);
  211. m += GET_BONE_MATRIX(bones.x, bones_a.x, bones_b.x, in_weight_attrib2.x);
  212. m += GET_BONE_MATRIX(bones.y, bones_a.y, bones_b.y, in_weight_attrib2.y);
  213. m += GET_BONE_MATRIX(bones.z, bones_a.z, bones_b.z, in_weight_attrib2.z);
  214. m += GET_BONE_MATRIX(bones.w, bones_a.w, bones_b.w, in_weight_attrib2.w);
  215. #endif
  216. // Reverse order because its transposed.
  217. out_vertex = (vec4(out_vertex, 1.0) * m).xyz;
  218. #ifdef USE_NORMAL
  219. vec3 vertex_normal = oct_to_vec3(out_normal);
  220. out_normal = vec3_to_oct(normalize((vec4(vertex_normal, 0.0) * m).xyz));
  221. #endif // USE_NORMAL
  222. #ifdef USE_TANGENT
  223. vec4 vertex_tangent = oct_to_tang(out_tangent);
  224. out_tangent = tang_to_oct(vec4(normalize((vec4(vertex_tangent.xyz, 0.0) * m).xyz), vertex_tangent.w));
  225. #endif // USE_TANGENT
  226. #endif // USE_SKELETON
  227. #endif // MODE_2D
  228. }
  229. /* clang-format off */
  230. #[fragment]
  231. void main() {
  232. }
  233. /* clang-format on */