more shadow decoupling + change world instance to position instance
parent
96f6d22896
commit
4d3c5fc316
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasTranslation
|
||||||
|
{
|
||||||
|
Vector3 Translation { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
|
|
BIN
Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/DeferredPBR_GBufferEffect.fxb (Stored with Git LFS)
Binary file not shown.
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
|
@ -24,11 +24,6 @@ struct VertexInput
|
||||||
float2 TexCoord : TEXCOORD;
|
float2 TexCoord : TEXCOORD;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstanceInput
|
|
||||||
{
|
|
||||||
float4x4 World : TEXCOORD2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PixelInput
|
struct PixelInput
|
||||||
{
|
{
|
||||||
float4 Position : SV_POSITION;
|
float4 Position : SV_POSITION;
|
||||||
|
@ -61,15 +56,23 @@ PixelInput main_vs(VertexInput input)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelInput instanced_vs(VertexInput input, InstanceInput instanceInput)
|
PixelInput instanced_vs(VertexInput input, float3 Translation : TEXCOORD2)
|
||||||
{
|
{
|
||||||
PixelInput output;
|
PixelInput output;
|
||||||
|
|
||||||
output.PositionWorld = mul(input.Position, instanceInput.World).xyz;
|
float4x4 world = float4x4(
|
||||||
output.NormalWorld = normalize(mul(input.Normal, instanceInput.World));
|
float4(1, 0, 0, 0),
|
||||||
|
float4(0, 1, 0, 0),
|
||||||
|
float4(0, 0, 1, 0),
|
||||||
|
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||||
|
|
||||||
|
output.PositionWorld = mul(input.Position, world);
|
||||||
|
output.NormalWorld = mul(input.Normal, world);
|
||||||
output.TexCoord = input.TexCoord;
|
output.TexCoord = input.TexCoord;
|
||||||
|
|
||||||
float4x4 worldViewProjection = mul(instanceInput.World, ViewProjection);
|
|
||||||
output.Position = mul(input.Position, worldViewProjection);
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
BEGIN_CONSTANTS
|
BEGIN_CONSTANTS
|
||||||
|
|
||||||
float4x4 ModelViewProjection _vs(c0) _cb(c0);
|
|
||||||
|
|
||||||
MATRIX_CONSTANTS
|
MATRIX_CONSTANTS
|
||||||
|
|
||||||
|
float4x4 World _vs(c0) _cb(c0);
|
||||||
|
float4x4 ViewProjection _vs(c4) _cb(c4);
|
||||||
|
|
||||||
END_CONSTANTS
|
END_CONSTANTS
|
||||||
|
|
||||||
struct VertexShaderInput
|
struct VertexShaderInput
|
||||||
|
@ -15,15 +16,16 @@ struct VertexShaderInput
|
||||||
|
|
||||||
struct VertexShaderOutput
|
struct VertexShaderOutput
|
||||||
{
|
{
|
||||||
float4 Position : SV_Position;
|
float4 Position : SV_POSITION;
|
||||||
float Depth : TEXCOORD0;
|
float Depth : DEPTH;
|
||||||
};
|
};
|
||||||
|
|
||||||
VertexShaderOutput main_vs(VertexShaderInput input)
|
VertexShaderOutput main_vs(VertexShaderInput input)
|
||||||
{
|
{
|
||||||
VertexShaderOutput output;
|
VertexShaderOutput output;
|
||||||
|
|
||||||
output.Position = mul(input.Position, ModelViewProjection);
|
float4x4 worldViewProjection = mul(World, ViewProjection);
|
||||||
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
output.Depth = output.Position.z / output.Position.w;
|
output.Depth = output.Position.z / output.Position.w;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
float4x4 ViewProjection;
|
||||||
|
|
||||||
|
struct VertexShaderInput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexShaderOutput
|
||||||
|
{
|
||||||
|
float4 Position : POSITION0;
|
||||||
|
float4 ProjectedPosition : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VertexShaderOutput instanced_vs(VertexShaderInput input, float3 Translation : TEXCOORD2)
|
||||||
|
{
|
||||||
|
VertexShaderOutput output;
|
||||||
|
|
||||||
|
float4x4 world = float4x4(
|
||||||
|
float4(1, 0, 0, 0),
|
||||||
|
float4(0, 1, 0, 0),
|
||||||
|
float4(0, 0, 1, 0),
|
||||||
|
float4(Translation.x, Translation.y, Translation.z, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
float4x4 worldViewProjection = mul(world, ViewProjection);
|
||||||
|
|
||||||
|
output.Position = mul(input.Position, worldViewProjection);
|
||||||
|
output.ProjectedPosition = output.Position;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 main_ps(VertexShaderOutput input) : COLOR0
|
||||||
|
{
|
||||||
|
return float4(input.ProjectedPosition.z / input.ProjectedPosition.w, 0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Technique SimpleDepth
|
||||||
|
{
|
||||||
|
Pass
|
||||||
|
{
|
||||||
|
VertexShader = compile vs_3_0 instanced_vs();
|
||||||
|
PixelShader = compile ps_3_0 main_ps();
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,12 +7,10 @@ namespace Kav
|
||||||
{
|
{
|
||||||
EffectParameter worldParam;
|
EffectParameter worldParam;
|
||||||
EffectParameter viewProjectionParam;
|
EffectParameter viewProjectionParam;
|
||||||
EffectParameter vertexShaderIndexParam;
|
|
||||||
|
|
||||||
Matrix world;
|
Matrix world;
|
||||||
Matrix view;
|
Matrix view;
|
||||||
Matrix projection;
|
Matrix projection;
|
||||||
bool hardwareInstancingEnabled = false;
|
|
||||||
|
|
||||||
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
@ -46,19 +44,6 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HardwareInstancingEnabled
|
|
||||||
{
|
|
||||||
get { return hardwareInstancingEnabled; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value != hardwareInstancingEnabled)
|
|
||||||
{
|
|
||||||
hardwareInstancingEnabled = value;
|
|
||||||
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimpleDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffect)
|
public SimpleDepthEffect(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffect)
|
||||||
{
|
{
|
||||||
CacheEffectParameters();
|
CacheEffectParameters();
|
||||||
|
@ -80,25 +65,12 @@ namespace Kav
|
||||||
|
|
||||||
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
|
|
||||||
{
|
|
||||||
int vertexShaderIndex = 0;
|
|
||||||
|
|
||||||
if (hardwareInstancingEnabled)
|
|
||||||
{
|
|
||||||
vertexShaderIndex = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexShaderIndexParam.SetValue(vertexShaderIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheEffectParameters()
|
private void CacheEffectParameters()
|
||||||
{
|
{
|
||||||
worldParam = Parameters["World"];
|
worldParam = Parameters["World"];
|
||||||
viewProjectionParam = Parameters["ViewProjection"];
|
viewProjectionParam = Parameters["ViewProjection"];
|
||||||
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public class SimpleDepthEffectInstanced : Effect
|
||||||
|
{
|
||||||
|
EffectParameter viewProjectionParam;
|
||||||
|
|
||||||
|
Matrix view;
|
||||||
|
Matrix projection;
|
||||||
|
|
||||||
|
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
|
||||||
|
|
||||||
|
public Matrix View
|
||||||
|
{
|
||||||
|
get { return view; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
view = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Matrix Projection
|
||||||
|
{
|
||||||
|
get { return projection; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
projection = value;
|
||||||
|
dirtyFlags |= EffectDirtyFlags.ViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDepthEffectInstanced(GraphicsDevice graphicsDevice) : base(graphicsDevice, Resources.SimpleDepthEffectInstanced)
|
||||||
|
{
|
||||||
|
CacheEffectParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnApply()
|
||||||
|
{
|
||||||
|
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
|
||||||
|
{
|
||||||
|
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
|
||||||
|
viewProjectionParam.SetValue(viewProjection);
|
||||||
|
|
||||||
|
dirtyFlags &= ~EffectDirtyFlags.ViewProj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CacheEffectParameters()
|
||||||
|
{
|
||||||
|
viewProjectionParam = Parameters["ViewProjection"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasVertexPositions
|
||||||
|
{
|
||||||
|
Vector3[] Positions { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable
|
public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable, IHasVertexPositions
|
||||||
{
|
{
|
||||||
public IndexBuffer IndexBuffer { get; }
|
public IndexBuffer IndexBuffer { get; }
|
||||||
public VertexBuffer VertexBuffer { get; }
|
public VertexBuffer VertexBuffer { get; }
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.SimpleDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Effects\FXB\SimpleDepthEffectInstanced.fxb">
|
||||||
|
<LogicalName>Kav.Resources.SimpleDepthEffectInstanced.fxb</LogicalName>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
<EmbeddedResource Include="Effects\FXB\LinearDepthEffect.fxb">
|
||||||
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
<LogicalName>Kav.Resources.LinearDepthEffect.fxb</LogicalName>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
|
151
Renderer.cs
151
Renderer.cs
|
@ -9,7 +9,6 @@ namespace Kav
|
||||||
public class Renderer
|
public class Renderer
|
||||||
{
|
{
|
||||||
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
|
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
|
||||||
private const int MAX_SHADOW_CASCADES = 4;
|
|
||||||
|
|
||||||
private GraphicsDevice GraphicsDevice { get; }
|
private GraphicsDevice GraphicsDevice { get; }
|
||||||
|
|
||||||
|
@ -23,6 +22,7 @@ namespace Kav
|
||||||
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
private DeferredPBR_DirectionalLightEffect DeferredDirectionalLightEffect { get; }
|
||||||
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
private Deferred_ToonEffect Deferred_ToonEffect { get; }
|
||||||
private SimpleDepthEffect SimpleDepthEffect { get; }
|
private SimpleDepthEffect SimpleDepthEffect { get; }
|
||||||
|
private SimpleDepthEffectInstanced SimpleDepthEffectInstanced { get; }
|
||||||
private LinearDepthEffect LinearDepthEffect { get; }
|
private LinearDepthEffect LinearDepthEffect { get; }
|
||||||
private Effect ToneMapEffect { get; }
|
private Effect ToneMapEffect { get; }
|
||||||
private SkyboxEffect SkyboxEffect { get; }
|
private SkyboxEffect SkyboxEffect { get; }
|
||||||
|
@ -30,10 +30,8 @@ namespace Kav
|
||||||
|
|
||||||
private Kav.Model UnitCube { get; }
|
private Kav.Model UnitCube { get; }
|
||||||
|
|
||||||
private SpriteBatch SpriteBatch { get; }
|
private DynamicVertexBuffer PositionInstanceVertexBuffer { get; }
|
||||||
|
private readonly PositionInstanceVertex[] GBufferInstanceVertices = new PositionInstanceVertex[MAX_INSTANCE_VERTEX_COUNT];
|
||||||
private DynamicVertexBuffer GBufferInstanceVertexBuffer { get; }
|
|
||||||
private readonly GBufferInstanceVertex[] GBufferInstanceVertices = new GBufferInstanceVertex[MAX_INSTANCE_VERTEX_COUNT];
|
|
||||||
|
|
||||||
public Renderer(
|
public Renderer(
|
||||||
GraphicsDevice graphicsDevice
|
GraphicsDevice graphicsDevice
|
||||||
|
@ -41,6 +39,7 @@ namespace Kav
|
||||||
GraphicsDevice = graphicsDevice;
|
GraphicsDevice = graphicsDevice;
|
||||||
|
|
||||||
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
SimpleDepthEffect = new SimpleDepthEffect(GraphicsDevice);
|
||||||
|
SimpleDepthEffectInstanced = new SimpleDepthEffectInstanced(GraphicsDevice);
|
||||||
LinearDepthEffect = new LinearDepthEffect(GraphicsDevice);
|
LinearDepthEffect = new LinearDepthEffect(GraphicsDevice);
|
||||||
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
DeferredPBREffect = new DeferredPBREffect(GraphicsDevice);
|
||||||
|
|
||||||
|
@ -65,11 +64,9 @@ namespace Kav
|
||||||
Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel))
|
Smuggler.Importer.ImportGLB(GraphicsDevice, new MemoryStream(Resources.UnitCubeModel))
|
||||||
);
|
);
|
||||||
|
|
||||||
SpriteBatch = new SpriteBatch(graphicsDevice);
|
PositionInstanceVertexBuffer = new DynamicVertexBuffer(
|
||||||
|
|
||||||
GBufferInstanceVertexBuffer = new DynamicVertexBuffer(
|
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
VertexDeclarations.GBufferInstanceDeclaration,
|
VertexDeclarations.PositionInstanceDeclaration,
|
||||||
MAX_INSTANCE_VERTEX_COUNT,
|
MAX_INSTANCE_VERTEX_COUNT,
|
||||||
BufferUsage.WriteOnly
|
BufferUsage.WriteOnly
|
||||||
);
|
);
|
||||||
|
@ -203,13 +200,11 @@ namespace Kav
|
||||||
// Effect must be pre-configured!!
|
// Effect must be pre-configured!!
|
||||||
public static void CullAndRenderIndexed<T, U>(
|
public static void CullAndRenderIndexed<T, U>(
|
||||||
GraphicsDevice graphicsDevice,
|
GraphicsDevice graphicsDevice,
|
||||||
PerspectiveCamera camera,
|
BoundingFrustum boundingFrustum,
|
||||||
IEnumerable<(T, Matrix)> drawableTransformPairs,
|
IEnumerable<(T, Matrix)> drawableTransformPairs,
|
||||||
U effect
|
U effect
|
||||||
) where T : IIndexDrawable, ICullable where U : Effect, IHasWorldMatrix
|
) where T : IIndexDrawable, ICullable where U : Effect, IHasWorldMatrix
|
||||||
{
|
{
|
||||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
|
||||||
|
|
||||||
foreach (var (drawable, transform) in FrustumCull(boundingFrustum, drawableTransformPairs))
|
foreach (var (drawable, transform) in FrustumCull(boundingFrustum, drawableTransformPairs))
|
||||||
{
|
{
|
||||||
effect.World = transform;
|
effect.World = transform;
|
||||||
|
@ -253,14 +248,14 @@ namespace Kav
|
||||||
IEnumerable<Matrix> transforms,
|
IEnumerable<Matrix> transforms,
|
||||||
V[] vertexData,
|
V[] vertexData,
|
||||||
DynamicVertexBuffer dynamicVertexBuffer
|
DynamicVertexBuffer dynamicVertexBuffer
|
||||||
) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasWorldMatrix
|
) where T : ICullable, IIndexDrawable where V : struct, IVertexType, IHasTranslation
|
||||||
{
|
{
|
||||||
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
var boundingFrustum = new BoundingFrustum(camera.View * camera.Projection);
|
||||||
|
|
||||||
int numInstances = 0;
|
int numInstances = 0;
|
||||||
foreach (var transform in FrustumCull(boundingFrustum, drawable, transforms))
|
foreach (var transform in FrustumCull(boundingFrustum, drawable, transforms))
|
||||||
{
|
{
|
||||||
vertexData[numInstances].World = transform;
|
vertexData[numInstances].Translation = transform.Translation;
|
||||||
numInstances += 1;
|
numInstances += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +326,7 @@ namespace Kav
|
||||||
|
|
||||||
CullAndRenderIndexed(
|
CullAndRenderIndexed(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
camera,
|
new BoundingFrustum(camera.View * camera.Projection),
|
||||||
drawableTransforms,
|
drawableTransforms,
|
||||||
SimpleDepthEffect
|
SimpleDepthEffect
|
||||||
);
|
);
|
||||||
|
@ -396,7 +391,7 @@ namespace Kav
|
||||||
drawable,
|
drawable,
|
||||||
transforms,
|
transforms,
|
||||||
GBufferInstanceVertices,
|
GBufferInstanceVertices,
|
||||||
GBufferInstanceVertexBuffer
|
PositionInstanceVertexBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderInstanced(
|
RenderInstanced(
|
||||||
|
@ -407,12 +402,15 @@ namespace Kav
|
||||||
);
|
);
|
||||||
|
|
||||||
// re-render to get depth
|
// re-render to get depth
|
||||||
GraphicsDevice.SetRenderTarget(depthBuffer);
|
GraphicsDevice.SetRenderTargets(depthBuffer);
|
||||||
|
|
||||||
|
SimpleDepthEffectInstanced.View = camera.View;
|
||||||
|
SimpleDepthEffectInstanced.Projection = camera.Projection;
|
||||||
|
|
||||||
RenderInstanced(
|
RenderInstanced(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
drawable,
|
drawable,
|
||||||
Deferred_GBufferEffect,
|
SimpleDepthEffectInstanced,
|
||||||
numInstances
|
numInstances
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -498,17 +496,16 @@ namespace Kav
|
||||||
RenderFullscreenEffect(DeferredPointLightEffect);
|
RenderFullscreenEffect(DeferredPointLightEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderDirectionalLight<T>(
|
public void RenderDirectionalLight(
|
||||||
RenderTarget2D renderTarget,
|
RenderTarget2D renderTarget,
|
||||||
Texture2D gPosition,
|
Texture2D gPosition,
|
||||||
Texture2D gAlbedo,
|
Texture2D gAlbedo,
|
||||||
Texture2D gNormal,
|
Texture2D gNormal,
|
||||||
Texture2D gMetallicRoughness,
|
Texture2D gMetallicRoughness,
|
||||||
|
DirectionalShadowMapData shadowMapData,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(T, Matrix)> modelTransforms,
|
DirectionalLight directionalLight
|
||||||
DirectionalLight directionalLight,
|
) {
|
||||||
DirectionalShadowMapData shadowMapData
|
|
||||||
) where T : ICullable, IIndexDrawable {
|
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
GraphicsDevice.BlendState = BlendState.Additive;
|
GraphicsDevice.BlendState = BlendState.Additive;
|
||||||
|
@ -522,21 +519,25 @@ namespace Kav
|
||||||
|
|
||||||
DeferredDirectionalLightEffect.ShadowMapOne = shadowMapData.ShadowMaps[0];
|
DeferredDirectionalLightEffect.ShadowMapOne = shadowMapData.ShadowMaps[0];
|
||||||
DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne;
|
DeferredDirectionalLightEffect.LightSpaceMatrixOne = shadowMapData.LightSpaceMatrixOne;
|
||||||
|
DeferredDirectionalLightEffect.CascadeFarPlanes[0] = shadowMapData.CascadeFarPlanes[0];
|
||||||
|
|
||||||
if (shadowMapData.NumShadowCascades > 1)
|
if (shadowMapData.NumShadowCascades > 1)
|
||||||
{
|
{
|
||||||
DeferredDirectionalLightEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1];
|
DeferredDirectionalLightEffect.ShadowMapTwo = shadowMapData.ShadowMaps[1];
|
||||||
DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceMatrixTwo;
|
DeferredDirectionalLightEffect.LightSpaceMatrixTwo = shadowMapData.LightSpaceMatrixTwo;
|
||||||
|
DeferredDirectionalLightEffect.CascadeFarPlanes[1] = shadowMapData.CascadeFarPlanes[1];
|
||||||
}
|
}
|
||||||
if (shadowMapData.NumShadowCascades > 2)
|
if (shadowMapData.NumShadowCascades > 2)
|
||||||
{
|
{
|
||||||
DeferredDirectionalLightEffect.ShadowMapThree = shadowMapData.ShadowMaps[2];
|
DeferredDirectionalLightEffect.ShadowMapThree = shadowMapData.ShadowMaps[2];
|
||||||
DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceMatrixThree;
|
DeferredDirectionalLightEffect.LightSpaceMatrixThree = shadowMapData.LightSpaceMatrixThree;
|
||||||
|
DeferredDirectionalLightEffect.CascadeFarPlanes[2] = shadowMapData.CascadeFarPlanes[2];
|
||||||
}
|
}
|
||||||
if (shadowMapData.NumShadowCascades > 3)
|
if (shadowMapData.NumShadowCascades > 3)
|
||||||
{
|
{
|
||||||
DeferredDirectionalLightEffect.ShadowMapFour = shadowMapData.ShadowMaps[3];
|
DeferredDirectionalLightEffect.ShadowMapFour = shadowMapData.ShadowMaps[3];
|
||||||
DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceMatrixFour;
|
DeferredDirectionalLightEffect.LightSpaceMatrixFour = shadowMapData.LightSpaceMatrixFour;
|
||||||
|
DeferredDirectionalLightEffect.CascadeFarPlanes[3] = shadowMapData.CascadeFarPlanes[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredDirectionalLightEffect.DirectionalLightDirection = directionalLight.Direction;
|
DeferredDirectionalLightEffect.DirectionalLightDirection = directionalLight.Direction;
|
||||||
|
@ -549,7 +550,7 @@ namespace Kav
|
||||||
RenderFullscreenEffect(DeferredDirectionalLightEffect);
|
RenderFullscreenEffect(DeferredDirectionalLightEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderDirectionalLightToon<T>(
|
public void RenderDirectionalLightToon(
|
||||||
RenderTarget2D renderTarget,
|
RenderTarget2D renderTarget,
|
||||||
Texture2D gPosition,
|
Texture2D gPosition,
|
||||||
Texture2D gAlbedo,
|
Texture2D gAlbedo,
|
||||||
|
@ -557,10 +558,9 @@ namespace Kav
|
||||||
Texture2D gMetallicRoughness,
|
Texture2D gMetallicRoughness,
|
||||||
DirectionalShadowMapData shadowMapData,
|
DirectionalShadowMapData shadowMapData,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(T, Matrix)> modelTransforms,
|
|
||||||
DirectionalLight directionalLight,
|
DirectionalLight directionalLight,
|
||||||
bool ditheredShadows
|
bool ditheredShadows
|
||||||
) where T : ICullable, IIndexDrawable {
|
) {
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
|
||||||
GraphicsDevice.BlendState = BlendState.Additive;
|
GraphicsDevice.BlendState = BlendState.Additive;
|
||||||
|
@ -697,10 +697,15 @@ namespace Kav
|
||||||
shadowMapData.LightSpaceMatrixFour = lightSpaceMatrix;
|
shadowMapData.LightSpaceMatrixFour = lightSpaceMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
CullAndRenderIndexed(GraphicsDevice, camera, drawableTransforms, SimpleDepthEffect);
|
CullAndRenderIndexed(
|
||||||
|
GraphicsDevice,
|
||||||
|
new BoundingFrustum(lightSpaceMatrix),
|
||||||
|
drawableTransforms,
|
||||||
|
SimpleDepthEffect
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RenderPointShadowsIndexed<T>(
|
public void RenderPointShadowMapIndexed<T>(
|
||||||
RenderTargetCube pointShadowCubeMap,
|
RenderTargetCube pointShadowCubeMap,
|
||||||
PerspectiveCamera camera,
|
PerspectiveCamera camera,
|
||||||
IEnumerable<(T, Matrix)> modelTransforms,
|
IEnumerable<(T, Matrix)> modelTransforms,
|
||||||
|
@ -770,13 +775,101 @@ namespace Kav
|
||||||
|
|
||||||
CullAndRenderIndexed(
|
CullAndRenderIndexed(
|
||||||
GraphicsDevice,
|
GraphicsDevice,
|
||||||
camera,
|
new BoundingFrustum(LinearDepthEffect.View * LinearDepthEffect.Projection),
|
||||||
modelTransforms,
|
modelTransforms,
|
||||||
LinearDepthEffect
|
LinearDepthEffect
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RenderPointShadowMapInstanced<T>(
|
||||||
|
RenderTargetCube pointShadowCubeMap,
|
||||||
|
PerspectiveCamera camera,
|
||||||
|
T drawable,
|
||||||
|
IEnumerable<Matrix> modelTransforms,
|
||||||
|
PointLight pointLight
|
||||||
|
) where T : ICullable, IIndexDrawable
|
||||||
|
{
|
||||||
|
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
|
||||||
|
GraphicsDevice.BlendState = BlendState.Opaque;
|
||||||
|
|
||||||
|
foreach (CubeMapFace face in Enum.GetValues(typeof(CubeMapFace)))
|
||||||
|
{
|
||||||
|
GraphicsDevice.SetRenderTarget(pointShadowCubeMap, face);
|
||||||
|
|
||||||
|
Vector3 targetDirection;
|
||||||
|
Vector3 targetUpDirection;
|
||||||
|
switch(face)
|
||||||
|
{
|
||||||
|
case CubeMapFace.PositiveX:
|
||||||
|
targetDirection = Vector3.Right;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeX:
|
||||||
|
targetDirection = Vector3.Left;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.PositiveY:
|
||||||
|
targetDirection = Vector3.Up;
|
||||||
|
targetUpDirection = Vector3.Forward;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeY:
|
||||||
|
targetDirection = Vector3.Down;
|
||||||
|
targetUpDirection = Vector3.Backward;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.PositiveZ:
|
||||||
|
targetDirection = Vector3.Backward;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CubeMapFace.NegativeZ:
|
||||||
|
targetDirection = Vector3.Forward;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
targetDirection = Vector3.Right;
|
||||||
|
targetUpDirection = Vector3.Up;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinearDepthEffect.View = Matrix.CreateLookAt(
|
||||||
|
pointLight.Position,
|
||||||
|
pointLight.Position + targetDirection,
|
||||||
|
targetUpDirection
|
||||||
|
);
|
||||||
|
LinearDepthEffect.Projection = Matrix.CreatePerspectiveFieldOfView(
|
||||||
|
MathHelper.PiOver2,
|
||||||
|
1,
|
||||||
|
0.1f,
|
||||||
|
25f // FIXME: magic value
|
||||||
|
);
|
||||||
|
LinearDepthEffect.FarPlane = 25f;
|
||||||
|
|
||||||
|
LinearDepthEffect.LightPosition = pointLight.Position;
|
||||||
|
|
||||||
|
// TODO: set up instancing
|
||||||
|
// var numInstances = FillAndSetBuffersForInstancing(
|
||||||
|
// GraphicsDevice,
|
||||||
|
// camera,
|
||||||
|
// drawable,
|
||||||
|
// transforms,
|
||||||
|
// VertexPos
|
||||||
|
// );
|
||||||
|
|
||||||
|
// RenderInstanced(
|
||||||
|
// GraphicsDevice,
|
||||||
|
// camera,
|
||||||
|
// modelTransforms,
|
||||||
|
// LinearDepthEffect
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static IEnumerable<(T, Matrix)> FrustumCull<T>(
|
private static IEnumerable<(T, Matrix)> FrustumCull<T>(
|
||||||
BoundingFrustum boundingFrustum,
|
BoundingFrustum boundingFrustum,
|
||||||
IEnumerable<(T, Matrix)> cullableTransforms
|
IEnumerable<(T, Matrix)> cullableTransforms
|
||||||
|
|
13
Resources.cs
13
Resources.cs
|
@ -111,6 +111,18 @@ namespace Kav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] SimpleDepthEffectInstanced
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (simpleDepthEffectInstanced == null)
|
||||||
|
{
|
||||||
|
simpleDepthEffectInstanced = GetResource("SimpleDepthEffectInstanced.fxb");
|
||||||
|
}
|
||||||
|
return simpleDepthEffectInstanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] LinearDepthEffect
|
public static byte[] LinearDepthEffect
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -168,6 +180,7 @@ namespace Kav
|
||||||
private static byte[] deferredPBREffect;
|
private static byte[] deferredPBREffect;
|
||||||
private static byte[] pbrEffect;
|
private static byte[] pbrEffect;
|
||||||
private static byte[] simpleDepthEffect;
|
private static byte[] simpleDepthEffect;
|
||||||
|
private static byte[] simpleDepthEffectInstanced;
|
||||||
private static byte[] linearDepthEffect;
|
private static byte[] linearDepthEffect;
|
||||||
private static byte[] skyboxEffect;
|
private static byte[] skyboxEffect;
|
||||||
private static byte[] diffuseLitSpriteEffect;
|
private static byte[] diffuseLitSpriteEffect;
|
||||||
|
|
|
@ -4,12 +4,9 @@ namespace Kav
|
||||||
{
|
{
|
||||||
public static class VertexDeclarations
|
public static class VertexDeclarations
|
||||||
{
|
{
|
||||||
public static VertexDeclaration GBufferInstanceDeclaration = new VertexDeclaration
|
public static VertexDeclaration PositionInstanceDeclaration = new VertexDeclaration
|
||||||
(
|
(
|
||||||
new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 2),
|
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2)
|
||||||
new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3),
|
|
||||||
new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4),
|
|
||||||
new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 5)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,24 @@ using Microsoft.Xna.Framework.Graphics;
|
||||||
namespace Kav
|
namespace Kav
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct GBufferInstanceVertex : IVertexType, IHasWorldMatrix
|
public struct PositionInstanceVertex : IVertexType, IHasTranslation
|
||||||
{
|
{
|
||||||
VertexDeclaration IVertexType.VertexDeclaration
|
VertexDeclaration IVertexType.VertexDeclaration
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return VertexDeclarations.GBufferInstanceDeclaration;
|
return VertexDeclarations.PositionInstanceDeclaration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Matrix World { get; set; }
|
public Vector3 Translation { get; set; }
|
||||||
|
|
||||||
public static readonly VertexDeclaration VertexDeclaration;
|
public static readonly VertexDeclaration VertexDeclaration;
|
||||||
|
|
||||||
public GBufferInstanceVertex(
|
public PositionInstanceVertex(
|
||||||
Matrix world
|
Vector3 translation
|
||||||
) {
|
) {
|
||||||
World = world;
|
Translation = translation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue