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