Frustum Culling #4
|
@ -1,12 +1,23 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Kav
|
||||
{
|
||||
public class Mesh
|
||||
{
|
||||
public MeshPart[] MeshParts { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public Mesh(MeshPart[] meshParts)
|
||||
{
|
||||
MeshParts = meshParts;
|
||||
|
||||
BoundingBox boundingBox = new BoundingBox();
|
||||
foreach (var meshPart in MeshParts)
|
||||
{
|
||||
boundingBox = BoundingBox.CreateMerged(boundingBox, meshPart.BoundingBox);
|
||||
}
|
||||
|
||||
BoundingBox = boundingBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace Kav
|
|||
public Triangle[] Triangles { get; }
|
||||
public Vector3[] Positions { get; }
|
||||
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
private Texture2D albedoTexture = null;
|
||||
private Texture2D normalTexture = null;
|
||||
private Texture2D metallicRoughnessTexture = null;
|
||||
|
@ -50,6 +52,8 @@ namespace Kav
|
|||
IndexBuffer = indexBuffer;
|
||||
Positions = positions;
|
||||
Triangles = triangles;
|
||||
|
||||
BoundingBox = BoundingBox.CreateFromPoints(Positions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Kav
|
|||
public class Model
|
||||
{
|
||||
public Mesh[] Meshes { get; }
|
||||
public BoundingBox BoundingBox { get; }
|
||||
|
||||
public Color Albedo
|
||||
{
|
||||
|
@ -51,6 +52,14 @@ namespace Kav
|
|||
public Model(Mesh[] meshes)
|
||||
{
|
||||
Meshes = meshes;
|
||||
|
||||
BoundingBox boundingBox = new BoundingBox();
|
||||
foreach (var mesh in Meshes)
|
||||
{
|
||||
boundingBox = BoundingBox.CreateMerged(boundingBox, mesh.BoundingBox);
|
||||
}
|
||||
|
||||
BoundingBox = boundingBox;
|
||||
}
|
||||
|
||||
public void DisableAlbedoMaps()
|
||||
|
|
|
@ -14,7 +14,7 @@ Essential
|
|||
- [x] Cascading shadow maps
|
||||
- [x] Tone map shader
|
||||
- [x] Poisson soft shadowing
|
||||
- [ ] Frustum culling
|
||||
- [x] Frustum culling
|
||||
- [x] Shadow-casting point lights
|
||||
- [ ] Parabolic lights
|
||||
- [x] Skyboxes
|
||||
|
|
52
Renderer.cs
52
Renderer.cs
|
@ -240,7 +240,9 @@ namespace Kav
|
|||
PerspectiveCamera camera,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms
|
||||
) {
|
||||
foreach (var (model, transform) in modelTransforms)
|
||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||
|
||||
foreach (var (model, transform) in FrustumCull(boundingFrustum, modelTransforms))
|
||||
{
|
||||
foreach (var modelMesh in model.Meshes)
|
||||
{
|
||||
|
@ -312,7 +314,9 @@ namespace Kav
|
|||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||
|
||||
foreach (var (model, transform) in modelTransforms)
|
||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||
|
||||
foreach (var (model, transform) in FrustumCull(boundingFrustum, modelTransforms))
|
||||
{
|
||||
foreach (var modelMesh in model.Meshes)
|
||||
{
|
||||
|
@ -581,7 +585,9 @@ namespace Kav
|
|||
effect.LightSpaceMatrixFour = lightSpaceMatrix;
|
||||
}
|
||||
|
||||
foreach (var (model, transform) in modelTransforms)
|
||||
var boundingFrustum = new BoundingFrustum(lightSpaceMatrix);
|
||||
|
||||
foreach (var (model, transform) in FrustumCull(boundingFrustum, modelTransforms))
|
||||
{
|
||||
foreach (var modelMesh in model.Meshes)
|
||||
{
|
||||
|
@ -677,7 +683,9 @@ namespace Kav
|
|||
targetUpDirection
|
||||
);
|
||||
|
||||
foreach (var (model, transform) in modelTransforms)
|
||||
var boundingFrustum = new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection);
|
||||
|
||||
foreach (var (model, transform) in FrustumCull(boundingFrustum, modelTransforms))
|
||||
{
|
||||
foreach (var modelMesh in model.Meshes)
|
||||
{
|
||||
|
@ -706,5 +714,41 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<(Model, Matrix)> FrustumCull(
|
||||
BoundingFrustum boundingFrustum,
|
||||
IEnumerable<(Model, Matrix)> modelTransforms
|
||||
) {
|
||||
foreach (var modelTransform in modelTransforms)
|
||||
{
|
||||
var boundingBox = TransformedBoundingBox(modelTransform.Item1.BoundingBox, modelTransform.Item2);
|
||||
var containment = boundingFrustum.Contains(boundingBox);
|
||||
if (containment != ContainmentType.Disjoint)
|
||||
{
|
||||
yield return modelTransform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static BoundingBox TransformedBoundingBox(BoundingBox boundingBox, Matrix matrix)
|
||||
{
|
||||
var center = (boundingBox.Min + boundingBox.Max) / 2f;
|
||||
var extent = (boundingBox.Max - boundingBox.Min) / 2f;
|
||||
|
||||
var newCenter = Vector3.Transform(center, matrix);
|
||||
var newExtent = Vector3.TransformNormal(extent, AbsoluteMatrix(matrix));
|
||||
|
||||
return new BoundingBox(newCenter - newExtent, newCenter + newExtent);
|
||||
}
|
||||
|
||||
private static Matrix AbsoluteMatrix(Matrix matrix)
|
||||
{
|
||||
return new Matrix(
|
||||
Math.Abs(matrix.M11), Math.Abs(matrix.M12), Math.Abs(matrix.M13), Math.Abs(matrix.M14),
|
||||
Math.Abs(matrix.M21), Math.Abs(matrix.M22), Math.Abs(matrix.M23), Math.Abs(matrix.M24),
|
||||
Math.Abs(matrix.M31), Math.Abs(matrix.M32), Math.Abs(matrix.M33), Math.Abs(matrix.M34),
|
||||
Math.Abs(matrix.M41), Math.Abs(matrix.M42), Math.Abs(matrix.M43), Math.Abs(matrix.M44)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue