@@ -24,12 +24,14 @@ private struct InstanceInfo
2424 private class InstanceData
2525 {
2626 public ExpandableContainer < InstanceInfo > instanceInfos = new ( ) ;
27- public Matrix4x4 [ ] transformMatrices = [ ] ;
2827 }
2928
3029 private readonly Dictionary < int , InstanceData > instanceCache = [ ] ;
3130
32- private readonly Dictionary < int , VertexBuffer > instanceBuffers = [ ] ;
31+ private VertexBuffer instanceBuffer ;
32+ private int instanceOffset ;
33+ private int instanceCount ;
34+ private Matrix4x4 [ ] transformMatrices = [ ] ;
3335
3436 private readonly Lazy < VertexLayout > instanceLayout = new ( ( ) =>
3537 {
@@ -59,27 +61,6 @@ public void Prepare()
5961 }
6062 #endregion
6163
62- private VertexBuffer GetInstanceBuffer ( int count )
63- {
64- if ( instanceBuffers . TryGetValue ( count , out var buffer ) && buffer . Disposed == false )
65- {
66- return buffer ;
67- }
68-
69- buffer = VertexBuffer . Create ( new Matrix4x4 [ count ] , instanceLayout . Value , RenderBufferFlags . GraphicsRead ) ;
70-
71- if ( ( buffer ? . Disposed ?? true ) )
72- {
73- instanceBuffers . Remove ( count ) ;
74-
75- return null ;
76- }
77-
78- instanceBuffers . AddOrSetKey ( count , buffer ) ;
79-
80- return buffer ;
81- }
82-
8364 /// <summary>
8465 /// Renders a mesh
8566 /// </summary>
@@ -258,13 +239,7 @@ void Add(Material material, int submeshIndex)
258239 }
259240 }
260241
261- foreach ( var p in instanceCache )
262- {
263- if ( p . Value . instanceInfos . Length != p . Value . transformMatrices . Length )
264- {
265- Array . Resize ( ref p . Value . transformMatrices , p . Value . instanceInfos . Length ) ;
266- }
267- }
242+ instanceOffset = 0 ;
268243 }
269244
270245 public void Submit ( )
@@ -275,6 +250,50 @@ public void Submit()
275250 enableDepth = true ,
276251 } ;
277252
253+ if ( instanceBuffer ? . Disposed ?? true )
254+ {
255+ instanceBuffer = VertexBuffer . Create ( new Matrix4x4 [ 1 ] , instanceLayout . Value , RenderBufferFlags . GraphicsRead ) ;
256+ }
257+
258+ instanceCount = instanceOffset = 0 ;
259+
260+ foreach ( var ( _, contents ) in instanceCache )
261+ {
262+ if ( contents . instanceInfos . Length <= 1 )
263+ {
264+ continue ;
265+ }
266+
267+ instanceCount += contents . instanceInfos . Length ;
268+ }
269+
270+ if ( instanceCount > 0 )
271+ {
272+ if ( instanceCount > transformMatrices . Length )
273+ {
274+ Array . Resize ( ref transformMatrices , instanceCount ) ;
275+ }
276+
277+ foreach ( var ( _, contents ) in instanceCache )
278+ {
279+ if ( contents . instanceInfos . Length <= 1 )
280+ {
281+ continue ;
282+ }
283+
284+ for ( var i = 0 ; i < contents . instanceInfos . Length ; i ++ )
285+ {
286+ transformMatrices [ instanceOffset ++ ] = contents . instanceInfos . Contents [ i ] . transform . Matrix ;
287+ }
288+ }
289+
290+ instanceOffset = 0 ;
291+
292+ var span = new Span < Matrix4x4 > ( transformMatrices , 0 , instanceCount ) ;
293+
294+ instanceBuffer . Update ( span ) ;
295+ }
296+
278297 foreach ( var ( _, contents ) in instanceCache )
279298 {
280299 if ( contents . instanceInfos . Length == 0 )
@@ -284,6 +303,9 @@ public void Submit()
284303
285304 renderState . ClearStorageBuffers ( ) ;
286305
306+ renderState . instanceCount = 1 ;
307+ renderState . instanceOffset = 0 ;
308+
287309 var renderData = contents . instanceInfos . Contents [ 0 ] ;
288310
289311 var material = renderData . material ;
@@ -324,25 +346,14 @@ public void Submit()
324346
325347 contents . instanceInfos . Contents [ 0 ] . mesh . SetActive ( ref renderState , contents . instanceInfos . Contents [ 0 ] . submeshIndex ) ;
326348
327- for ( var i = 0 ; i < contents . instanceInfos . Length ; i ++ )
328- {
329- contents . transformMatrices [ i ] = contents . instanceInfos . Contents [ i ] . transform . Matrix ;
330- }
331-
332- var buffer = GetInstanceBuffer ( contents . transformMatrices . Length ) ;
333-
334- if ( buffer == null )
349+ if ( instanceBuffer != null )
335350 {
336- continue ;
337- }
338-
339- buffer . Update ( contents . transformMatrices ) ;
351+ renderState . instanceOffset = instanceOffset ;
352+ renderState . instanceCount = contents . instanceInfos . Length ;
340353
341- if ( buffer != null )
342- {
343- renderState . instanceCount = contents . transformMatrices . Length ;
354+ instanceOffset += renderState . instanceCount ;
344355
345- renderState . ApplyStorageBufferIfNeeded ( "StapleInstancingTransforms" , buffer ) ;
356+ renderState . ApplyStorageBufferIfNeeded ( "StapleInstancingTransforms" , instanceBuffer ) ;
346357
347358 RenderSystem . Submit ( renderState , renderData . mesh . SubmeshTriangleCount ( contents . instanceInfos . Contents [ 0 ] . submeshIndex ) ,
348359 contents . instanceInfos . Length ) ;
0 commit comments