refactor for reusing instance buffers
parent
0c576668cb
commit
9a7fb75ec5
138
Renderer.cs
138
Renderer.cs
|
@ -8,8 +8,6 @@ namespace Kav
|
|||
{
|
||||
public class Renderer
|
||||
{
|
||||
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
|
||||
|
||||
private GraphicsDevice GraphicsDevice { get; }
|
||||
|
||||
private VertexBuffer FullscreenTriangle { get; }
|
||||
|
@ -24,15 +22,13 @@ namespace Kav
|
|||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||
private SimpleDepthEffectInstanced SimpleDepthEffectInstanced { get; }
|
||||
private LinearDepthEffect LinearDepthEffect { get; }
|
||||
private LinearDepthEffectInstanced LinearDepthEffectInstanced { get; }
|
||||
private Effect ToneMapEffect { get; }
|
||||
private SkyboxEffect SkyboxEffect { get; }
|
||||
private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; }
|
||||
|
||||
private Kav.Model UnitCube { get; }
|
||||
|
||||
private DynamicVertexBuffer PositionInstanceVertexBuffer { get; }
|
||||
private readonly PositionInstanceVertex[] PositionInstanceVertices = new PositionInstanceVertex[MAX_INSTANCE_VERTEX_COUNT];
|
||||
|
||||
public Renderer(
|
||||
GraphicsDevice graphicsDevice
|
||||
) {
|
||||
|
@ -41,6 +37,8 @@ namespace Kav
|
|||
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
||||
SimpleDepthEffectInstanced = new SimpleDepthEffectInstanced(GraphicsDevice);
|
||||
LinearDepthEffect = new LinearDepthEffect(GraphicsDevice);
|
||||
LinearDepthEffectInstanced = new LinearDepthEffectInstanced(GraphicsDevice);
|
||||
|
||||
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
||||
|
||||
Deferred_GBufferEffect = new DeferredPBR_GBufferEffect(GraphicsDevice);
|
||||
|
@ -63,13 +61,21 @@ namespace Kav
|
|||
GraphicsDevice,
|
||||
Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel))
|
||||
);
|
||||
}
|
||||
|
||||
PositionInstanceVertexBuffer = new DynamicVertexBuffer(
|
||||
GraphicsDevice,
|
||||
public static (PositionInstanceVertex[], DynamicVertexBuffer) CreatePositionVertexBuffer(
|
||||
GraphicsDevice graphicsDevice,
|
||||
int instanceVertexCount
|
||||
) {
|
||||
var positionData = new PositionInstanceVertex[instanceVertexCount];
|
||||
var vertexBuffer = new DynamicVertexBuffer(
|
||||
graphicsDevice,
|
||||
VertexDeclarations.PositionInstanceDeclaration,
|
||||
MAX_INSTANCE_VERTEX_COUNT,
|
||||
instanceVertexCount,
|
||||
BufferUsage.WriteOnly
|
||||
);
|
||||
|
||||
return (positionData, vertexBuffer);
|
||||
}
|
||||
|
||||
public static RenderTargetCube CreateShadowCubeMap(
|
||||
|
@ -251,13 +257,11 @@ namespace Kav
|
|||
}
|
||||
}
|
||||
|
||||
public static int FillAndSetBuffersForInstancing<T, V>(
|
||||
GraphicsDevice graphicsDevice,
|
||||
T drawable,
|
||||
public static int FillInstanceVertexBuffer<V>(
|
||||
IEnumerable<Matrix> transforms,
|
||||
V[] vertexData,
|
||||
DynamicVertexBuffer dynamicVertexBuffer
|
||||
) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasTranslation
|
||||
) where V : struct, IVertexType, IHasTranslation
|
||||
{
|
||||
int numInstances = 0;
|
||||
foreach (var transform in transforms)
|
||||
|
@ -275,22 +279,22 @@ namespace Kav
|
|||
SetDataOptions.Discard
|
||||
);
|
||||
|
||||
graphicsDevice.SetVertexBuffers(
|
||||
drawable.VertexBuffer,
|
||||
new VertexBufferBinding(dynamicVertexBuffer, 0, 1)
|
||||
);
|
||||
graphicsDevice.Indices = drawable.IndexBuffer;
|
||||
|
||||
return numInstances;
|
||||
}
|
||||
|
||||
public static void RenderInstanced<T, U>(
|
||||
public static void RenderInstanced<T>(
|
||||
GraphicsDevice graphicsDevice,
|
||||
T drawable,
|
||||
U effect,
|
||||
int numInstances
|
||||
) where T : ICullable, IIndexDrawable where U : Effect
|
||||
{
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances,
|
||||
Effect effect
|
||||
) where T : IIndexDrawable {
|
||||
graphicsDevice.SetVertexBuffers(
|
||||
drawable.VertexBuffer,
|
||||
new VertexBufferBinding(instanceVertexBuffer, 0, 1)
|
||||
);
|
||||
graphicsDevice.Indices = drawable.IndexBuffer;
|
||||
|
||||
foreach (var pass in effect.CurrentTechnique.Passes)
|
||||
{
|
||||
pass.Apply();
|
||||
|
@ -367,14 +371,16 @@ namespace Kav
|
|||
|
||||
/// <summary>
|
||||
/// GBuffer binding must have 4 render targets.
|
||||
/// Assumes that vertex buffer has been filled.
|
||||
/// </summary>
|
||||
public void RenderGBufferInstanced<T>(
|
||||
RenderTargetBinding[] gBuffer,
|
||||
RenderTarget2D depthBuffer,
|
||||
PerspectiveCamera camera,
|
||||
T drawable,
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable, IGBufferDrawable {
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IGBufferDrawable, IIndexDrawable {
|
||||
GraphicsDevice.SetRenderTargets(gBuffer);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||
|
@ -392,21 +398,12 @@ namespace Kav
|
|||
Deferred_GBufferEffect.View = camera.View;
|
||||
Deferred_GBufferEffect.Projection = camera.Projection;
|
||||
|
||||
var numInstances = FillAndSetBuffersForInstancing(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
transforms,
|
||||
PositionInstanceVertices,
|
||||
PositionInstanceVertexBuffer
|
||||
);
|
||||
|
||||
if (numInstances == 0) { return; }
|
||||
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
Deferred_GBufferEffect,
|
||||
numInstances
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
Deferred_GBufferEffect
|
||||
);
|
||||
|
||||
// re-render to get depth
|
||||
|
@ -418,8 +415,9 @@ namespace Kav
|
|||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
SimpleDepthEffectInstanced,
|
||||
numInstances
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
SimpleDepthEffectInstanced
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -717,8 +715,9 @@ namespace Kav
|
|||
public void RenderDirectionalShadowsInstanced<T>(
|
||||
DirectionalShadowMapData shadowMapData,
|
||||
T drawable,
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IIndexDrawable
|
||||
{
|
||||
// render the individual shadow cascades
|
||||
for (var i = 0; i < shadowMapData.NumShadowCascades; i++)
|
||||
|
@ -727,7 +726,8 @@ namespace Kav
|
|||
shadowMapData,
|
||||
i,
|
||||
drawable,
|
||||
transforms
|
||||
instanceVertexBuffer,
|
||||
numInstances
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -736,8 +736,9 @@ namespace Kav
|
|||
DirectionalShadowMapData shadowMapData,
|
||||
int shadowCascadeIndex,
|
||||
T drawable,
|
||||
IEnumerable<Matrix> transforms
|
||||
) where T : ICullable, IIndexDrawable
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances
|
||||
) where T : IIndexDrawable
|
||||
{
|
||||
GraphicsDevice.SetRenderTarget(shadowMapData.ShadowMaps[shadowCascadeIndex]);
|
||||
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||
|
@ -746,19 +747,12 @@ namespace Kav
|
|||
SimpleDepthEffectInstanced.View = shadowMapData.LightSpaceViews[shadowCascadeIndex];
|
||||
SimpleDepthEffectInstanced.Projection = shadowMapData.LightSpaceProjections[shadowCascadeIndex];
|
||||
|
||||
var numInstances = FillAndSetBuffersForInstancing(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
transforms,
|
||||
PositionInstanceVertices,
|
||||
PositionInstanceVertexBuffer
|
||||
);
|
||||
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
SimpleDepthEffectInstanced,
|
||||
numInstances
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
SimpleDepthEffectInstanced
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -841,9 +835,9 @@ namespace Kav
|
|||
|
||||
public void RenderPointShadowMapInstanced<T>(
|
||||
RenderTargetCube pointShadowCubeMap,
|
||||
PerspectiveCamera camera,
|
||||
T drawable,
|
||||
IEnumerable<Matrix> modelTransforms,
|
||||
VertexBuffer instanceVertexBuffer,
|
||||
int numInstances,
|
||||
PointLight pointLight
|
||||
) where T : ICullable, IIndexDrawable
|
||||
{
|
||||
|
@ -894,36 +888,28 @@ namespace Kav
|
|||
break;
|
||||
}
|
||||
|
||||
LinearDepthEffect.View = Matrix.CreateLookAt(
|
||||
LinearDepthEffectInstanced.View = Matrix.CreateLookAt(
|
||||
pointLight.Position,
|
||||
pointLight.Position + targetDirection,
|
||||
targetUpDirection
|
||||
);
|
||||
LinearDepthEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||
LinearDepthEffectInstanced.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||
MathHelper.PiOver2,
|
||||
1,
|
||||
0.1f,
|
||||
25f // FIXME: magic value
|
||||
);
|
||||
LinearDepthEffect.FarPlane = 25f;
|
||||
|
||||
LinearDepthEffect.LightPosition = pointLight.Position;
|
||||
LinearDepthEffectInstanced.FarPlane = 25f;
|
||||
LinearDepthEffectInstanced.LightPosition = pointLight.Position;
|
||||
|
||||
// TODO: set up instancing
|
||||
// var numInstances = FillAndSetBuffersForInstancing(
|
||||
// GraphicsDevice,
|
||||
// camera,
|
||||
// drawable,
|
||||
// transforms,
|
||||
// VertexPos
|
||||
// );
|
||||
|
||||
// RenderInstanced(
|
||||
// GraphicsDevice,
|
||||
// camera,
|
||||
// modelTransforms,
|
||||
// LinearDepthEffect
|
||||
// );
|
||||
RenderInstanced(
|
||||
GraphicsDevice,
|
||||
drawable,
|
||||
instanceVertexBuffer,
|
||||
numInstances,
|
||||
LinearDepthEffectInstanced
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue