testing instancing
parent
8f570e04f0
commit
867d4d7f5d
|
@ -94,7 +94,7 @@
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "./lib64",
|
"LD_LIBRARY_PATH": "./lib64",
|
||||||
"DYLD_LIBRARY_PATH": "./osx",
|
"DYLD_LIBRARY_PATH": "./osx",
|
||||||
"FNA3D_FORCE_DRIVER": "Vulkan"
|
"FNA3D_FORCE_DRIVER": "OpenGL"
|
||||||
},
|
},
|
||||||
"cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48"
|
"cwd": "${workspaceFolder}/KavTest/bin/x64/Debug/net48"
|
||||||
},
|
},
|
||||||
|
|
2
FNA
2
FNA
|
@ -1 +1 @@
|
||||||
Subproject commit 1df9f588a701eefc4b55a0869cd5871be0124307
|
Subproject commit 7357a6f297fee33b7a8d5afddaca30480c591ba5
|
2
Kav
2
Kav
|
@ -1 +1 @@
|
||||||
Subproject commit 8b43e8f45ee6fa35f5c4d4924a62a3fcafe61301
|
Subproject commit bb694d3dbe47dcfcee6bfe3fb315587419ba8c0f
|
|
@ -0,0 +1,6 @@
|
||||||
|
using Encompass;
|
||||||
|
|
||||||
|
namespace KavTest.Components
|
||||||
|
{
|
||||||
|
public struct InstancedCubeComponent : IComponent { }
|
||||||
|
}
|
|
@ -6,10 +6,12 @@ namespace KavTest.Components
|
||||||
public struct ModelComponent : IComponent
|
public struct ModelComponent : IComponent
|
||||||
{
|
{
|
||||||
public Model Model { get; }
|
public Model Model { get; }
|
||||||
|
public bool Instanced { get; }
|
||||||
|
|
||||||
public ModelComponent(Model model)
|
public ModelComponent(Model model, bool instanced)
|
||||||
{
|
{
|
||||||
Model = model;
|
Model = model;
|
||||||
|
Instanced = instanced;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace KavTest.Spawners
|
||||||
var entity = CreateEntity();
|
var entity = CreateEntity();
|
||||||
|
|
||||||
AddComponent(entity, new Transform3DComponent(message.Transform));
|
AddComponent(entity, new Transform3DComponent(message.Transform));
|
||||||
AddComponent(entity, new ModelComponent(RustyBallModel));
|
AddComponent(entity, new ModelComponent(RustyBallModel, true));
|
||||||
AddComponent(entity, new AngularVelocityComponent(message.AngularVelocity));
|
AddComponent(entity, new AngularVelocityComponent(message.AngularVelocity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace KavTest.Spawners
|
||||||
var entity = CreateEntity();
|
var entity = CreateEntity();
|
||||||
|
|
||||||
AddComponent(entity, new Transform3DComponent(message.Transform));
|
AddComponent(entity, new Transform3DComponent(message.Transform));
|
||||||
AddComponent(entity, new ModelComponent(message.Model));
|
AddComponent(entity, new ModelComponent(message.Model, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Kav;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public class InstancedModelContainer
|
||||||
|
{
|
||||||
|
public MeshPart CubeModel { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ namespace KavTest
|
||||||
class KavTestGame : Game
|
class KavTestGame : Game
|
||||||
{
|
{
|
||||||
GraphicsDeviceManager graphics;
|
GraphicsDeviceManager graphics;
|
||||||
|
InstancedModelContainer InstancedModelContainer { get; } = new InstancedModelContainer();
|
||||||
|
|
||||||
WorldBuilder WorldBuilder { get; } = new WorldBuilder();
|
WorldBuilder WorldBuilder { get; } = new WorldBuilder();
|
||||||
World World { get; set; }
|
World World { get; set; }
|
||||||
|
@ -119,6 +120,10 @@ namespace KavTest
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
InstancedModelContainer.CubeModel = cubeModel.Meshes[0].MeshParts[0];
|
||||||
|
InstancedModelContainer.CubeModel.Albedo = Color.Blue.ToVector3();
|
||||||
|
InstancedModelContainer.CubeModel.DisableAlbedoMap = true;
|
||||||
|
|
||||||
Texture2D.TextureDataFromStreamEXT(
|
Texture2D.TextureDataFromStreamEXT(
|
||||||
File.OpenRead("Content/Skybox/front.jpg"),
|
File.OpenRead("Content/Skybox/front.jpg"),
|
||||||
out var skyboxSize,
|
out var skyboxSize,
|
||||||
|
@ -187,7 +192,7 @@ namespace KavTest
|
||||||
WorldBuilder.AddEngine(new StaticModelSpawner());
|
WorldBuilder.AddEngine(new StaticModelSpawner());
|
||||||
WorldBuilder.AddEngine(new DirectionalLightSpawner());
|
WorldBuilder.AddEngine(new DirectionalLightSpawner());
|
||||||
WorldBuilder.AddEngine(new MeshSpriteSpawner());
|
WorldBuilder.AddEngine(new MeshSpriteSpawner());
|
||||||
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
|
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice, InstancedModelContainer), 0);
|
||||||
|
|
||||||
// WorldBuilder.SendMessage(new RustyBallSpawnMessage(
|
// WorldBuilder.SendMessage(new RustyBallSpawnMessage(
|
||||||
// new Transform3D(new Vector3(0, 0, 0)),
|
// new Transform3D(new Vector3(0, 0, 0)),
|
||||||
|
@ -209,46 +214,51 @@ namespace KavTest
|
||||||
// rustyBallModel
|
// rustyBallModel
|
||||||
// ));
|
// ));
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)),
|
// new Transform3D(new Vector3(0, -3, 0), Quaternion.Identity, new Vector3(10f, 1f, 10f)),
|
||||||
floorModel
|
// floorModel
|
||||||
));
|
// ));
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(
|
// new Transform3D(
|
||||||
new Vector3(0, 1, 0),
|
// new Vector3(0, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(
|
// Quaternion.CreateFromAxisAngle(
|
||||||
Vector3.Right,
|
// Vector3.Right,
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
// -Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
),
|
// ),
|
||||||
new Vector3(1f, 1f, 1f)
|
// new Vector3(1f, 1f, 1f)
|
||||||
),
|
// ),
|
||||||
redCylinderModel
|
// redCylinderModel
|
||||||
));
|
// ));
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
// WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
||||||
new Transform3D(
|
// new Transform3D(
|
||||||
new Vector3(-3, 1, 0),
|
// new Vector3(-3, 1, 0),
|
||||||
Quaternion.CreateFromAxisAngle(
|
// Quaternion.CreateFromAxisAngle(
|
||||||
Vector3.Right,
|
// Vector3.Right,
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
// -Microsoft.Xna.Framework.MathHelper.PiOver2
|
||||||
),
|
// ),
|
||||||
new Vector3(1f, 1f, 1f)
|
// new Vector3(1f, 1f, 1f)
|
||||||
),
|
// ),
|
||||||
blueTorusModel
|
// blueTorusModel
|
||||||
));
|
// ));
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new StaticModelSpawnMessage(
|
for (int i = -10; i < 10; i++)
|
||||||
new Transform3D(
|
{
|
||||||
new Vector3(3, 1, 0),
|
for (int j = -10; j < 10; j++)
|
||||||
Quaternion.CreateFromAxisAngle(
|
{
|
||||||
Vector3.Right,
|
for (int k = -10; k < 10; k++)
|
||||||
-Microsoft.Xna.Framework.MathHelper.PiOver2
|
{
|
||||||
),
|
var entity = WorldBuilder.CreateEntity();
|
||||||
new Vector3(1f, 1f, 1f)
|
WorldBuilder.SetComponent(entity, new Transform3DComponent(
|
||||||
),
|
new Transform3D(
|
||||||
cubeModel
|
new Vector3(i * 3, j * 3, k * 3)
|
||||||
));
|
)
|
||||||
|
));
|
||||||
|
WorldBuilder.SetComponent(entity, new InstancedCubeComponent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WorldBuilder.SendMessage(new MeshSpriteSpawnMessage(
|
WorldBuilder.SendMessage(new MeshSpriteSpawnMessage(
|
||||||
new Transform3D(new Vector3(3, 0, 11), Quaternion.CreateFromAxisAngle(Vector3.Up, (float)System.Math.PI), Vector3.One),
|
new Transform3D(new Vector3(3, 0, 11), Quaternion.CreateFromAxisAngle(Vector3.Up, (float)System.Math.PI), Vector3.One),
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace KavTest.Renderers
|
||||||
{
|
{
|
||||||
private GraphicsDevice GraphicsDevice { get; }
|
private GraphicsDevice GraphicsDevice { get; }
|
||||||
private SpriteBatch SpriteBatch { get; }
|
private SpriteBatch SpriteBatch { get; }
|
||||||
|
private InstancedModelContainer InstancedModelContainer { get; }
|
||||||
|
|
||||||
private Kav.Renderer Renderer { get; }
|
private Kav.Renderer Renderer { get; }
|
||||||
|
|
||||||
|
@ -26,6 +27,24 @@ namespace KavTest.Renderers
|
||||||
private RenderTarget2D DeferredTarget { get; }
|
private RenderTarget2D DeferredTarget { get; }
|
||||||
private RenderTarget2D BillboardTarget { get; }
|
private RenderTarget2D BillboardTarget { get; }
|
||||||
|
|
||||||
|
private readonly Dictionary<Kav.MeshPart, List<Matrix>> InstanceMap = new Dictionary<MeshPart, List<Matrix>>();
|
||||||
|
|
||||||
|
private IEnumerable<Matrix> CubeTransforms
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var entity in ReadEntitiesAsEnumerable<InstancedCubeComponent>())
|
||||||
|
{
|
||||||
|
if (HasComponent<Transform3DComponent>(entity))
|
||||||
|
{
|
||||||
|
var transformComponent = GetComponent<Transform3DComponent>(entity);
|
||||||
|
|
||||||
|
yield return transformComponent.Transform.TransformMatrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<(Kav.Model, Matrix)> ModelTransforms
|
private IEnumerable<(Kav.Model, Matrix)> ModelTransforms
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -117,9 +136,12 @@ namespace KavTest.Renderers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SceneRenderer(GraphicsDevice graphicsDevice)
|
public SceneRenderer(
|
||||||
{
|
GraphicsDevice graphicsDevice,
|
||||||
|
InstancedModelContainer instancedModelContainer
|
||||||
|
) {
|
||||||
GraphicsDevice = graphicsDevice;
|
GraphicsDevice = graphicsDevice;
|
||||||
|
InstancedModelContainer = instancedModelContainer;
|
||||||
|
|
||||||
var renderDimensionsX = GraphicsDevice.PresentationParameters.BackBufferWidth;
|
var renderDimensionsX = GraphicsDevice.PresentationParameters.BackBufferWidth;
|
||||||
var renderDimensionsY = GraphicsDevice.PresentationParameters.BackBufferHeight;
|
var renderDimensionsY = GraphicsDevice.PresentationParameters.BackBufferHeight;
|
||||||
|
@ -220,11 +242,19 @@ namespace KavTest.Renderers
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTargets(GBuffer);
|
GraphicsDevice.SetRenderTargets(GBuffer);
|
||||||
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
|
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
|
||||||
Renderer.GBufferRender(
|
// Renderer.GBufferRender(
|
||||||
|
// GBuffer,
|
||||||
|
// camera,
|
||||||
|
// ModelTransforms
|
||||||
|
// );
|
||||||
|
|
||||||
|
Renderer.InstancedGBufferRender(
|
||||||
GBuffer,
|
GBuffer,
|
||||||
camera,
|
camera,
|
||||||
ModelTransforms
|
InstancedModelContainer.CubeModel,
|
||||||
|
CubeTransforms
|
||||||
);
|
);
|
||||||
|
|
||||||
GraphicsDevice.SetRenderTarget(DeferredTarget);
|
GraphicsDevice.SetRenderTarget(DeferredTarget);
|
||||||
|
@ -299,5 +329,39 @@ namespace KavTest.Renderers
|
||||||
SpriteBatch.End();
|
SpriteBatch.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CollectInstances()
|
||||||
|
{
|
||||||
|
foreach (var list in InstanceMap.Values)
|
||||||
|
{
|
||||||
|
list.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var modelEntity in ReadEntities<ModelComponent>())
|
||||||
|
{
|
||||||
|
if (HasComponent<Transform3DComponent>(modelEntity))
|
||||||
|
{
|
||||||
|
var modelComponent = GetComponent<ModelComponent>(modelEntity);
|
||||||
|
if (modelComponent.Instanced)
|
||||||
|
{
|
||||||
|
var transformComponent = GetComponent<Transform3DComponent>(modelEntity);
|
||||||
|
|
||||||
|
foreach (var mesh in modelComponent.Model.Meshes)
|
||||||
|
{
|
||||||
|
foreach (var meshPart in mesh.MeshParts)
|
||||||
|
{
|
||||||
|
if (!InstanceMap.ContainsKey(meshPart))
|
||||||
|
{
|
||||||
|
InstanceMap.Add(meshPart, new List<Matrix>());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
InstanceMap[meshPart].Add(transformComponent.Transform.TransformMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue