diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj
index 5dc55ff..2af5424 100644
--- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj
+++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj
@@ -392,6 +392,16 @@
Pixel
4.0
+
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+
Vertex
4.0
@@ -434,6 +444,16 @@
Vertex
4.0
+
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+ Pixel
+ 4.1
+
Pixel
4.0
diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters
index 424bf17..b6bf4d5 100644
--- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters
+++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters
@@ -262,6 +262,12 @@
Lights
+
+ Lights
+
+
+ Lights
+
diff --git a/CodeWalker.Shaders/DirLightPS_MS.hlsl b/CodeWalker.Shaders/DirLightPS_MS.hlsl
new file mode 100644
index 0000000..1beb390
--- /dev/null
+++ b/CodeWalker.Shaders/DirLightPS_MS.hlsl
@@ -0,0 +1,66 @@
+#include "LightPS.hlsli"
+
+
+Texture2DMS DepthTex : register(t0);
+Texture2DMS DiffuseTex : register(t2);
+Texture2DMS NormalTex : register(t3);
+Texture2DMS SpecularTex : register(t4);
+Texture2DMS IrradianceTex : register(t5);
+
+struct VS_Output
+{
+ float4 Pos : SV_POSITION;
+ float4 Screen : TEXCOORD0;
+};
+
+PS_OUTPUT main(VS_Output input)
+{
+
+ //switch (RenderMode)
+ //{
+ // case 5: c += diffuse.rgb; break;
+ // case 6: c += normal.rgb; break;
+ // case 7: c += specular.rgb; break;
+ //}
+
+ uint2 ssloc = uint2(input.Pos.xy); //pixel location
+ float2 spos = float2(input.Screen.xy / input.Screen.w);
+ float3 c = 0;
+ float d = 0;
+ float a = 0;
+ int sc = min(SampleCount, 8);
+
+ [unroll]
+ for (int i = 0; i < sc; i++)
+ {
+ float depth = DepthTex.Load(ssloc, i);
+ if (depth == 0) continue; //no existing subpixel rendered here
+
+ float4 diffuse = DiffuseTex.Load(ssloc, i);
+ float4 normal = NormalTex.Load(ssloc, i);
+ float4 specular = SpecularTex.Load(ssloc, i);
+ float4 irradiance = IrradianceTex.Load(ssloc, i);
+
+ float4 cpos = mul(float4(spos, depth, 1), ViewProjInv);
+ float3 camRel = cpos.xyz * (1 / cpos.w);
+ float3 norm = normal.xyz * 2 - 1;
+
+ float3 colour = DeferredDirectionalLight(camRel, norm, diffuse, specular, irradiance);
+
+ c += colour;
+ d += depth;
+ a += 1;
+ }
+
+ c *= SampleMult;
+ d *= SampleMult;
+ a *= SampleMult;
+
+ if (d <= 0) discard;
+
+ PS_OUTPUT output;
+ output.Colour = float4(c, a);
+ output.Depth = d;
+ return output;
+}
+
diff --git a/CodeWalker.Shaders/LightPS.hlsli b/CodeWalker.Shaders/LightPS.hlsli
index 1336438..7bb7002 100644
--- a/CodeWalker.Shaders/LightPS.hlsli
+++ b/CodeWalker.Shaders/LightPS.hlsli
@@ -18,8 +18,8 @@ cbuffer PSLightVars : register(b0)
uint RenderSamplerCoord;
uint LightType; //0=directional, 1=Point, 2=Spot, 4=Capsule
uint IsLOD; //useful or not?
- uint Pad0;
- uint Pad1;
+ uint SampleCount;//for MSAA
+ float SampleMult;//for MSAA
}
diff --git a/CodeWalker.Shaders/LodLightsPS_MS.hlsl b/CodeWalker.Shaders/LodLightsPS_MS.hlsl
new file mode 100644
index 0000000..cb7d0f8
--- /dev/null
+++ b/CodeWalker.Shaders/LodLightsPS_MS.hlsl
@@ -0,0 +1,53 @@
+#include "LightPS.hlsli"
+
+
+Texture2DMS DepthTex : register(t0);
+Texture2DMS DiffuseTex : register(t2);
+Texture2DMS NormalTex : register(t3);
+Texture2DMS SpecularTex : register(t4);
+Texture2DMS IrradianceTex : register(t5);
+
+struct VS_Output
+{
+ float4 Pos : SV_POSITION;
+ float4 Screen : TEXCOORD0;
+ uint IID : SV_INSTANCEID;
+};
+
+float4 main(VS_Output input) : SV_TARGET
+{
+ uint2 ssloc = uint2(input.Pos.xy); //pixel location
+ float2 spos = float2(input.Screen.xy / input.Screen.w);
+ float4 c = 0;
+ float d = 0;
+ int sc = min(SampleCount, 8);
+
+ [unroll]
+ for (int i = 0; i < sc; i++)
+ {
+ float depth = DepthTex.Load(ssloc, i);
+ if (depth == 0) continue; //no existing subpixel rendered here
+
+ float4 diffuse = DiffuseTex.Load(ssloc, i);
+ float4 normal = NormalTex.Load(ssloc, i);
+ float4 specular = SpecularTex.Load(ssloc, i);
+ float4 irradiance = IrradianceTex.Load(ssloc, i);
+
+ float4 cpos = mul(float4(spos, depth, 1), ViewProjInv);
+ float3 camRel = cpos.xyz * (1 / cpos.w);
+ float3 norm = normal.xyz * 2 - 1;
+
+ float4 colour = DeferredLODLight(camRel, norm, diffuse, specular, irradiance, input.IID);
+
+ c += colour;
+ d += depth;
+ }
+
+ c *= SampleMult;
+ d *= SampleMult;
+
+ if (d <= 0) discard;
+
+ return c;
+}
+
diff --git a/Rendering/DirectX/DXManager.cs b/Rendering/DirectX/DXManager.cs
index bc099af..b3ca953 100644
--- a/Rendering/DirectX/DXManager.cs
+++ b/Rendering/DirectX/DXManager.cs
@@ -63,7 +63,7 @@ namespace CodeWalker.Rendering
Usage = Usage.RenderTargetOutput
};
- FeatureLevel[] levels = new FeatureLevel[] { FeatureLevel.Level_10_0 };
+ FeatureLevel[] levels = new FeatureLevel[] { FeatureLevel.Level_11_0, FeatureLevel.Level_10_1, FeatureLevel.Level_10_0 };
DeviceCreationFlags flags = DeviceCreationFlags.None;
//#if DEBUG
diff --git a/Rendering/DirectX/DXUtility.cs b/Rendering/DirectX/DXUtility.cs
index 0b4dec7..7480147 100644
--- a/Rendering/DirectX/DXUtility.cs
+++ b/Rendering/DirectX/DXUtility.cs
@@ -132,6 +132,10 @@ namespace CodeWalker.Rendering
srvd.Texture3D.MipLevels = mipLevels;
srvd.Texture3D.MostDetailedMip = mostDetailedMip;
break;
+ case ShaderResourceViewDimension.Texture2DMultisampled:
+ case ShaderResourceViewDimension.Texture2DMultisampledArray:
+ //nothing to do here
+ break;
default:
throw new Exception(); //not implemented....
}
diff --git a/Rendering/Shaders/DeferredScene.cs b/Rendering/Shaders/DeferredScene.cs
index 48574ba..92b8b3e 100644
--- a/Rendering/Shaders/DeferredScene.cs
+++ b/Rendering/Shaders/DeferredScene.cs
@@ -37,8 +37,8 @@ namespace CodeWalker.Rendering
public uint RenderSamplerCoord; //which texcoord to use in single texture mode
public uint LightType; //0=directional, 1=Point, 2=Spot, 4=Capsule
public uint IsLOD; //useful or not?
- public uint Pad0;
- public uint Pad1;
+ public uint SampleCount;//for MSAA
+ public float SampleMult;//for MSAA
}
public struct DeferredSSAAPSVars
@@ -66,8 +66,10 @@ namespace CodeWalker.Rendering
VertexShader DirLightVS;
PixelShader DirLightPS;
+ PixelShader DirLightMSPS;
VertexShader LodLightVS;
PixelShader LodLightPS;
+ PixelShader LodLightMSPS;
UnitCone LightCone;
UnitSphere LightSphere;
UnitCapsule LightCapsule;
@@ -86,6 +88,11 @@ namespace CodeWalker.Rendering
public int SSAASampleCount = 1;
+ public int MSAASampleCount = 4;
+
+
+
+
public long VramUsage
{
get
@@ -102,8 +109,10 @@ namespace CodeWalker.Rendering
byte[] bDirLightVS = File.ReadAllBytes("Shaders\\DirLightVS.cso");
byte[] bDirLightPS = File.ReadAllBytes("Shaders\\DirLightPS.cso");
+ byte[] bDirLightMSPS = File.ReadAllBytes("Shaders\\DirLightPS_MS.cso");
byte[] bLodLightVS = File.ReadAllBytes("Shaders\\LodLightsVS.cso");
byte[] bLodLightPS = File.ReadAllBytes("Shaders\\LodLightsPS.cso");
+ byte[] bLodLightMSPS = File.ReadAllBytes("Shaders\\LodLightsPS_MS.cso");
byte[] bFinalVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso");
byte[] bSSAAPS = File.ReadAllBytes("Shaders\\PPSSAAPS.cso");
@@ -111,6 +120,19 @@ namespace CodeWalker.Rendering
DirLightPS = new PixelShader(device, bDirLightPS);
LodLightVS = new VertexShader(device, bLodLightVS);
LodLightPS = new PixelShader(device, bLodLightPS);
+
+ try
+ {
+ //error could happen here if the device isn't supporting feature level 10.1
+ DirLightMSPS = new PixelShader(device, bDirLightMSPS);
+ LodLightMSPS = new PixelShader(device, bLodLightMSPS);
+ }
+ catch
+ {
+ MSAASampleCount = 1; //can't do MSAA without at least 10.1 support
+ }
+
+
LightCone = new UnitCone(device, bLodLightVS, 4, false);
LightSphere = new UnitSphere(device, bLodLightVS, 4, true);
LightCapsule = new UnitCapsule(device, bLodLightVS, 4, false);
@@ -198,6 +220,11 @@ namespace CodeWalker.Rendering
DirLightPS.Dispose();
DirLightPS = null;
}
+ if (DirLightMSPS != null)
+ {
+ DirLightMSPS.Dispose();
+ DirLightMSPS = null;
+ }
if (DirLightVS != null)
{
DirLightVS.Dispose();
@@ -208,6 +235,11 @@ namespace CodeWalker.Rendering
LodLightPS.Dispose();
LodLightPS = null;
}
+ if (LodLightMSPS != null)
+ {
+ LodLightMSPS.Dispose();
+ LodLightMSPS = null;
+ }
if (LodLightVS != null)
{
LodLightVS.Dispose();
@@ -249,7 +281,7 @@ namespace CodeWalker.Rendering
Viewport.Y = 0.0f;
- GBuffers = new GpuMultiTexture(device, uw, uh, 4, Format.R8G8B8A8_UNorm, true, Format.D32_Float);
+ GBuffers = new GpuMultiTexture(device, uw, uh, 4, Format.R8G8B8A8_UNorm, true, Format.D32_Float, MSAASampleCount);
WindowSizeVramUsage += GBuffers.VramUsage;
SceneColour = new GpuTexture(device, uw, uh, Format.R32G32B32A32_Float, 1, 0, true, Format.D32_Float);
@@ -293,18 +325,18 @@ namespace CodeWalker.Rendering
public void RenderLights(DeviceContext context, Camera camera, Shadowmap globalShadows, ShaderGlobalLights globalLights)
{
- uint rendermode = 0;
- uint rendermodeind = 1;
//first full-screen directional light pass, for sun/moon
//discard pixels where scene depth is 0, since nothing was rendered there
//blend mode: overwrite
- context.VertexShader.Set(DirLightVS);
- context.PixelShader.Set(DirLightPS);
+ var ps = (MSAASampleCount > 1) ? DirLightMSPS : DirLightPS;
- LightVSVars.Vars.ViewProj = Matrix.Identity; //Matrix.Transpose(camera.ViewProjMatrix);
- LightVSVars.Vars.CameraPos = Vector4.Zero; //new Vector4(camera.Position, 0.0f);
+ context.VertexShader.Set(DirLightVS);
+ context.PixelShader.Set(ps);
+
+ LightVSVars.Vars.ViewProj = Matrix.Identity;
+ LightVSVars.Vars.CameraPos = Vector4.Zero;
LightVSVars.Vars.LightType = 0;
LightVSVars.Vars.IsLOD = 0;
LightVSVars.Vars.Pad0 = 0;
@@ -314,15 +346,15 @@ namespace CodeWalker.Rendering
LightPSVars.Vars.GlobalLights = globalLights.Params;
LightPSVars.Vars.ViewProjInv = Matrix.Transpose(camera.ViewProjInvMatrix);
- LightPSVars.Vars.CameraPos = Vector4.Zero; //new Vector4(camera.Position, 0.0f);
+ LightPSVars.Vars.CameraPos = Vector4.Zero;
LightPSVars.Vars.EnableShadows = (globalShadows != null) ? 1u : 0u;
- LightPSVars.Vars.RenderMode = rendermode;
- LightPSVars.Vars.RenderModeIndex = rendermodeind;
- LightPSVars.Vars.RenderSamplerCoord = 0;// (uint)RenderTextureSamplerCoord;
+ LightPSVars.Vars.RenderMode = 0;
+ LightPSVars.Vars.RenderModeIndex = 1;
+ LightPSVars.Vars.RenderSamplerCoord = 0;
LightPSVars.Vars.LightType = 0;
LightPSVars.Vars.IsLOD = 0;
- LightPSVars.Vars.Pad0 = 0;
- LightPSVars.Vars.Pad1 = 0;
+ LightPSVars.Vars.SampleCount = (uint)MSAASampleCount;
+ LightPSVars.Vars.SampleMult = 1.0f / MSAASampleCount;
LightPSVars.Update(context);
LightPSVars.SetPSCBuffer(context, 0);
@@ -350,9 +382,10 @@ namespace CodeWalker.Rendering
//instanced rendering of all other lights, using appropriate shapes
//blend mode: additive
+ var ps = (MSAASampleCount > 1) ? LodLightMSPS : LodLightPS;
context.VertexShader.Set(LodLightVS);
- context.PixelShader.Set(LodLightPS);
+ context.PixelShader.Set(ps);
LightVSVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
LightVSVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
@@ -361,26 +394,20 @@ namespace CodeWalker.Rendering
LightVSVars.Vars.Pad0 = 0;
LightVSVars.Vars.Pad1 = 0;
- //LightPSVars.Vars.GlobalLights = globalLights.Params;
LightPSVars.Vars.ViewProjInv = Matrix.Transpose(camera.ViewProjInvMatrix);
LightPSVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
- LightPSVars.Vars.EnableShadows = 0;// (globalShadows != null) ? 1u : 0u;
- LightPSVars.Vars.RenderMode = 0;// rendermode;
- LightPSVars.Vars.RenderModeIndex = 1;// rendermodeind;
- LightPSVars.Vars.RenderSamplerCoord = 0;// (uint)RenderTextureSamplerCoord;
+ LightPSVars.Vars.EnableShadows = 0;
+ LightPSVars.Vars.RenderMode = 0;
+ LightPSVars.Vars.RenderModeIndex = 1;
+ LightPSVars.Vars.RenderSamplerCoord = 0;
LightPSVars.Vars.LightType = 0;
LightPSVars.Vars.IsLOD = 0;
- LightPSVars.Vars.Pad0 = 0;
- LightPSVars.Vars.Pad1 = 0;
+ LightPSVars.Vars.SampleCount = (uint)MSAASampleCount;
+ LightPSVars.Vars.SampleMult = 1.0f / MSAASampleCount;
context.PixelShader.SetShaderResources(0, GBuffers.DepthSRV);
context.PixelShader.SetShaderResources(2, GBuffers.SRVs);
- //if (globalShadows != null)
- //{
- // globalShadows.SetFinalRenderResources(context);
- //}
-
foreach (var rll in lodlights)
{
@@ -427,10 +454,6 @@ namespace CodeWalker.Rendering
context.PixelShader.Set(null);
context.PixelShader.SetShaderResources(0, null, null, null);
context.PixelShader.SetSamplers(0, null, null);
-
-
-
-
}
diff --git a/Rendering/Utils/GpuBuffers.cs b/Rendering/Utils/GpuBuffers.cs
index d67cf32..6f3b462 100644
--- a/Rendering/Utils/GpuBuffers.cs
+++ b/Rendering/Utils/GpuBuffers.cs
@@ -293,13 +293,13 @@ namespace CodeWalker.Rendering
TextureMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, sc, sq, u, b, 0, 0);
MSRTV = DXUtility.CreateRenderTargetView(device, TextureMS, f, rtvd, 0, 0, 0);
- VramUsage += (wh * fs);
+ VramUsage += (wh * fs) * sc;
if (depth)
{
DepthMS = DXUtility.CreateTexture2D(device, w, h, 1, 1, df, sc, sq, u, db, 0, 0);
MSDSV = DXUtility.CreateDepthStencilView(device, DepthMS, df, dsvd);
- VramUsage += (wh * DXUtility.ElementSize(df));
+ VramUsage += (wh * DXUtility.ElementSize(df)) * sc;
}
}
else
@@ -432,31 +432,42 @@ namespace CodeWalker.Rendering
public int VramUsage;
public bool UseDepth;
public int Count;
+ public bool Multisampled;
+ public int MultisampleCount;
- public void Init(Device device, int w, int h, int count, Format f, bool depth, Format df)
+ public void Init(Device device, int w, int h, int count, Format f, bool depth, Format df, int multisamplecount)
{
Count = count;
VramUsage = 0;
UseDepth = depth;
+ MultisampleCount = multisamplecount;
+ Multisampled = (multisamplecount > 1);
ResourceUsage u = ResourceUsage.Default;
BindFlags b = BindFlags.RenderTarget | BindFlags.ShaderResource;
- RenderTargetViewDimension rtvd = RenderTargetViewDimension.Texture2D;
- ShaderResourceViewDimension srvd = ShaderResourceViewDimension.Texture2D;// D3D11_SRV_DIMENSION_TEXTURE2D;
int fs = DXUtility.ElementSize(f);
int wh = w * h;
BindFlags db = BindFlags.DepthStencil | BindFlags.ShaderResource;// D3D11_BIND_DEPTH_STENCIL;
+ RenderTargetViewDimension rtvd = RenderTargetViewDimension.Texture2D;
+ ShaderResourceViewDimension srvd = ShaderResourceViewDimension.Texture2D;// D3D11_SRV_DIMENSION_TEXTURE2D;
DepthStencilViewDimension dsvd = DepthStencilViewDimension.Texture2D;
+ if (Multisampled)
+ {
+ rtvd = RenderTargetViewDimension.Texture2DMultisampled;
+ srvd = ShaderResourceViewDimension.Texture2DMultisampled;
+ dsvd = DepthStencilViewDimension.Texture2DMultisampled;
+ }
+
Textures = new Texture2D[count];
RTVs = new RenderTargetView[count];
SRVs = new ShaderResourceView[count];
for (int i = 0; i < count; i++)
{
- Textures[i] = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, 1, 0, u, b, 0, 0);
+ Textures[i] = DXUtility.CreateTexture2D(device, w, h, 1, 1, f, multisamplecount, 0, u, b, 0, 0);
RTVs[i] = DXUtility.CreateRenderTargetView(device, Textures[i], f, rtvd, 0, 0, 0);
SRVs[i] = DXUtility.CreateShaderResourceView(device, Textures[i], f, srvd, 1, 0, 0, 0);
- VramUsage += (wh * fs);
+ VramUsage += (wh * fs) * multisamplecount;
}
if (depth)
{
@@ -482,10 +493,10 @@ namespace CodeWalker.Rendering
break;
}
- Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, 1, 0, u, db, 0, 0);
+ Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, multisamplecount, 0, u, db, 0, 0);
DSV = DXUtility.CreateDepthStencilView(device, Depth, df, dsvd);
DepthSRV = DXUtility.CreateShaderResourceView(device, Depth, dsrvf, srvd, 1, 0, 0, 0);
- VramUsage += (wh * DXUtility.ElementSize(df));
+ VramUsage += (wh * DXUtility.ElementSize(df)) * multisamplecount;
}
}
public void Dispose()
@@ -516,13 +527,13 @@ namespace CodeWalker.Rendering
Depth = null;
}
}
- public GpuMultiTexture(Device device, int w, int h, int count, Format f, bool depth, Format df)
+ public GpuMultiTexture(Device device, int w, int h, int count, Format f, bool depth, Format df, int msc = 1)
{
- Init(device, w, h, count, f, depth, df);
+ Init(device, w, h, count, f, depth, df, msc);
}
- public GpuMultiTexture(Device device, int w, int h, int count, Format f)
+ public GpuMultiTexture(Device device, int w, int h, int count, Format f, int msc = 1)
{
- Init(device, w, h, count, f, false, Format.Unknown);
+ Init(device, w, h, count, f, false, Format.Unknown, msc);
}
public void Clear(DeviceContext context, Color4 colour)
diff --git a/Shaders/DirLightPS.cso b/Shaders/DirLightPS.cso
index ff652f9..4706947 100644
Binary files a/Shaders/DirLightPS.cso and b/Shaders/DirLightPS.cso differ
diff --git a/Shaders/DirLightPS_MS.cso b/Shaders/DirLightPS_MS.cso
new file mode 100644
index 0000000..240b300
Binary files /dev/null and b/Shaders/DirLightPS_MS.cso differ
diff --git a/Shaders/LightPS.cso b/Shaders/LightPS.cso
index 2a4eb4a..b92ff1a 100644
Binary files a/Shaders/LightPS.cso and b/Shaders/LightPS.cso differ
diff --git a/Shaders/LodLightsPS.cso b/Shaders/LodLightsPS.cso
index 905872e..b95822b 100644
Binary files a/Shaders/LodLightsPS.cso and b/Shaders/LodLightsPS.cso differ
diff --git a/Shaders/LodLightsPS_MS.cso b/Shaders/LodLightsPS_MS.cso
new file mode 100644
index 0000000..5e54009
Binary files /dev/null and b/Shaders/LodLightsPS_MS.cso differ