more shadow decoupling + change world instance to position instance

instancing
cosmonaut 2020-12-08 02:49:18 -08:00
parent 96f6d22896
commit 4d3c5fc316
18 changed files with 296 additions and 88 deletions

View File

@ -0,0 +1,9 @@
using Microsoft.Xna.Framework;
namespace Kav
{
public interface IHasTranslation
{
Vector3 Translation { get; set; }
}
}

View File

@ -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)

Binary file not shown.

BIN
Effects/FXB/SimpleDepthEffect.fxb (Stored with Git LFS)

Binary file not shown.

BIN
Effects/FXB/SimpleDepthEffectInstanced.fxb (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -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;

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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"];
} }
} }
} }

View File

@ -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"];
}
}
}

View File

@ -0,0 +1,9 @@
using Microsoft.Xna.Framework;
namespace Kav
{
public interface IHasVertexPositions
{
Vector3[] Positions { get; }
}
}

View File

@ -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; }

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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)
); );
} }
} }

View File

@ -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;
} }
} }
} }