frustum cull meshsprites

instancing
cosmonaut 2020-12-06 19:27:46 -08:00
parent 46f2cad81a
commit fc09082f1b
2 changed files with 41 additions and 6 deletions

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
@ -16,13 +17,14 @@ namespace Kav
2 2
}; };
public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; }
public Texture2D Texture { get; } public Texture2D Texture { get; }
public Texture2D Normal { get; } public Texture2D Normal { get; }
public SpriteBillboardConstraint BillboardConstraint { get; } public SpriteBillboardConstraint BillboardConstraint { get; }
public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; }
public BoundingBox BoundingBox { get; }
public MeshSprite( public MeshSprite(
GraphicsDevice graphicsDevice, GraphicsDevice graphicsDevice,
Texture2D texture, Texture2D texture,
@ -40,13 +42,17 @@ namespace Kav
); );
IndexBuffer.SetData(Indices); IndexBuffer.SetData(Indices);
var vertexArray = GenerateVertexArray(Texture);
VertexBuffer = new VertexBuffer( VertexBuffer = new VertexBuffer(
graphicsDevice, graphicsDevice,
typeof(VertexPositionNormalTexture), typeof(VertexPositionNormalTexture),
4, 4,
BufferUsage.WriteOnly BufferUsage.WriteOnly
); );
VertexBuffer.SetData(GenerateVertexArray(Texture)); VertexBuffer.SetData(vertexArray);
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
} }
public MeshSprite( public MeshSprite(
@ -67,13 +73,17 @@ namespace Kav
); );
IndexBuffer.SetData(Indices); IndexBuffer.SetData(Indices);
var vertexArray = GenerateVertexArray(Texture);
VertexBuffer = new VertexBuffer( VertexBuffer = new VertexBuffer(
graphicsDevice, graphicsDevice,
typeof(VertexPositionNormalTexture), typeof(VertexPositionNormalTexture),
4, 4,
BufferUsage.WriteOnly BufferUsage.WriteOnly
); );
VertexBuffer.SetData(GenerateVertexArray(Texture)); VertexBuffer.SetData(vertexArray);
BoundingBox = BoundingBox.CreateFromPoints(Positions(vertexArray));
} }
private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture) private static VertexPositionNormalTexture[] GenerateVertexArray(Texture2D texture)
@ -98,5 +108,13 @@ namespace Kav
return result; return result;
} }
private static IEnumerable<Vector3> Positions(IEnumerable<VertexPositionNormalTexture> vertices)
{
foreach (var vertex in vertices)
{
yield return vertex.Position;
}
}
} }
} }

View File

@ -297,7 +297,9 @@ namespace Kav
i += 1; i += 1;
} }
foreach (var (sprite, transform) in meshSpriteTransforms) var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
foreach (var (sprite, transform) in FrustumCull(boundingFrustum, meshSpriteTransforms))
{ {
DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null; DiffuseLitSpriteEffect.NormalMapEnabled = sprite.Normal != null;
@ -849,6 +851,21 @@ namespace Kav
} }
} }
private static IEnumerable<(MeshSprite, Matrix)> FrustumCull(
BoundingFrustum boundingFrustum,
IEnumerable<(MeshSprite, Matrix)> meshSpriteTransforms
) {
foreach (var (meshSprite, transform) in meshSpriteTransforms)
{
var boundingBox = TransformedBoundingBox(meshSprite.BoundingBox, transform);
var containment = boundingFrustum.Contains(boundingBox);
if (containment != ContainmentType.Disjoint)
{
yield return (meshSprite, 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;