diff --git a/Effects/DeferredPBR_GBufferEffect.cs b/Effects/DeferredPBR_GBufferEffect.cs index b7eeb65..335a592 100644 --- a/Effects/DeferredPBR_GBufferEffect.cs +++ b/Effects/DeferredPBR_GBufferEffect.cs @@ -6,8 +6,7 @@ namespace Kav public class DeferredPBR_GBufferEffect : Effect, TransformEffect { EffectParameter worldParam; - EffectParameter worldViewProjectionParam; - EffectParameter worldInverseTransposeParam; + EffectParameter viewProjectionParam; EffectParameter albedoTextureParam; EffectParameter normalTextureParam; @@ -41,7 +40,7 @@ namespace Kav set { world = value; - dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj; + dirtyFlags |= EffectDirtyFlags.World; } } @@ -51,7 +50,7 @@ namespace Kav set { view = value; - dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition; + dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition; } } @@ -61,7 +60,7 @@ namespace Kav set { projection = value; - dirtyFlags |= EffectDirtyFlags.WorldViewProj; + dirtyFlags |= EffectDirtyFlags.ViewProj; } } @@ -174,20 +173,15 @@ namespace Kav { worldParam.SetValue(world); - Matrix.Invert(ref world, out Matrix worldInverse); - Matrix.Transpose(ref worldInverse, out Matrix worldInverseTranspose); - worldInverseTransposeParam.SetValue(worldInverseTranspose); - 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 worldView, ref projection, out Matrix worldViewProj); - worldViewProjectionParam.SetValue(worldViewProj); + Matrix.Multiply(ref view, ref projection, out Matrix viewProj); + viewProjectionParam.SetValue(viewProj); - dirtyFlags &= ~EffectDirtyFlags.WorldViewProj; + dirtyFlags &= ~EffectDirtyFlags.ViewProj; } if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0) @@ -244,8 +238,7 @@ namespace Kav void CacheEffectParameters() { worldParam = Parameters["World"]; - worldViewProjectionParam = Parameters["WorldViewProjection"]; - worldInverseTransposeParam = Parameters["WorldInverseTranspose"]; + viewProjectionParam = Parameters["ViewProjection"]; albedoTextureParam = Parameters["AlbedoTexture"]; normalTextureParam = Parameters["NormalTexture"]; diff --git a/Effects/EffectHelpers.cs b/Effects/EffectHelpers.cs index c20bfcd..56a0cec 100644 --- a/Effects/EffectHelpers.cs +++ b/Effects/EffectHelpers.cs @@ -10,6 +10,7 @@ namespace Kav EyePosition = 4, VertexShaderIndex = 8, PixelShaderIndex = 16, + ViewProj = 32, All = -1 } } diff --git a/Effects/FXB/DeferredPBR_GBufferEffect.fxb b/Effects/FXB/DeferredPBR_GBufferEffect.fxb index 6199ff0..5c38c1e 100644 --- a/Effects/FXB/DeferredPBR_GBufferEffect.fxb +++ b/Effects/FXB/DeferredPBR_GBufferEffect.fxb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14ff7607c5d2f267e84e5e68bb2d1d10f0191f63325f0bb3f9c320f566807f35 -size 8492 +oid sha256:a0fde33abf96c838d507d637922e614e8490f41b700846c87f5d344e14699959 +size 9228 diff --git a/Effects/HLSL/DeferredPBR_GBufferEffect.fx b/Effects/HLSL/DeferredPBR_GBufferEffect.fx index f5322d2..328ad7c 100644 --- a/Effects/HLSL/DeferredPBR_GBufferEffect.fx +++ b/Effects/HLSL/DeferredPBR_GBufferEffect.fx @@ -13,8 +13,7 @@ BEGIN_CONSTANTS MATRIX_CONSTANTS float4x4 World _vs(c0) _cb(c7); - float4x4 WorldInverseTranspose _vs(c4) _cb(c11); - float4x4 WorldViewProjection _vs(c8) _cb(c15); + float4x4 ViewProjection _vs(c4) _cb(c11); END_CONSTANTS @@ -22,14 +21,12 @@ struct VertexInput { float4 Position : POSITION; float3 Normal : NORMAL; - float2 TexCoord : TEXCOORD0; + float2 TexCoord : TEXCOORD; }; struct InstanceInput { - float4x4 World : TEXCOORD0; - float4x4 WorldInverseTranspose : TEXCOORD1; - float4x4 WorldViewProjection : TEXCOORD2; + float4x4 World : COLOR0; }; struct PixelInput @@ -55,9 +52,11 @@ PixelInput main_vs(VertexInput input) PixelInput output; 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.Position = mul(input.Position, WorldViewProjection); + + float4x4 worldViewProjection = mul(World, ViewProjection); + output.Position = mul(input.Position, worldViewProjection); return output; } @@ -67,9 +66,11 @@ 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.NormalWorld = normalize(mul(input.Normal, instanceInput.World)); output.TexCoord = input.TexCoord; - output.Position = mul(input.Position, instanceInput.WorldViewProjection); + + float4x4 worldViewProjection = mul(World, ViewProjection); + output.Position = mul(input.Position, worldViewProjection); return output; } diff --git a/Geometry/MeshPart.cs b/Geometry/MeshPart.cs index 2a669eb..f2eac05 100644 --- a/Geometry/MeshPart.cs +++ b/Geometry/MeshPart.cs @@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics; namespace Kav { - public class MeshPart : IIndexDrawable + public class MeshPart : IIndexDrawable, IGBufferDrawable { public IndexBuffer IndexBuffer { get; } public VertexBuffer VertexBuffer { get; } diff --git a/Renderer.cs b/Renderer.cs index fa36434..ccdef63 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -321,6 +321,8 @@ namespace Kav GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; + Deferred_GBufferEffect.HardwareInstancingEnabled = true; + Deferred_GBufferEffect.Albedo = drawable.Albedo; Deferred_GBufferEffect.Metallic = drawable.Metallic; Deferred_GBufferEffect.Roughness = drawable.Roughness; @@ -329,13 +331,14 @@ namespace Kav Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture; Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture; + Deferred_GBufferEffect.View = camera.View; + Deferred_GBufferEffect.Projection = camera.Projection; + 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; } @@ -352,15 +355,19 @@ namespace Kav ); GraphicsDevice.Indices = drawable.IndexBuffer; - GraphicsDevice.DrawInstancedPrimitives( - PrimitiveType.TriangleList, - 0, - 0, - drawable.VertexBuffer.VertexCount, - 0, - drawable.IndexBuffer.IndexCount / 3, - numInstances - ); + foreach (var pass in Deferred_GBufferEffect.CurrentTechnique.Passes) + { + pass.Apply(); + GraphicsDevice.DrawInstancedPrimitives( + PrimitiveType.TriangleList, + 0, + 0, + drawable.VertexBuffer.VertexCount, + 0, + drawable.IndexBuffer.IndexCount / 3, + numInstances + ); + } } public void GBufferRender( @@ -384,6 +391,8 @@ namespace Kav Deferred_GBufferEffect.View = camera.View; Deferred_GBufferEffect.Projection = camera.Projection; + Deferred_GBufferEffect.HardwareInstancingEnabled = false; + Deferred_GBufferEffect.Albedo = meshPart.Albedo; Deferred_GBufferEffect.Metallic = meshPart.Metallic; Deferred_GBufferEffect.Roughness = meshPart.Roughness; diff --git a/VertexDeclarations.cs b/VertexDeclarations.cs index a12b2f8..1e8b869 100644 --- a/VertexDeclarations.cs +++ b/VertexDeclarations.cs @@ -6,18 +6,10 @@ namespace Kav { 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) + new VertexElement(0, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 0), + new VertexElement(16, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 1), + new VertexElement(32, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 2), + new VertexElement(48, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 3) ); } } diff --git a/Vertices/GBufferInstanceVertex.cs b/Vertices/GBufferInstanceVertex.cs index 63e8d1e..329c8e9 100644 --- a/Vertices/GBufferInstanceVertex.cs +++ b/Vertices/GBufferInstanceVertex.cs @@ -1,8 +1,10 @@ +using System.Runtime.InteropServices; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace Kav { + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GBufferInstanceVertex : IVertexType { VertexDeclaration IVertexType.VertexDeclaration @@ -14,19 +16,13 @@ namespace Kav } 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 + Matrix world ) { World = world; - WorldInverseTranspose = worldInverseTranspose; - WorldViewProjection = worldViewProjection; } } }