Frustum Culling #4
|
@ -1,12 +1,23 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class Mesh
|
public class Mesh
|
||||||
{
|
{
|
||||||
public MeshPart[] MeshParts { get; }
|
public MeshPart[] MeshParts { get; }
|
||||||
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
||||||
public Mesh(MeshPart[] meshParts)
|
public Mesh(MeshPart[] meshParts)
|
||||||
{
|
{
|
||||||
MeshParts = 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 Triangle[] Triangles { get; }
|
||||||
public Vector3[] Positions { get; }
|
public Vector3[] Positions { get; }
|
||||||
|
|
||||||
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
||||||
private Texture2D albedoTexture = null;
|
private Texture2D albedoTexture = null;
|
||||||
private Texture2D normalTexture = null;
|
private Texture2D normalTexture = null;
|
||||||
private Texture2D metallicRoughnessTexture = null;
|
private Texture2D metallicRoughnessTexture = null;
|
||||||
|
@ -50,6 +52,8 @@ namespace Kav
|
||||||
IndexBuffer = indexBuffer;
|
IndexBuffer = indexBuffer;
|
||||||
Positions = positions;
|
Positions = positions;
|
||||||
Triangles = triangles;
|
Triangles = triangles;
|
||||||
|
|
||||||
|
BoundingBox = BoundingBox.CreateFromPoints(Positions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Kav
|
||||||
public class Model
|
public class Model
|
||||||
{
|
{
|
||||||
public Mesh[] Meshes { get; }
|
public Mesh[] Meshes { get; }
|
||||||
|
public BoundingBox BoundingBox { get; }
|
||||||
|
|
||||||
public Color Albedo
|
public Color Albedo
|
||||||
{
|
{
|
||||||
|
@ -51,6 +52,14 @@ namespace Kav
|
||||||
public Model(Mesh[] meshes)
|
public Model(Mesh[] meshes)
|
||||||
{
|
{
|
||||||
Meshes = meshes;
|
Meshes = meshes;
|
||||||
|
|
||||||
|
BoundingBox boundingBox = new BoundingBox();
|
||||||
|
foreach (var mesh in Meshes)
|
||||||
|
{
|
||||||
|
boundingBox = BoundingBox.CreateMerged(boundingBox, mesh.BoundingBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundingBox = boundingBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisableAlbedoMaps()
|
public void DisableAlbedoMaps()
|
||||||
|
|
|
@ -14,7 +14,7 @@ Essential
|
||||||
- [x] Cascading shadow maps
|
- [x] Cascading shadow maps
|
||||||
- [x] Tone map shader
|
- [x] Tone map shader
|
||||||
- [x] Poisson soft shadowing
|
- [x] Poisson soft shadowing
|
||||||
- [ ] Frustum culling
|
- [x] Frustum culling
|
||||||
- [x] Shadow-casting point lights
|
- [x] Shadow-casting point lights
|
||||||
- [ ] Parabolic lights
|
- [ ] Parabolic lights
|
||||||
- [x] Skyboxes
|
- [x] Skyboxes
|
||||||
|
|
52
Renderer.cs
52
Renderer.cs
|
@ -240,7 +240,9 @@ namespace Kav
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(Model, Matrix)> modelTransforms
|
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)
|
foreach (var modelMesh in model.Meshes)
|
||||||
{
|
{
|
||||||
|
@ -312,7 +314,9 @@ namespace Kav
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
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)
|
foreach (var modelMesh in model.Meshes)
|
||||||
{
|
{
|
||||||
|
@ -581,7 +585,9 @@ namespace Kav
|
||||||
effect.LightSpaceMatrixFour = lightSpaceMatrix;
|
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)
|
foreach (var modelMesh in model.Meshes)
|
||||||
{
|
{
|
||||||
|
@ -677,7 +683,9 @@ namespace Kav
|
||||||
targetUpDirection
|
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)
|
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