started adding support for instanced draws + started decoupling API

instancing
cosmonaut 2020-12-07 01:30:09 -08:00
parent c9a4e35816
commit ee8b0c5ee8
13 changed files with 353 additions and 92 deletions

View File

@ -17,6 +17,7 @@ namespace Kav
EffectParameter metallicParam;
EffectParameter roughnessParam;
EffectParameter vertexShaderIndexParam;
EffectParameter shaderIndexParam;
Matrix world = Matrix.Identity;
@ -30,6 +31,7 @@ namespace Kav
bool albedoTextureEnabled = false;
bool metallicRoughnessMapEnabled = false;
bool normalMapEnabled = false;
bool hardwareInstancingEnabled = false;
EffectDirtyFlags dirtyFlags = EffectDirtyFlags.All;
@ -100,7 +102,7 @@ namespace Kav
{
albedoTextureParam.SetValue(value);
albedoTextureEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
}
}
@ -111,7 +113,7 @@ namespace Kav
{
normalTextureParam.SetValue(value);
normalMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
}
}
@ -122,7 +124,20 @@ namespace Kav
{
metallicRoughnessTextureParam.SetValue(value);
metallicRoughnessMapEnabled = value != null;
dirtyFlags |= EffectDirtyFlags.ShaderIndex;
dirtyFlags |= EffectDirtyFlags.PixelShaderIndex;
}
}
public bool HardwareInstancingEnabled
{
get { return hardwareInstancingEnabled; }
set
{
if (value != hardwareInstancingEnabled)
{
hardwareInstancingEnabled = value;
dirtyFlags |= EffectDirtyFlags.VertexShaderIndex;
}
}
}
@ -175,14 +190,19 @@ namespace Kav
dirtyFlags &= ~EffectDirtyFlags.WorldViewProj;
}
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;
@ -217,7 +237,7 @@ namespace Kav
shaderIndexParam.SetValue(shaderIndex);
dirtyFlags &= ~EffectDirtyFlags.ShaderIndex;
dirtyFlags &= ~EffectDirtyFlags.PixelShaderIndex;
}
}
@ -235,7 +255,8 @@ namespace Kav
metallicParam = Parameters["MetallicValue"];
roughnessParam = Parameters["RoughnessValue"];
shaderIndexParam = Parameters["ShaderIndex"];
shaderIndexParam = Parameters["PixelShaderIndex"];
vertexShaderIndexParam = Parameters["VertexShaderIndex"];
}
}
}

View File

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

View File

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

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

Binary file not shown.

View File

@ -25,6 +25,13 @@ struct VertexInput
float2 TexCoord : TEXCOORD0;
};
struct InstanceInput
{
float4x4 World : TEXCOORD0;
float4x4 WorldInverseTranspose : TEXCOORD1;
float4x4 WorldViewProjection : TEXCOORD2;
};
struct PixelInput
{
float4 Position : SV_POSITION;
@ -55,6 +62,18 @@ PixelInput main_vs(VertexInput input)
return output;
}
PixelInput instanced_vs(VertexInput input, InstanceInput instanceInput)
{
PixelInput output;
output.PositionWorld = mul(input.Position, instanceInput.World).xyz;
output.NormalWorld = mul(input.Normal, (float3x3)instanceInput.WorldInverseTranspose).xyz;
output.TexCoord = input.TexCoord;
output.Position = mul(input.Position, instanceInput.WorldViewProjection);
return output;
}
// Pixel Shaders
// Easy trick to get tangent-normals to world-space to keep PBR code simplified.
@ -171,6 +190,19 @@ PixelOutput AlbedoMetallicRoughnessNormalMapPS(PixelInput input)
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] =
{
compile ps_3_0 NonePS(),
@ -191,13 +223,13 @@ int PSIndices[8] =
0, 1, 2, 3, 4, 5, 6, 7
};
int ShaderIndex = 0;
int PixelShaderIndex = 0;
Technique GBuffer
{
Pass
{
VertexShader = compile vs_3_0 main_vs();
PixelShader = (PSArray[PSIndices[ShaderIndex]]);
VertexShader = (VSArray[VSIndices[VertexShaderIndex]]);
PixelShader = (PSArray[PSIndices[PixelShaderIndex]]);
}
}

View File

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

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

View File

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

View File

@ -8,18 +8,16 @@ namespace Kav
{
public class Renderer
{
private const int MAX_INSTANCE_VERTEX_COUNT = 1000000;
private const int MAX_SHADOW_CASCADES = 4;
private int ShadowMapSize { get; }
private GraphicsDevice GraphicsDevice { get; }
private int RenderDimensionsX { get; }
private int RenderDimensionsY { get; }
private VertexBuffer FullscreenTriangle { get; }
private int NumShadowCascades { get; }
private RenderTarget2D ColorRenderTarget { get; }
private RenderTarget2D DirectionalRenderTarget { get; }
private RenderTarget2D[] ShadowRenderTargets { get; }
private DeferredPBREffect DeferredPBREffect { get; }
@ -35,10 +33,10 @@ namespace Kav
private SkyboxEffect SkyboxEffect { get; }
private DiffuseLitSpriteEffect DiffuseLitSpriteEffect { get; }
private RenderTarget2D gPosition { get; }
private RenderTarget2D gNormal { get; }
private RenderTarget2D gAlbedo { get; }
private RenderTarget2D gMetallicRoughness { get; }
private RenderTarget2D GPosition { get; }
private RenderTarget2D GNormal { get; }
private RenderTarget2D GAlbedo { get; }
private RenderTarget2D GMetallicRoughness { get; }
private RenderTargetCube PointShadowCubeMap { get; }
private RenderTargetBinding[] GBuffer { get; }
@ -47,6 +45,9 @@ namespace Kav
private SpriteBatch SpriteBatch { get; }
private DynamicVertexBuffer GBufferInstanceVertexBuffer { get; }
private readonly GBufferInstanceVertex[] GBufferInstanceVertices = new GBufferInstanceVertex[MAX_INSTANCE_VERTEX_COUNT];
public Renderer(
GraphicsDevice graphicsDevice,
int renderDimensionsX,
@ -55,8 +56,6 @@ namespace Kav
int shadowMapSize
) {
GraphicsDevice = graphicsDevice;
RenderDimensionsX = renderDimensionsX;
RenderDimensionsY = renderDimensionsY;
ShadowMapSize = shadowMapSize;
@ -86,18 +85,7 @@ namespace Kav
RenderTargetUsage.PreserveContents
);
DirectionalRenderTarget = new RenderTarget2D(
graphicsDevice,
renderDimensionsX,
renderDimensionsY,
false,
SurfaceFormat.Color,
DepthFormat.None,
0,
RenderTargetUsage.PreserveContents
);
gPosition = new RenderTarget2D(
GPosition = new RenderTarget2D(
GraphicsDevice,
renderDimensionsX,
renderDimensionsY,
@ -106,7 +94,7 @@ namespace Kav
DepthFormat.Depth24
);
gNormal = new RenderTarget2D(
GNormal = new RenderTarget2D(
GraphicsDevice,
renderDimensionsX,
renderDimensionsY,
@ -115,7 +103,7 @@ namespace Kav
DepthFormat.None
);
gAlbedo = new RenderTarget2D(
GAlbedo = new RenderTarget2D(
GraphicsDevice,
renderDimensionsX,
renderDimensionsY,
@ -124,7 +112,7 @@ namespace Kav
DepthFormat.None
);
gMetallicRoughness = new RenderTarget2D(
GMetallicRoughness = new RenderTarget2D(
GraphicsDevice,
renderDimensionsX,
renderDimensionsY,
@ -134,10 +122,10 @@ namespace Kav
);
GBuffer = new RenderTargetBinding[4] {
new RenderTargetBinding(gPosition),
new RenderTargetBinding(gNormal),
new RenderTargetBinding(gAlbedo),
new RenderTargetBinding(gMetallicRoughness)
new RenderTargetBinding(GPosition),
new RenderTargetBinding(GNormal),
new RenderTargetBinding(GAlbedo),
new RenderTargetBinding(GMetallicRoughness)
};
PointShadowCubeMap = new RenderTargetCube(
@ -175,6 +163,13 @@ namespace Kav
);
SpriteBatch = new SpriteBatch(graphicsDevice);
GBufferInstanceVertexBuffer = new DynamicVertexBuffer(
GraphicsDevice,
VertexDeclarations.GBufferInstanceDeclaration,
MAX_INSTANCE_VERTEX_COUNT,
BufferUsage.WriteOnly
);
}
public void DeferredRender(
@ -185,23 +180,47 @@ namespace Kav
IEnumerable<PointLight> pointLights,
DirectionalLight? directionalLight
) {
GBufferRender(camera, modelTransforms);
GBufferRender(GBuffer, camera, modelTransforms);
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
GraphicsDevice.Clear(Color.Black);
AmbientLightRender(ambientLight);
AmbientLightRender(
ColorRenderTarget,
GPosition,
GAlbedo,
ambientLight
);
DeferredPointLightEffect.EyePosition = camera.Position;
foreach (var pointLight in pointLights)
{
PointLightRender(camera, modelTransforms, pointLight);
PointLightRender(
ColorRenderTarget,
GPosition,
GAlbedo,
GNormal,
GMetallicRoughness,
camera,
modelTransforms,
pointLight
);
}
if (directionalLight.HasValue)
{
DirectionalLightRender(camera, modelTransforms, directionalLight.Value);
DirectionalLightRender(
ColorRenderTarget,
GPosition,
GAlbedo,
GNormal,
GMetallicRoughness,
camera,
modelTransforms,
directionalLight.Value,
NumShadowCascades
);
}
GraphicsDevice.SetRenderTarget(renderTarget);
@ -219,7 +238,7 @@ namespace Kav
DirectionalLight? directionalLight,
TextureCube skybox
) {
GBufferRender(camera, modelTransforms);
GBufferRender(GBuffer, camera, modelTransforms);
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
@ -228,18 +247,44 @@ namespace Kav
DepthRender(camera, modelTransforms);
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
AmbientLightRender(ambientLight);
AmbientLightRender(
ColorRenderTarget,
GPosition,
GAlbedo,
ambientLight
);
foreach (var pointLight in pointLights)
{
PointLightRender(camera, modelTransforms, pointLight);
PointLightRender(
ColorRenderTarget,
GPosition,
GAlbedo,
GNormal,
GMetallicRoughness,
camera,
modelTransforms,
pointLight
);
}
if (directionalLight.HasValue)
{
DirectionalLightToonRender(camera, modelTransforms, directionalLight.Value);
DirectionalLightToonRender(
ColorRenderTarget,
GPosition,
GAlbedo,
GNormal,
GMetallicRoughness,
camera,
modelTransforms,
directionalLight.Value,
NumShadowCascades,
false
);
}
SkyboxRender(camera, skybox);
SkyboxRender(ColorRenderTarget, camera, skybox);
GraphicsDevice.SetRenderTarget(renderTarget);
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, null, null, null, null);
@ -394,9 +439,11 @@ namespace Kav
}
private void SkyboxRender(
RenderTarget2D renderTarget,
PerspectiveCamera camera,
TextureCube skybox
) {
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.RasterizerState.CullMode = CullMode.CullClockwiseFace;
SkyboxEffect.Skybox = skybox;
@ -425,12 +472,68 @@ namespace Kav
GraphicsDevice.RasterizerState.CullMode = CullMode.CullCounterClockwiseFace;
}
private void GBufferRender(
/// <summary>
/// GBuffer binding must have 4 render targets.
/// </summary>
public void InstancedGBufferRender<T>(
RenderTargetBinding[] gBuffer,
PerspectiveCamera camera,
T drawable,
int numInstances,
IEnumerable<Matrix> transforms
) where T : IIndexDrawable, IGBufferDrawable {
GraphicsDevice.SetRenderTargets(gBuffer);
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.Opaque;
Deferred_GBufferEffect.Albedo = drawable.Albedo;
Deferred_GBufferEffect.Metallic = drawable.Metallic;
Deferred_GBufferEffect.Roughness = drawable.Roughness;
Deferred_GBufferEffect.AlbedoTexture = drawable.AlbedoTexture;
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
int i = 0;
foreach (var transform in transforms)
{
if (i >= numInstances) { break; }
GBufferInstanceVertices[i].World = transform;
GBufferInstanceVertices[i].WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(transform));
GBufferInstanceVertices[i].WorldViewProjection = transform * camera.View * camera.Projection;
i += 1;
}
GBufferInstanceVertexBuffer.SetData(
GBufferInstanceVertices,
0,
numInstances,
SetDataOptions.Discard
);
GraphicsDevice.SetVertexBuffers(
drawable.VertexBuffer,
new VertexBufferBinding(GBufferInstanceVertexBuffer, 0, 1)
);
GraphicsDevice.Indices = drawable.IndexBuffer;
GraphicsDevice.DrawInstancedPrimitives(
PrimitiveType.TriangleList,
0,
0,
drawable.VertexBuffer.VertexCount,
0,
drawable.IndexBuffer.IndexCount / 3,
numInstances
);
}
public void GBufferRender(
RenderTargetBinding[] gBuffer,
PerspectiveCamera camera,
IEnumerable<(Model, Matrix)> modelTransforms
) {
GraphicsDevice.SetRenderTargets(GBuffer);
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1f, 0);
GraphicsDevice.SetRenderTargets(gBuffer);
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.Opaque;
@ -475,9 +578,13 @@ namespace Kav
}
}
private void AmbientLightRender(AmbientLight ambientLight)
{
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
public void AmbientLightRender(
RenderTarget2D renderTarget,
Texture2D gPosition,
Texture2D gAlbedo,
AmbientLight ambientLight
) {
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.BlendState = BlendState.Opaque;
DeferredAmbientLightEffect.GPosition = gPosition;
@ -492,14 +599,19 @@ namespace Kav
}
}
private void PointLightRender(
public void PointLightRender(
RenderTarget2D renderTarget,
Texture2D gPosition,
Texture2D gAlbedo,
Texture2D gNormal,
Texture2D gMetallicRoughness,
PerspectiveCamera camera,
IEnumerable<(Model, Matrix)> modelTransforms,
PointLight pointLight
) {
RenderPointShadows(camera, modelTransforms, pointLight);
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
GraphicsDevice.BlendState = BlendState.Additive;
@ -523,28 +635,38 @@ namespace Kav
}
}
private void DirectionalLightRender(
public void DirectionalLightRender(
RenderTarget2D renderTarget,
Texture2D gPosition,
Texture2D gAlbedo,
Texture2D gNormal,
Texture2D gMetallicRoughness,
PerspectiveCamera camera,
IEnumerable<(Model, Matrix)> modelTransforms,
DirectionalLight directionalLight
DirectionalLight directionalLight,
int numShadowCascades
) {
RenderDirectionalShadows(camera, modelTransforms, directionalLight, DeferredDirectionalLightEffect);
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
GraphicsDevice.BlendState = BlendState.Additive;
DeferredDirectionalLightEffect.GPosition = gPosition;
DeferredDirectionalLightEffect.GAlbedo = gAlbedo;
DeferredDirectionalLightEffect.GNormal = gNormal;
DeferredDirectionalLightEffect.GMetallicRoughness = gMetallicRoughness;
DeferredDirectionalLightEffect.ShadowMapOne = ShadowRenderTargets[0];
if (NumShadowCascades > 1)
if (numShadowCascades > 1)
{
DeferredDirectionalLightEffect.ShadowMapTwo = ShadowRenderTargets[1];
}
if (NumShadowCascades > 2)
if (numShadowCascades > 2)
{
DeferredDirectionalLightEffect.ShadowMapThree = ShadowRenderTargets[2];
}
if (NumShadowCascades > 3)
if (numShadowCascades > 3)
{
DeferredDirectionalLightEffect.ShadowMapFour = ShadowRenderTargets[3];
}
@ -556,9 +678,6 @@ namespace Kav
DeferredDirectionalLightEffect.ViewMatrix = camera.View;
DeferredDirectionalLightEffect.EyePosition = camera.Position;
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
GraphicsDevice.BlendState = BlendState.Additive;
foreach (EffectPass pass in DeferredDirectionalLightEffect.CurrentTechnique.Passes)
{
pass.Apply();
@ -568,13 +687,20 @@ namespace Kav
}
private void DirectionalLightToonRender(
RenderTarget2D renderTarget,
Texture2D gPosition,
Texture2D gAlbedo,
Texture2D gNormal,
Texture2D gMetallicRoughness,
PerspectiveCamera camera,
IEnumerable<(Model, Matrix)> modelTransforms,
DirectionalLight directionalLight
DirectionalLight directionalLight,
int numShadowCascades,
bool ditheredShadows
) {
RenderDirectionalShadows(camera, modelTransforms, directionalLight, Deferred_ToonEffect);
GraphicsDevice.SetRenderTarget(ColorRenderTarget);
GraphicsDevice.SetRenderTarget(renderTarget);
GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
GraphicsDevice.BlendState = BlendState.Additive;
@ -583,7 +709,7 @@ namespace Kav
Deferred_ToonEffect.GNormal = gNormal;
Deferred_ToonEffect.GMetallicRoughness = gMetallicRoughness;
Deferred_ToonEffect.DitheredShadows = false;
Deferred_ToonEffect.DitheredShadows = ditheredShadows;
Deferred_ToonEffect.EyePosition = camera.Position;
@ -592,15 +718,15 @@ namespace Kav
directionalLight.Color.ToVector3() * directionalLight.Intensity;
Deferred_ToonEffect.ShadowMapOne = ShadowRenderTargets[0];
if (NumShadowCascades > 1)
if (numShadowCascades > 1)
{
Deferred_ToonEffect.ShadowMapTwo = ShadowRenderTargets[1];
}
if (NumShadowCascades > 2)
if (numShadowCascades > 2)
{
Deferred_ToonEffect.ShadowMapThree = ShadowRenderTargets[2];
}
if (NumShadowCascades > 3)
if (numShadowCascades > 3)
{
Deferred_ToonEffect.ShadowMapFour = ShadowRenderTargets[3];
}

23
VertexDeclarations.cs Normal file
View File

@ -0,0 +1,23 @@
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public static class VertexDeclarations
{
public static VertexDeclaration GBufferInstanceDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 0),
new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1),
new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 2),
new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3),
new VertexElement(64, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4),
new VertexElement(80, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 5),
new VertexElement(96, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 6),
new VertexElement(112, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 7),
new VertexElement(128, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 8),
new VertexElement(144, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 9),
new VertexElement(160, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 10),
new VertexElement(176, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 11)
);
}
}

View File

@ -0,0 +1,32 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Kav
{
public struct GBufferInstanceVertex : IVertexType
{
VertexDeclaration IVertexType.VertexDeclaration
{
get
{
return VertexDeclarations.GBufferInstanceDeclaration;
}
}
public Matrix World { get; set; }
public Matrix WorldInverseTranspose { get; set; }
public Matrix WorldViewProjection { get; set; }
public static readonly VertexDeclaration VertexDeclaration;
public GBufferInstanceVertex(
Matrix world,
Matrix worldInverseTranspose,
Matrix worldViewProjection
) {
World = world;
WorldInverseTranspose = worldInverseTranspose;
WorldViewProjection = worldViewProjection;
}
}
}