diff --git a/packages/flame_3d/assets/shaders/spatial_material.shaderbundle b/packages/flame_3d/assets/shaders/spatial_material.shaderbundle index 648c138382..841e7a8b93 100644 Binary files a/packages/flame_3d/assets/shaders/spatial_material.shaderbundle and b/packages/flame_3d/assets/shaders/spatial_material.shaderbundle differ diff --git a/packages/flame_3d/lib/src/resources/material/spatial_material.dart b/packages/flame_3d/lib/src/resources/material/spatial_material.dart index 1895393535..dddb14c11b 100644 --- a/packages/flame_3d/lib/src/resources/material/spatial_material.dart +++ b/packages/flame_3d/lib/src/resources/material/spatial_material.dart @@ -21,13 +21,10 @@ class SpatialMaterial extends Material { 'view', 'projection', }), - UniformSlot.value('JointMatrices', { - 'joint0', - 'joint1', - 'joint2', - 'joint3', - 'joint4', - }), + UniformSlot.value( + 'JointMatrices', + List.generate(_maxJoints, (idx) => 'joint$idx').toSet(), + ), ], ), fragmentShader: Shader( @@ -81,9 +78,9 @@ class SpatialMaterial extends Material { void _bindJointMatrices(GraphicsDevice device) { final jointTransforms = device.jointsInfo.jointTransforms; - if (jointTransforms.length > 5) { + if (jointTransforms.length > _maxJoints) { throw Exception( - 'At most 5 joints per surface, found ${jointTransforms.length}', + 'At most $_maxJoints joints per surface, found ${jointTransforms.length}', ); } for (final (idx, transform) in jointTransforms.indexed) { @@ -113,4 +110,6 @@ class SpatialMaterial extends Material { static final _library = gpu.ShaderLibrary.fromAsset( 'packages/flame_3d/assets/shaders/spatial_material.shaderbundle', )!; + + static const _maxJoints = 16; } diff --git a/packages/flame_3d/lib/src/resources/shader/uniform_value.dart b/packages/flame_3d/lib/src/resources/shader/uniform_value.dart index a138dfdf7f..6b27f8d004 100644 --- a/packages/flame_3d/lib/src/resources/shader/uniform_value.dart +++ b/packages/flame_3d/lib/src/resources/shader/uniform_value.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:flame_3d/graphics.dart'; import 'package:flame_3d/resources.dart'; +import 'package:ordered_set/comparing.dart'; /// {@template uniform_value} /// Instance of a uniform value. Represented by a [ByteBuffer]. @@ -21,7 +22,9 @@ class UniformValue extends UniformInstance { if (super.resource == null) { var previousIndex = -1; - final data = _storage.entries.fold>([], (p, e) { + final entries = _storage.entries.toList() + ..sort(Comparing.on((c) => c.key)); + final data = entries.fold>([], (p, e) { if (previousIndex + 1 != e.key) { final field = slot.fields.indexed.firstWhere((e) => e.$1 == previousIndex + 1); diff --git a/packages/flame_3d/pubspec.yaml b/packages/flame_3d/pubspec.yaml index 425399a95c..4649e69d32 100644 --- a/packages/flame_3d/pubspec.yaml +++ b/packages/flame_3d/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: flutter_gpu: sdk: flutter meta: ^1.12.0 + ordered_set: ^6.0.1 vector_math: ^2.1.4 dev_dependencies: diff --git a/packages/flame_3d/shaders/spatial_material.vert b/packages/flame_3d/shaders/spatial_material.vert index a602965d94..f7dfc0b496 100644 --- a/packages/flame_3d/shaders/spatial_material.vert +++ b/packages/flame_3d/shaders/spatial_material.vert @@ -24,6 +24,17 @@ uniform JointMatrices { mat4 joint2; mat4 joint3; mat4 joint4; + mat4 joint5; + mat4 joint6; + mat4 joint7; + mat4 joint8; + mat4 joint9; + mat4 joint10; + mat4 joint11; + mat4 joint12; + mat4 joint13; + mat4 joint14; + mat4 joint15; } joints; mat4 jointMat(float jointIndex) { @@ -37,6 +48,28 @@ mat4 jointMat(float jointIndex) { return joints.joint3; } else if (jointIndex == 4.0) { return joints.joint4; + } else if (jointIndex == 5.0) { + return joints.joint5; + } else if (jointIndex == 6.0) { + return joints.joint6; + } else if (jointIndex == 7.0) { + return joints.joint7; + } else if (jointIndex == 8.0) { + return joints.joint8; + } else if (jointIndex == 9.0) { + return joints.joint9; + } else if (jointIndex == 10.0) { + return joints.joint10; + } else if (jointIndex == 11.0) { + return joints.joint11; + } else if (jointIndex == 12.0) { + return joints.joint12; + } else if (jointIndex == 13.0) { + return joints.joint13; + } else if (jointIndex == 14.0) { + return joints.joint14; + } else if (jointIndex == 15.0) { + return joints.joint15; } else { return mat4(0.0); }