trying different shader semantics

instancing
cosmonaut 2020-12-07 13:50:32 -08:00
parent 8b43e8f45e
commit b784f9df4b
8 changed files with 51 additions and 59 deletions

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;
@ -41,7 +40,7 @@ namespace Kav
set set
{ {
world = value; world = value;
dirtyFlags |= EffectDirtyFlags.World | EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.World;
} }
} }
@ -51,7 +50,7 @@ namespace Kav
set set
{ {
view = value; view = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj | EffectDirtyFlags.EyePosition; dirtyFlags |= EffectDirtyFlags.ViewProj | EffectDirtyFlags.EyePosition;
} }
} }
@ -61,7 +60,7 @@ namespace Kav
set set
{ {
projection = value; projection = value;
dirtyFlags |= EffectDirtyFlags.WorldViewProj; dirtyFlags |= EffectDirtyFlags.ViewProj;
} }
} }
@ -174,20 +173,15 @@ 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.VertexShaderIndex) != 0) if ((dirtyFlags & EffectDirtyFlags.VertexShaderIndex) != 0)
@ -244,8 +238,7 @@ namespace Kav
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"];

View File

@ -10,6 +10,7 @@ namespace Kav
EyePosition = 4, EyePosition = 4,
VertexShaderIndex = 8, VertexShaderIndex = 8,
PixelShaderIndex = 16, PixelShaderIndex = 16,
ViewProj = 32,
All = -1 All = -1
} }
} }

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

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,14 +21,12 @@ struct VertexInput
{ {
float4 Position : POSITION; float4 Position : POSITION;
float3 Normal : NORMAL; float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0; float2 TexCoord : TEXCOORD;
}; };
struct InstanceInput struct InstanceInput
{ {
float4x4 World : TEXCOORD0; float4x4 World : COLOR0;
float4x4 WorldInverseTranspose : TEXCOORD1;
float4x4 WorldViewProjection : TEXCOORD2;
}; };
struct PixelInput struct PixelInput
@ -55,9 +52,11 @@ 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; return output;
} }
@ -67,9 +66,11 @@ PixelInput instanced_vs(VertexInput input, InstanceInput instanceInput)
PixelInput output; PixelInput output;
output.PositionWorld = mul(input.Position, instanceInput.World).xyz; 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.TexCoord = input.TexCoord;
output.Position = mul(input.Position, instanceInput.WorldViewProjection);
float4x4 worldViewProjection = mul(World, ViewProjection);
output.Position = mul(input.Position, worldViewProjection);
return output; return output;
} }

View File

@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
public class MeshPart : IIndexDrawable public class MeshPart : IIndexDrawable, IGBufferDrawable
{ {
public IndexBuffer IndexBuffer { get; } public IndexBuffer IndexBuffer { get; }
public VertexBuffer VertexBuffer { get; } public VertexBuffer VertexBuffer { get; }

View File

@ -321,6 +321,8 @@ namespace Kav
GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.BlendState = BlendState.Opaque; GraphicsDevice.BlendState = BlendState.Opaque;
Deferred_GBufferEffect.HardwareInstancingEnabled = true;
Deferred_GBufferEffect.Albedo = drawable.Albedo; Deferred_GBufferEffect.Albedo = drawable.Albedo;
Deferred_GBufferEffect.Metallic = drawable.Metallic; Deferred_GBufferEffect.Metallic = drawable.Metallic;
Deferred_GBufferEffect.Roughness = drawable.Roughness; Deferred_GBufferEffect.Roughness = drawable.Roughness;
@ -329,13 +331,14 @@ namespace Kav
Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture; Deferred_GBufferEffect.NormalTexture = drawable.NormalTexture;
Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture; Deferred_GBufferEffect.MetallicRoughnessTexture = drawable.MetallicRoughnessTexture;
Deferred_GBufferEffect.View = camera.View;
Deferred_GBufferEffect.Projection = camera.Projection;
int i = 0; int i = 0;
foreach (var transform in transforms) foreach (var transform in transforms)
{ {
if (i >= numInstances) { break; } if (i >= numInstances) { break; }
GBufferInstanceVertices[i].World = transform; GBufferInstanceVertices[i].World = transform;
GBufferInstanceVertices[i].WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(transform));
GBufferInstanceVertices[i].WorldViewProjection = transform * camera.View * camera.Projection;
i += 1; i += 1;
} }
@ -352,6 +355,9 @@ namespace Kav
); );
GraphicsDevice.Indices = drawable.IndexBuffer; GraphicsDevice.Indices = drawable.IndexBuffer;
foreach (var pass in Deferred_GBufferEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawInstancedPrimitives( GraphicsDevice.DrawInstancedPrimitives(
PrimitiveType.TriangleList, PrimitiveType.TriangleList,
0, 0,
@ -362,6 +368,7 @@ namespace Kav
numInstances numInstances
); );
} }
}
public void GBufferRender( public void GBufferRender(
RenderTargetBinding[] gBuffer, RenderTargetBinding[] gBuffer,
@ -384,6 +391,8 @@ namespace Kav
Deferred_GBufferEffect.View = camera.View; Deferred_GBufferEffect.View = camera.View;
Deferred_GBufferEffect.Projection = camera.Projection; Deferred_GBufferEffect.Projection = camera.Projection;
Deferred_GBufferEffect.HardwareInstancingEnabled = false;
Deferred_GBufferEffect.Albedo = meshPart.Albedo; Deferred_GBufferEffect.Albedo = meshPart.Albedo;
Deferred_GBufferEffect.Metallic = meshPart.Metallic; Deferred_GBufferEffect.Metallic = meshPart.Metallic;
Deferred_GBufferEffect.Roughness = meshPart.Roughness; Deferred_GBufferEffect.Roughness = meshPart.Roughness;

View File

@ -6,18 +6,10 @@ namespace Kav
{ {
public static VertexDeclaration GBufferInstanceDeclaration = new VertexDeclaration public static VertexDeclaration GBufferInstanceDeclaration = new VertexDeclaration
( (
new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 0), new VertexElement(0, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 0),
new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 1), new VertexElement(16, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 1),
new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 2), new VertexElement(32, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 2),
new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3), new VertexElement(48, VertexElementFormat.HalfVector4, VertexElementUsage.Color, 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

@ -1,8 +1,10 @@
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
namespace Kav namespace Kav
{ {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct GBufferInstanceVertex : IVertexType public struct GBufferInstanceVertex : IVertexType
{ {
VertexDeclaration IVertexType.VertexDeclaration VertexDeclaration IVertexType.VertexDeclaration
@ -14,19 +16,13 @@ namespace Kav
} }
public Matrix World { get; set; } public Matrix World { get; set; }
public Matrix WorldInverseTranspose { get; set; }
public Matrix WorldViewProjection { get; set; }
public static readonly VertexDeclaration VertexDeclaration; public static readonly VertexDeclaration VertexDeclaration;
public GBufferInstanceVertex( public GBufferInstanceVertex(
Matrix world, Matrix world
Matrix worldInverseTranspose,
Matrix worldViewProjection
) { ) {
World = world; World = world;
WorldInverseTranspose = worldInverseTranspose;
WorldViewProjection = worldViewProjection;
} }
} }
} }