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 namespace Kav
{ {
public class MeshPart : IIndexDrawable, IGBufferDrawable public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable
{ {
public IndexBuffer IndexBuffer { get; } public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; } public VertexBuffer VertexBuffer { get; }

View File

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