diff --git a/Geometry/MeshPart.cs b/Geometry/MeshPart.cs index f2eac05..c8d033b 100644 --- a/Geometry/MeshPart.cs +++ b/Geometry/MeshPart.cs @@ -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; } diff --git a/Renderer.cs b/Renderer.cs index 45afee8..1fe0b9c 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -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 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 FrustumCull( + BoundingFrustum boundingFrustum, + T cullable, + IEnumerable 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;