instancing + mega refactor #6
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasTranslation
|
||||||
|
{
|
||||||
|
Vector3 Translation { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasWorldMatrix
|
||||||
|
{
|
||||||
|
Matrix World { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
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.
|
@ -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]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"];
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IHasVertexPositions
|
||||||
|
{
|
||||||
|
Vector3[] Positions { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace Kav
|
||||||
|
{
|
||||||
|
public interface IIndexDrawable
|
||||||
|
{
|
||||||
|
VertexBuffer VertexBuffer { get; }
|
||||||
|
IndexBuffer IndexBuffer { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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[]
|
||||||
|
|
|
@ -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>
|
||||||
|
|
1007
Renderer.cs
1007
Renderer.cs
File diff suppressed because it is too large
Load Diff
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;
|
||||||
|
|
|
@ -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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue