instancing + mega refactor #6

Merged
cosmonaut merged 12 commits from instancing into main 2020-12-08 11:37:18 +00:00
27 changed files with 977 additions and 542 deletions

View File

@ -0,0 +1,59 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public class DirectionalShadowMapData
{
public static readonly int MAX_SHADOW_CASCADES = 4;
public RenderTarget2D[] ShadowMaps { get; }
public Matrix[] LightSpaceViews { get; }
public Matrix[] LightSpaceProjections { get; }
public float[] CascadeFarPlanes { get; }
public int ShadowMapSize { get; }
public int NumShadowCascades { get; }
internal DirectionalShadowMapData(
GraphicsDevice graphicsDevice,
int shadowMapSize,
int numCascades
) {
ShadowMapSize = shadowMapSize;
NumShadowCascades = (int)MathHelper.Clamp(numCascades, 1, MAX_SHADOW_CASCADES);
LightSpaceViews = new Matrix[4];
LightSpaceProjections = new Matrix[4];
ShadowMaps = new RenderTarget2D[NumShadowCascades];
for (var i = 0; i < NumShadowCascades; i++)
{
ShadowMaps[i] = new RenderTarget2D(
graphicsDevice,
shadowMapSize,
shadowMapSize,
false,
SurfaceFormat.Single,
DepthFormat.Depth24,
0,
RenderTargetUsage.PreserveContents
);
}
CascadeFarPlanes = new float[MAX_SHADOW_CASCADES];
}
public void Clear(GraphicsDevice graphicsDevice)
{
foreach (var shadowMap in ShadowMaps)
{
graphicsDevice.SetRenderTarget(shadowMap);
graphicsDevice.Clear(Color.White);
}
}
}
}

View File

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

View File

@ -0,0 +1,9 @@
using Microsoft.Xna.Framework;
namespace Kav
{
public interface IHasWorldMatrix
{
Matrix World { get; set; }
}
}

View File

@ -6,8 +6,7 @@ namespace Kav
public class DeferredPBR_GBufferEffect : Effect, TransformEffect public class DeferredPBR_GBufferEffect : Effect, TransformEffect
{ {
EffectParameter worldParam; EffectParameter worldParam;
EffectParameter worldViewProjectionParam; EffectParameter viewProjectionParam;
EffectParameter worldInverseTransposeParam;
EffectParameter albedoTextureParam; EffectParameter albedoTextureParam;
EffectParameter normalTextureParam; EffectParameter normalTextureParam;
@ -17,6 +16,7 @@ namespace Kav
EffectParameter metallicParam; EffectParameter metallicParam;
EffectParameter roughnessParam; EffectParameter roughnessParam;
EffectParameter vertexShaderIndexParam;
EffectParameter shaderIndexParam; EffectParameter shaderIndexParam;
Matrix world = Matrix.Identity; Matrix world = Matrix.Identity;
@ -30,6 +30,7 @@ namespace Kav
bool albedoTextureEnabled = false; bool albedoTextureEnabled = false;
bool metallicRoughnessMapEnabled = false; bool metallicRoughnessMapEnabled = false;
bool normalMapEnabled = false; bool normalMapEnabled = false;
bool hardwareInstancingEnabled = false;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
@ -39,7 +40,7 @@ namespace Kav
set set
{ {
world = value; world = value;
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.World;
} }
} }
@ -49,7 +50,7 @@ namespace Kav
set set
{ {
view = value; view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition; dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition;
} }
} }
@ -59,7 +60,7 @@ namespace Kav
set set
{ {
projection = value; projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.ViewProj;
} }
} }
@ -100,7 +101,7 @@ namespace Kav
{ {
albedoTextureParam.SetValue(value); albedoTextureParam.SetValue(value);
albedoTextureEnabled = value != null; albedoTextureEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
@ -111,7 +112,7 @@ namespace Kav
{ {
normalTextureParam.SetValue(value); normalTextureParam.SetValue(value);
normalMapEnabled = value != null; normalMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
@ -122,7 +123,20 @@ namespace Kav
{ {
metallicRoughnessTextureParam.SetValue(value); metallicRoughnessTextureParam.SetValue(value);
metallicRoughnessMapEnabled = value != null; metallicRoughnessMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
}
}
public bool HardwareInstancingEnabled
{
get { return hardwareInstancingEnabled; }
set
{
if (value != hardwareInstancingEnabled)
{
hardwareInstancingEnabled = value;
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
}
} }
} }
@ -159,30 +173,30 @@ namespace Kav
{ {
worldParam.SetValue(world); worldParam.SetValue(world);
Matrix.Invert(ref world, out Matrix worldInverse);
Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose);
worldInverseTransposeParam.SetValue(worldInverseTranspose);
dirtyFlags &= ~EffectDirtyFlags.World; dirtyFlags &= ~EffectDirtyFlags.World;
} }
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
{ {
Matrix.Multiply(ref world, ref view, out Matrix worldView); Matrix.Multiply(ref view, ref projection, out Matrix viewProj);
Matrix.Multiply(ref worldView, ref projection, out Matrix worldViewProj); viewProjectionParam.SetValue(viewProj);
worldViewProjectionParam.SetValue(worldViewProj);
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; dirtyFlags &= ~EffectDirtyFlags.ViewProj;
} }
if ((dirtyFlags & EffectDirtyFlags.EyePosition) != 0) if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
{ {
Matrix.Invert(ref view, out Matrix inverseView); int vertexShaderIndex = 0;
dirtyFlags &= ~EffectDirtyFlags.EyePosition; if (hardwareInstancingEnabled)
{
vertexShaderIndex = 1;
}
vertexShaderIndexParam.SetValue(vertexShaderIndex);
} }
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
{ {
int shaderIndex = 0; int shaderIndex = 0;
@ -217,15 +231,14 @@ namespace Kav
shaderIndexParam.SetValue(shaderIndex); shaderIndexParam.SetValue(shaderIndex);
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex; dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
} }
} }
void CacheEffectParameters() void CacheEffectParameters()
{ {
worldParam = Parameters["World"]; worldParam = Parameters["World"];
worldViewProjectionParam = Parameters["WorldViewProjection"]; viewProjectionParam = Parameters["ViewProjection"];
worldInverseTransposeParam = Parameters["WorldInverseTranspose"];
albedoTextureParam = Parameters["AlbedoTexture"]; albedoTextureParam = Parameters["AlbedoTexture"];
normalTextureParam = Parameters["NormalTexture"]; normalTextureParam = Parameters["NormalTexture"];
@ -235,7 +248,8 @@ namespace Kav
metallicParam = Parameters["MetallicValue"]; metallicParam = Parameters["MetallicValue"];
roughnessParam = Parameters["RoughnessValue"]; roughnessParam = Parameters["RoughnessValue"];
shaderIndexParam = Parameters["ShaderIndex"]; shaderIndexParam = Parameters["PixelShaderIndex"];
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
} }
} }
} }

View File

@ -40,7 +40,7 @@ namespace Kav
if (normalMapEnabled != value) if (normalMapEnabled != value)
{ {
normalMapEnabled = value; normalMapEnabled = value;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
} }
@ -142,7 +142,7 @@ namespace Kav
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
} }
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
{ {
int shaderIndex = 0; int shaderIndex = 0;

View File

@ -8,7 +8,9 @@ namespace Kav
WorldViewProj = 1, WorldViewProj = 1,
World = 2, World = 2,
EyePosition = 4, EyePosition = 4,
ShaderIndex = 8, VertexShaderIndex = 8,
PixelShaderIndex = 16,
ViewProj = 32,
All = -1 All = -1
} }
} }

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

@ -13,8 +13,7 @@ BEGIN_CONSTANTS
MATRIX_CONSTANTS MATRIX_CONSTANTS
float4x4 World _vs(c0) _cb(c7); float4x4 World _vs(c0) _cb(c7);
float4x4 WorldInverseTranspose _vs(c4) _cb(c11); float4x4 ViewProjection _vs(c4) _cb(c11);
float4x4 WorldViewProjection _vs(c8) _cb(c15);
END_CONSTANTS END_CONSTANTS
@ -22,7 +21,7 @@ struct VertexInput
{ {
float4 Position : POSITION; float4 Position : POSITION;
float3 Normal : NORMAL; float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD;
}; };
struct PixelInput struct PixelInput
@ -48,9 +47,33 @@ PixelInput main_vs(VertexInput input)
PixelInput output; PixelInput output;
output.PositionWorld = mul(input.Position, World).xyz; output.PositionWorld = mul(input.Position, World).xyz;
output.NormalWorld = mul(input.Normal, (float3x3)WorldInverseTranspose).xyz; output.NormalWorld = normalize(mul(input.Normal, World));
output.TexCoord = input.TexCoord; output.TexCoord = input.TexCoord;
output.Position = mul(input.Position, WorldViewProjection);
float4x4 worldViewProjection = mul(World, ViewProjection);
output.Position = mul(input.Position, worldViewProjection);
return output;
}
PixelInput instanced_vs(VertexInput input, float3 Translation : TEXCOORD2)
{
PixelInput 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.PositionWorld = mul(input.Position, world);
output.NormalWorld = mul(input.Normal, world);
output.TexCoord = input.TexCoord;
output.Position = mul(input.Position, worldViewProjection);
return output; return output;
} }
@ -171,6 +194,19 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
return output; return output;
} }
VertexShader VSArray[2] =
{
compile vs_3_0 main_vs(),
compile vs_3_0 instanced_vs()
};
int VSIndices[2] =
{
0, 1
};
int VertexShaderIndex = 0;
PixelShader PSArray[8] = PixelShader PSArray[8] =
{ {
compile ps_3_0 NonePS(), compile ps_3_0 NonePS(),
@ -191,13 +227,13 @@ int PSIndices[8] =
0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7
}; };
int ShaderIndex = 0; int PixelShaderIndex = 0;
Technique GBuffer Technique GBuffer
{ {
Pass Pass
{ {
VertexShader = compile vs_3_0 main_vs(); VertexShader = (VSArray[VSIndices[VertexShaderIndex]]);
PixelShader = (PSArray[PSIndices[ShaderIndex]]); PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
} }
} }

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

@ -3,28 +3,28 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
public class LinearDepthEffect : Effect public class LinearDepthEffect : Effect, IHasWorldMatrix
{ {
EffectParameter modelParam; EffectParameter worldParam;
EffectParameter modelViewProjectionParam; EffectParameter worldViewProjectionParam;
EffectParameter lightPositionParam; EffectParameter lightPositionParam;
EffectParameter farPlaneParam; EffectParameter farPlaneParam;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
Matrix model; Matrix world;
Matrix view; Matrix view;
Matrix projection; Matrix projection;
public Vector3 LightPosition { get; set; } public Vector3 LightPosition { get; set; }
public float FarPlane { get; set; } public float FarPlane { get; set; }
public Matrix Model public Matrix World
{ {
get { return model; } get { return world; }
set set
{ {
model = value; world = value;
dirtyFlags |= EffectDirtyFlags.World; dirtyFlags |= EffectDirtyFlags.World;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.WorldViewProj;
} }
@ -60,16 +60,16 @@ namespace Kav
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0)
{ {
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection); Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
Matrix.Multiply(ref model, ref viewProjection, out Matrix worldViewProj); Matrix.Multiply(ref world, ref viewProjection, out Matrix worldViewProj);
modelViewProjectionParam.SetValue(worldViewProj); worldViewProjectionParam.SetValue(worldViewProj);
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
} }
if ((dirtyFlags & EffectDirtyFlags.World) != 0) if ((dirtyFlags & EffectDirtyFlags.World) != 0)
{ {
modelParam.SetValue(model); worldParam.SetValue(world);
dirtyFlags &= ~EffectDirtyFlags.World; dirtyFlags &= ~EffectDirtyFlags.World;
} }
@ -80,8 +80,8 @@ namespace Kav
private void CacheEffectParameters() private void CacheEffectParameters()
{ {
modelParam = Parameters["Model"]; worldParam = Parameters["Model"];
modelViewProjectionParam = Parameters["ModelViewProjection"]; worldViewProjectionParam = Parameters["ModelViewProjection"];
lightPositionParam = Parameters["LightPosition"]; lightPositionParam = Parameters["LightPosition"];
farPlaneParam = Parameters["FarPlane"]; farPlaneParam = Parameters["FarPlane"];

View File

@ -130,7 +130,7 @@ namespace Kav
{ {
albedoTextureParam.SetValue(value); albedoTextureParam.SetValue(value);
albedoTextureEnabled = value != null; albedoTextureEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
@ -141,7 +141,7 @@ namespace Kav
{ {
normalTextureParam.SetValue(value); normalTextureParam.SetValue(value);
normalMapEnabled = value != null; normalMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
@ -164,7 +164,7 @@ namespace Kav
{ {
metallicRoughnessTextureParam.SetValue(value); metallicRoughnessTextureParam.SetValue(value);
metallicRoughnessMapEnabled = value != null; metallicRoughnessMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex; dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
} }
} }
@ -266,7 +266,7 @@ namespace Kav
dirtyFlags &= ~EffectDirtyFlags.EyePosition; dirtyFlags &= ~EffectDirtyFlags.EyePosition;
} }
if ((dirtyFlags & EffectDirtyFlags.ShaderIndex) != 0) if ((dirtyFlags & EffectDirtyFlags.PixelShaderIndex) != 0)
{ {
int shaderIndex = 0; int shaderIndex = 0;
@ -301,7 +301,7 @@ namespace Kav
shaderIndexParam.SetValue(shaderIndex); shaderIndexParam.SetValue(shaderIndex);
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex; dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
} }
} }

View File

@ -3,23 +3,24 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
public class SimpleDepthEffect : Effect public class SimpleDepthEffect : Effect, IHasWorldMatrix
{ {
EffectParameter modelViewProjectionParam; EffectParameter worldParam;
EffectParameter viewProjectionParam;
Matrix model; Matrix world;
Matrix view; Matrix view;
Matrix projection; Matrix projection;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All; EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
public Matrix Model public Matrix World
{ {
get { return model; } get { return world; }
set set
{ {
model = value; world = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.World;
} }
} }
@ -29,7 +30,7 @@ namespace Kav
set set
{ {
view = value; view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.ViewProj;
} }
} }
@ -39,7 +40,7 @@ namespace Kav
set set
{ {
projection = value; projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.ViewProj;
} }
} }
@ -50,20 +51,26 @@ namespace Kav
protected override void OnApply() protected override void OnApply()
{ {
if ((dirtyFlags & EffectDirtyFlags.WorldViewProj) != 0) if ((dirtyFlags & EffectDirtyFlags.World) != 0)
{
worldParam.SetValue(world);
dirtyFlags &= ~EffectDirtyFlags.World;
}
if ((dirtyFlags & EffectDirtyFlags.ViewProj) != 0)
{ {
Matrix.Multiply(ref view, ref projection, out Matrix viewProjection); Matrix.Multiply(ref view, ref projection, out Matrix viewProjection);
Matrix.Multiply(ref model, ref viewProjection, out Matrix worldViewProj); viewProjectionParam.SetValue(viewProjection);
modelViewProjectionParam.SetValue(worldViewProj); dirtyFlags &= ~EffectDirtyFlags.ViewProj;
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
} }
} }
private void CacheEffectParameters() private void CacheEffectParameters()
{ {
modelViewProjectionParam = Parameters["ModelViewProjection"]; worldParam = Parameters["World"];
viewProjectionParam = Parameters["ViewProjection"];
} }
} }
} }

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,16 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public interface IGBufferDrawable
{
Vector3 Albedo { get; }
float Metallic { get; }
float Roughness { get; }
Texture2D AlbedoTexture { get; }
Texture2D NormalTexture { get; }
Texture2D MetallicRoughnessTexture { get; }
}
}

View File

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

View File

@ -0,0 +1,10 @@
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public interface IIndexDrawable
{
VertexBuffer VertexBuffer { get; }
IndexBuffer IndexBuffer { get; }
}
}

View File

@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
public class MeshPart public class MeshPart : IIndexDrawable, IGBufferDrawable, ICullable, IHasVertexPositions
{ {
public IndexBuffer IndexBuffer { get; } public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; } public VertexBuffer VertexBuffer { get; }
@ -11,27 +11,27 @@ namespace Kav
public Vector3[] Positions { get; } public Vector3[] Positions { get; }
public BoundingBox BoundingBox { 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;
public Texture2D AlbedoTexture public Texture2D AlbedoTexture
{ {
get { return DisableAlbedoMap ? null : albedoTexture; } get { return DisableAlbedoMap ? null : albedoTexture; }
set { albedoTexture = value; } set { albedoTexture = value; }
} }
public Texture2D NormalTexture public Texture2D NormalTexture
{ {
get { return DisableNormalMap ? null : normalTexture; } get { return DisableNormalMap ? null : normalTexture; }
set { normalTexture = value; } set { normalTexture = value; }
} }
public Texture2D MetallicRoughnessTexture public Texture2D MetallicRoughnessTexture
{ {
get { return DisableMetallicRoughnessMap ? null : metallicRoughnessTexture; } get { return DisableMetallicRoughnessMap ? null : metallicRoughnessTexture; }
set { metallicRoughnessTexture = value; } set { metallicRoughnessTexture = value; }
} }
public Vector3 Albedo { get; set; } = Vector3.One; public Vector3 Albedo { get; set; } = Vector3.One;

View File

@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
public class MeshSprite : ICullable public class MeshSprite : ICullable, IIndexDrawable
{ {
private static readonly int PixelScale = 40; private static readonly int PixelScale = 40;
private static readonly short[] Indices = new short[] private static readonly short[] Indices = new short[]

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>

File diff suppressed because it is too large Load Diff

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;

12
VertexDeclarations.cs Normal file
View File

@ -0,0 +1,12 @@
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public static class VertexDeclarations
{
public static VertexDeclaration PositionInstanceDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.TextureCoordinate, 2)
);
}
}

View File

@ -0,0 +1,28 @@
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PositionInstanceVertex : IVertexType, IHasTranslation
{
VertexDeclaration IVertexType.VertexDeclaration
{
get
{
return VertexDeclarations.PositionInstanceDeclaration;
}
}
public Vector3 Translation { get; set; }
public static readonly VertexDeclaration VertexDeclaration;
public PositionInstanceVertex(
Vector3 translation
) {
Translation = translation;
}
}
}