cullable instance calls

instancing
cosmonaut 2020-12-07 14:58:03 -08:00
parent 283b078641
commit e2fdbff7d1
2 changed files with 28 additions and 9 deletions

View File

@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public class MeshPart : IIndexDrawable, IGBufferDrawable
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable
{
public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; }

View File

@ -8,7 +8,7 @@ namespace Kav
{
public class Renderer
{
private const int MAX_INSTANCE_VERTEX_COUNT = 1000;
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
private const int MAX_SHADOW_CASCADES = 4;
private int ShadowMapSize { get; }
@ -314,9 +314,10 @@ namespace Kav
RenderTargetBinding[] gBuffer,
PerspectiveCamera camera,
T drawable,
int numInstances,
IEnumerable<Matrix> transforms
) where T : IIndexDrawable, IGBufferDrawable {
) where T : ICullable, IIndexDrawable, IGBufferDrawable {
int numInstances = 0;
GraphicsDevice.SetRenderTargets(gBuffer);
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.Opaque;
@ -334,12 +335,13 @@ namespace Kav
Deferred_GBufferEffect.View = camera.View;
Deferred_GBufferEffect.Projection = camera.Projection;
int i = 0;
foreach (var transform in transforms)
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
foreach (var transform in FrustumCull(boundingFrustum, drawable, transforms))
{
if (i >= numInstances) { break; }
GBufferInstanceVertices[i].World = transform;
i += 1;
GBufferInstanceVertices[numInstances].World = transform;
numInstances += 1;
}
GBufferInstanceVertexBuffer.SetData(
@ -824,6 +826,23 @@ namespace Kav
}
}
private static IEnumerable<Matrix> FrustumCull<T>(
BoundingFrustum boundingFrustum,
T cullable,
IEnumerable<Matrix> transforms
) where T : ICullable
{
foreach (var transform in transforms)
{
var boundingBox = TransformedBoundingBox(cullable.BoundingBox, transform);
var containment = boundingFrustum.Contains(boundingBox);
if (containment != ContainmentType.Disjoint)
{
yield return transform;
}
}
}
private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix)
{
var center = (boundingBox.Min + boundingBox.Max) / 2f;