forked from stride3d/stride
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Rendering] WIP: Started rework to move instancing from ModelComponen…
…t to it's own render feature
- Loading branch information
Showing
11 changed files
with
279 additions
and
59 deletions.
There are no files selected for viewing
91 changes: 91 additions & 0 deletions
91
sources/engine/Stride.Engine/Engine/InstancingComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Stride.Core; | ||
using Stride.Core.Mathematics; | ||
using Stride.Engine.Design; | ||
using Stride.Engine.Processors; | ||
|
||
namespace Stride.Engine | ||
{ | ||
[DefaultEntityComponentProcessor(typeof(InstancingProcessor))] | ||
public class InstancingComponent : ActivableEntityComponent | ||
{ | ||
/// <summary> | ||
/// The instance count | ||
/// </summary> | ||
public int InstanceCount; | ||
|
||
/// <summary> | ||
/// The instance transformation matrices. | ||
/// </summary> | ||
[DataMemberIgnore] | ||
public Matrix[] WorldMatrices = new Matrix[0]; | ||
|
||
/// <summary> | ||
/// The inverse instance transformation matrices, updated automatically by the <see cref="InstancingProcessor"/>. | ||
/// </summary> | ||
[DataMemberIgnore] | ||
public Matrix[] WorldInverseMatrices = new Matrix[0]; | ||
|
||
/// <summary> | ||
/// The bounding box of the world matrices, updated automatically by the <see cref="InstancingProcessor"/>. | ||
/// </summary> | ||
public BoundingBox BoundingBox = BoundingBox.Empty; | ||
|
||
bool matricesUpdated; | ||
|
||
/// <summary> | ||
/// Updates the world matrices. | ||
/// </summary> | ||
/// <param name="matrices">The matrices.</param> | ||
/// <param name="instanceCount">The instance count. When set to -1 the lenght if the matrices array is used</param> | ||
public void UpdateWorldMatrices(Matrix[] matrices, int instanceCount = -1) | ||
{ | ||
WorldMatrices = matrices; | ||
|
||
if (WorldMatrices != null) | ||
{ | ||
InstanceCount = instanceCount < 0 ? WorldMatrices.Length : Math.Min(WorldMatrices.Length, instanceCount); | ||
} | ||
else | ||
{ | ||
InstanceCount = 0; | ||
} | ||
|
||
matricesUpdated = true; | ||
} | ||
|
||
// Should this be here or in processor or render feature? | ||
public void Process() | ||
{ | ||
if (matricesUpdated) | ||
{ | ||
if (WorldMatrices != null) | ||
{ | ||
// Make sure inverse matrices are big enough | ||
if (WorldInverseMatrices.Length < InstanceCount) | ||
{ | ||
WorldInverseMatrices = new Matrix[InstanceCount]; | ||
} | ||
|
||
// Invert matrices and update bounding box | ||
var bb = BoundingBox.Empty; | ||
for (int i = 0; i < InstanceCount; i++) | ||
{ | ||
Matrix.Invert(ref WorldMatrices[i], out WorldInverseMatrices[i]); | ||
var pos = WorldMatrices[i].TranslationVector; | ||
BoundingBox.Merge(ref bb, ref pos, out bb); | ||
} | ||
BoundingBox = bb; | ||
} | ||
else | ||
{ | ||
BoundingBox = BoundingBox.Empty; | ||
} | ||
} | ||
|
||
matricesUpdated = false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
sources/engine/Stride.Engine/Engine/Processors/InstancingProcessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using Stride.Core.Annotations; | ||
using Stride.Core.Threading; | ||
using Stride.Games; | ||
using Stride.Rendering; | ||
|
||
namespace Stride.Engine.Processors | ||
{ | ||
public class InstancingProcessor : EntityProcessor<InstancingComponent, InstancingProcessor.InstancingData> | ||
{ | ||
public class InstancingData | ||
{ | ||
public ModelComponent ModelComponent; | ||
} | ||
|
||
public InstancingProcessor() | ||
: base (typeof(ModelComponent)) // Requires a ModelComponent | ||
{ | ||
|
||
} | ||
|
||
public override void Draw(RenderContext context) | ||
{ | ||
Dispatcher.ForEach(ComponentDatas, entity => | ||
{ | ||
var instancingComponent = entity.Key; | ||
var instancingData = entity.Value; | ||
|
||
UpdateInstancingData(instancingComponent, instancingData); | ||
}); | ||
} | ||
|
||
private void UpdateInstancingData(InstancingComponent instancingComponent, InstancingData instancingData) | ||
{ | ||
if (instancingComponent.Enabled && instancingComponent.InstanceCount > 0) | ||
{ | ||
instancingComponent.Process(); | ||
} | ||
} | ||
|
||
protected override void OnEntityComponentAdding(Entity entity, [NotNull] InstancingComponent component, [NotNull] InstancingData data) | ||
{ | ||
base.OnEntityComponentAdding(entity, component, data); | ||
} | ||
|
||
// Instancing data per InstancingComponent | ||
protected override InstancingData GenerateComponentData([NotNull] Entity entity, [NotNull] InstancingComponent component) | ||
{ | ||
return new InstancingData(); | ||
} | ||
|
||
protected override bool IsAssociatedDataValid([NotNull] Entity entity, [NotNull] InstancingComponent component, [NotNull] InstancingData associatedData) | ||
{ | ||
return true; | ||
} | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
sources/engine/Stride.Engine/Rendering/InstancingRenderFeature.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Stride.Core.Mathematics; | ||
using Stride.Graphics; | ||
using Stride.Rendering; | ||
|
||
namespace Stride.Engine.Rendering | ||
{ | ||
public struct InstancingData | ||
{ | ||
public Matrix[] WorldMatrices; | ||
public Matrix[] WorldInverseMatrices; | ||
|
||
// GPU buffers, managed by the render feature | ||
public Buffer<Matrix> InstanceWorldBuffer; | ||
public Buffer<Matrix> InstanceWorldInverseBuffer; | ||
} | ||
|
||
public class InstancingRenderFeature : SubRenderFeature | ||
{ | ||
private StaticObjectPropertyKey<InstancingData> renderObjectInstancingDataInfoKey; | ||
|
||
private LogicalGroupReference instancingResourceGroupKey; | ||
|
||
/// <inheritdoc/> | ||
protected override void InitializeCore() | ||
{ | ||
renderObjectInstancingDataInfoKey = RootRenderFeature.RenderData.CreateStaticObjectKey<InstancingData>(); | ||
instancingResourceGroupKey = ((RootEffectRenderFeature)RootRenderFeature).CreateDrawLogicalGroup("Instancing"); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void Extract() | ||
{ | ||
var renderObjectInstancingData = RootRenderFeature.RenderData.GetData(renderObjectInstancingDataInfoKey); | ||
|
||
foreach (var objectNodeReference in RootRenderFeature.ObjectNodeReferences) | ||
{ | ||
var objectNode = RootRenderFeature.GetObjectNode(objectNodeReference); | ||
var renderMesh = objectNode.RenderObject as RenderMesh; | ||
if (renderMesh == null) | ||
continue; | ||
|
||
var modelComponent = renderMesh.Source as ModelComponent; | ||
if (modelComponent == null) | ||
continue; | ||
|
||
var instancingComponent = modelComponent.Entity.Get<InstancingComponent>(); | ||
if (instancingComponent == null) | ||
continue; | ||
|
||
var data = renderObjectInstancingData[renderMesh.StaticObjectNode]; | ||
data.WorldMatrices = instancingComponent.WorldMatrices; | ||
data.WorldInverseMatrices = instancingComponent.WorldInverseMatrices; | ||
renderMesh.ActiveMeshDraw.InstanceCount = instancingComponent.InstanceCount; | ||
|
||
renderMesh.BoundingBox.Center += instancingComponent.BoundingBox.Center; | ||
renderMesh.BoundingBox.Extent += instancingComponent.BoundingBox.Extent; | ||
} | ||
} | ||
|
||
/// <inheritdoc/> | ||
public unsafe override void Prepare(RenderDrawContext context) | ||
{ | ||
var renderObjectInstancingData = RootRenderFeature.RenderData.GetData(renderObjectInstancingDataInfoKey); | ||
|
||
foreach (var renderNode in ((RootEffectRenderFeature)RootRenderFeature).RenderNodes) | ||
{ | ||
var perDrawLayout = renderNode.RenderEffect.Reflection?.PerDrawLayout; | ||
if (perDrawLayout == null) | ||
continue; | ||
|
||
if (instancingResourceGroupKey.Index < 0) | ||
continue; | ||
|
||
var group = perDrawLayout.GetLogicalGroup(instancingResourceGroupKey); | ||
if (group.DescriptorEntryStart == -1) | ||
continue; | ||
|
||
var renderMesh = renderNode.RenderObject as RenderMesh; | ||
if (renderMesh == null) | ||
continue; | ||
|
||
var instancingData = renderObjectInstancingData[renderMesh.StaticObjectNode]; | ||
|
||
instancingData.InstanceWorldBuffer.SetData(context.CommandList, instancingData.WorldMatrices); | ||
instancingData.InstanceWorldInverseBuffer.SetData(context.CommandList, instancingData.WorldInverseMatrices); | ||
|
||
renderNode.Resources.DescriptorSet.SetShaderResourceView(group.DescriptorEntryStart, instancingData.InstanceWorldBuffer); | ||
renderNode.Resources.DescriptorSet.SetShaderResourceView(group.DescriptorEntryStart + 1, instancingData.InstanceWorldInverseBuffer); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Stride.Core.Mathematics; | ||
using Stride.Graphics; | ||
|
||
namespace Stride.Rendering | ||
{ | ||
public class Instancing | ||
{ | ||
|
||
|
||
|
||
public void UpdateTransforms(Matrix[] worldMatrices) | ||
{ | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.