| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | #[compute] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #version 450 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-13 17:01:43 -03:00
										 |  |  | #VERSION_DEFINES | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 0, binding = 1, std430) buffer restrict writeonly DstVertexData { | 
					
						
							|  |  |  | 	uint data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | dst_vertices; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 0, binding = 2, std430) buffer restrict readonly BlendShapeWeights { | 
					
						
							|  |  |  | 	float data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | blend_shape_weights; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 1, binding = 0, std430) buffer restrict readonly SrcVertexData { | 
					
						
							|  |  |  | 	uint data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | src_vertices; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 1, binding = 1, std430) buffer restrict readonly BoneWeightData { | 
					
						
							|  |  |  | 	uint data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | src_bone_weights; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 1, binding = 2, std430) buffer restrict readonly BlendShapeData { | 
					
						
							|  |  |  | 	uint data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | src_blend_shapes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | layout(set = 2, binding = 0, std430) buffer restrict readonly SkeletonData { | 
					
						
							|  |  |  | 	vec4 data[]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | bone_transforms; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-11 18:40:24 +01:00
										 |  |  | layout(push_constant, std430) uniform Params { | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	bool has_normal; | 
					
						
							|  |  |  | 	bool has_tangent; | 
					
						
							|  |  |  | 	bool has_skeleton; | 
					
						
							|  |  |  | 	bool has_blend_shape; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint vertex_count; | 
					
						
							|  |  |  | 	uint vertex_stride; | 
					
						
							|  |  |  | 	uint skin_stride; | 
					
						
							|  |  |  | 	uint skin_weight_offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint blend_shape_count; | 
					
						
							|  |  |  | 	bool normalized_blend_shapes; | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 	uint normal_tangent_stride; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	uint pad1; | 
					
						
							| 
									
										
										
										
											2023-01-27 14:55:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	vec2 skeleton_transform_x; | 
					
						
							|  |  |  | 	vec2 skeleton_transform_y; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec2 skeleton_transform_offset; | 
					
						
							|  |  |  | 	vec2 inverse_transform_x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vec2 inverse_transform_y; | 
					
						
							|  |  |  | 	vec2 inverse_transform_offset; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | } | 
					
						
							|  |  |  | params; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 20:59:28 -07:00
										 |  |  | vec2 uint_to_vec2(uint base) { | 
					
						
							|  |  |  | 	uvec2 decode = (uvec2(base) >> uvec2(0, 16)) & uvec2(0xFFFF, 0xFFFF); | 
					
						
							|  |  |  | 	return vec2(decode) / vec2(65535.0, 65535.0) * 2.0 - 1.0; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-20 20:59:28 -07:00
										 |  |  | vec3 oct_to_vec3(vec2 oct) { | 
					
						
							|  |  |  | 	vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y)); | 
					
						
							|  |  |  | 	float t = max(-v.z, 0.0); | 
					
						
							|  |  |  | 	v.xy += t * -sign(v.xy); | 
					
						
							| 
									
										
										
										
											2022-11-18 16:24:56 +05:30
										 |  |  | 	return normalize(v); | 
					
						
							| 
									
										
										
										
											2022-08-20 20:59:28 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec3 decode_uint_oct_to_norm(uint base) { | 
					
						
							|  |  |  | 	return oct_to_vec3(uint_to_vec2(base)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec4 decode_uint_oct_to_tang(uint base) { | 
					
						
							|  |  |  | 	vec2 oct_sign_encoded = uint_to_vec2(base); | 
					
						
							|  |  |  | 	// Binormal sign encoded in y component | 
					
						
							|  |  |  | 	vec2 oct = vec2(oct_sign_encoded.x, abs(oct_sign_encoded.y) * 2.0 - 1.0); | 
					
						
							|  |  |  | 	return vec4(oct_to_vec3(oct), sign(oct_sign_encoded.y)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec2 signNotZero(vec2 v) { | 
					
						
							|  |  |  | 	return mix(vec2(-1.0), vec2(1.0), greaterThanEqual(v.xy, vec2(0.0))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint vec2_to_uint(vec2 base) { | 
					
						
							|  |  |  | 	uvec2 enc = uvec2(clamp(ivec2(base * vec2(65535, 65535)), ivec2(0), ivec2(0xFFFF, 0xFFFF))) << uvec2(0, 16); | 
					
						
							|  |  |  | 	return enc.x | enc.y; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | vec2 vec3_to_oct(vec3 e) { | 
					
						
							|  |  |  | 	e /= abs(e.x) + abs(e.y) + abs(e.z); | 
					
						
							|  |  |  | 	vec2 oct = e.z >= 0.0f ? e.xy : (vec2(1.0f) - abs(e.yx)) * signNotZero(e.xy); | 
					
						
							|  |  |  | 	return oct * 0.5f + 0.5f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint encode_norm_to_uint_oct(vec3 base) { | 
					
						
							|  |  |  | 	return vec2_to_uint(vec3_to_oct(base)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint encode_tang_to_uint_oct(vec4 base) { | 
					
						
							|  |  |  | 	vec2 oct = vec3_to_oct(base.xyz); | 
					
						
							|  |  |  | 	// Encode binormal sign in y component | 
					
						
							|  |  |  | 	oct.y = oct.y * 0.5f + 0.5f; | 
					
						
							|  |  |  | 	oct.y = base.w >= 0.0f ? oct.y : 1 - oct.y; | 
					
						
							|  |  |  | 	return vec2_to_uint(oct); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void main() { | 
					
						
							|  |  |  | 	uint index = gl_GlobalInvocationID.x; | 
					
						
							|  |  |  | 	if (index >= params.vertex_count) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint src_offset = index * params.vertex_stride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef MODE_2D | 
					
						
							|  |  |  | 	vec2 vertex = uintBitsToFloat(uvec2(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1])); | 
					
						
							| 
									
										
										
										
											2021-05-10 13:12:44 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_blend_shape) { | 
					
						
							|  |  |  | 		float blend_total = 0.0; | 
					
						
							|  |  |  | 		vec2 blend_vertex = vec2(0.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (uint i = 0; i < params.blend_shape_count; i++) { | 
					
						
							|  |  |  | 			float w = blend_shape_weights.data[i]; | 
					
						
							|  |  |  | 			if (abs(w) > 0.0001) { | 
					
						
							|  |  |  | 				uint base_offset = (params.vertex_count * i + index) * params.vertex_stride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				blend_vertex += uintBitsToFloat(uvec2(src_blend_shapes.data[base_offset + 0], src_blend_shapes.data[base_offset + 1])) * w; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				base_offset += 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				blend_total += w; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (params.normalized_blend_shapes) { | 
					
						
							|  |  |  | 			vertex = (1.0 - blend_total) * vertex; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vertex += blend_vertex; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_skeleton) { | 
					
						
							|  |  |  | 		uint skin_offset = params.skin_stride * index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							| 
									
										
										
										
											2022-11-18 16:12:48 -08:00
										 |  |  | 		uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 2; //pre-add xform offset | 
					
						
							|  |  |  | 		uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 2; | 
					
						
							| 
									
										
										
										
											2021-05-10 13:12:44 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		skin_offset += params.skin_weight_offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vec2 weights_01 = unpackUnorm2x16(weights.x); | 
					
						
							|  |  |  | 		vec2 weights_23 = unpackUnorm2x16(weights.y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 14:55:22 -08:00
										 |  |  | 		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)); | 
					
						
							|  |  |  | 		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)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m = skeleton_matrix * transpose(m) * inverse_matrix; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vertex = (m * vec4(vertex, 0.0, 1.0)).xy; | 
					
						
							| 
									
										
										
										
											2021-05-10 13:12:44 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-11-18 16:12:48 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uint dst_offset = index * params.vertex_stride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uvec2 uvertex = floatBitsToUint(vertex); | 
					
						
							|  |  |  | 	dst_vertices.data[dst_offset + 0] = uvertex.x; | 
					
						
							|  |  |  | 	dst_vertices.data[dst_offset + 1] = uvertex.y; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | #else | 
					
						
							|  |  |  | 	vec3 vertex; | 
					
						
							|  |  |  | 	vec3 normal; | 
					
						
							|  |  |  | 	vec4 tangent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vertex = uintBitsToFloat(uvec3(src_vertices.data[src_offset + 0], src_vertices.data[src_offset + 1], src_vertices.data[src_offset + 2])); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 	uint src_normal = params.vertex_count * params.vertex_stride + index * params.normal_tangent_stride; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_normal) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 		normal = decode_uint_oct_to_norm(src_vertices.data[src_normal]); | 
					
						
							|  |  |  | 		src_normal++; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_tangent) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 		tangent = decode_uint_oct_to_tang(src_vertices.data[src_normal]); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_blend_shape) { | 
					
						
							|  |  |  | 		float blend_total = 0.0; | 
					
						
							|  |  |  | 		vec3 blend_vertex = vec3(0.0); | 
					
						
							|  |  |  | 		vec3 blend_normal = vec3(0.0); | 
					
						
							|  |  |  | 		vec3 blend_tangent = vec3(0.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (uint i = 0; i < params.blend_shape_count; i++) { | 
					
						
							|  |  |  | 			float w = blend_shape_weights.data[i]; | 
					
						
							| 
									
										
										
										
											2021-02-17 03:34:48 +00:00
										 |  |  | 			if (abs(w) > 0.0001) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 				uint base_offset = params.vertex_count * i * (params.vertex_stride + params.normal_tangent_stride) + index * params.vertex_stride; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 				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; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (params.has_normal) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 					blend_normal += decode_uint_oct_to_norm(src_blend_shapes.data[base_normal]) * w; | 
					
						
							|  |  |  | 					base_normal++; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (params.has_tangent) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 					blend_tangent += decode_uint_oct_to_tang(src_blend_shapes.data[base_normal]).rgb * w; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				blend_total += w; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (params.normalized_blend_shapes) { | 
					
						
							|  |  |  | 			vertex = (1.0 - blend_total) * vertex; | 
					
						
							|  |  |  | 			normal = (1.0 - blend_total) * normal; | 
					
						
							|  |  |  | 			tangent.rgb = (1.0 - blend_total) * tangent.rgb; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vertex += blend_vertex; | 
					
						
							| 
									
										
										
										
											2022-05-20 07:17:22 -04:00
										 |  |  | 		normal = normalize(normal + blend_normal); | 
					
						
							|  |  |  | 		tangent.rgb = normalize(tangent.rgb + blend_tangent); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_skeleton) { | 
					
						
							|  |  |  | 		uint skin_offset = params.skin_stride * index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							|  |  |  | 		uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset | 
					
						
							|  |  |  | 		uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		skin_offset += params.skin_weight_offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		uvec2 weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		vec2 weights_01 = unpackUnorm2x16(weights.x); | 
					
						
							|  |  |  | 		vec2 weights_23 = unpackUnorm2x16(weights.y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 		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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (params.skin_weight_offset == 4) { | 
					
						
							|  |  |  | 			//using 8 bones/weights | 
					
						
							|  |  |  | 			skin_offset = params.skin_stride * index + 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							|  |  |  | 			bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset | 
					
						
							|  |  |  | 			bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			skin_offset += params.skin_weight_offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			weights = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			weights_01 = unpackUnorm2x16(weights.x); | 
					
						
							|  |  |  | 			weights_23 = unpackUnorm2x16(weights.y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 			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; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//reverse order because its transposed | 
					
						
							|  |  |  | 		vertex = (vec4(vertex, 1.0) * m).xyz; | 
					
						
							|  |  |  | 		normal = normalize((vec4(normal, 0.0) * m).xyz); | 
					
						
							|  |  |  | 		tangent.xyz = normalize((vec4(tangent.xyz, 0.0) * m).xyz); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uint dst_offset = index * params.vertex_stride; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	uvec3 uvertex = floatBitsToUint(vertex); | 
					
						
							|  |  |  | 	dst_vertices.data[dst_offset + 0] = uvertex.x; | 
					
						
							|  |  |  | 	dst_vertices.data[dst_offset + 1] = uvertex.y; | 
					
						
							|  |  |  | 	dst_vertices.data[dst_offset + 2] = uvertex.z; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 	uint dst_normal = params.vertex_count * params.vertex_stride + index * params.normal_tangent_stride; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_normal) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 		dst_vertices.data[dst_normal] = encode_norm_to_uint_oct(normal); | 
					
						
							|  |  |  | 		dst_normal++; | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (params.has_tangent) { | 
					
						
							| 
									
										
										
										
											2023-08-29 21:04:32 +02:00
										 |  |  | 		dst_vertices.data[dst_normal] = encode_tang_to_uint_oct(tangent); | 
					
						
							| 
									
										
										
										
											2020-12-16 11:07:08 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | } |