diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj index 6c40aed..f4d2244 100644 --- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj +++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj @@ -504,6 +504,16 @@ Compute 4.0 + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Compute 4.0 diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters index ba0924b..3ad638c 100644 --- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters +++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters @@ -247,6 +247,9 @@ Lights + + PostProcessor + diff --git a/CodeWalker.Shaders/PPMSAAPS.hlsl b/CodeWalker.Shaders/PPMSAAPS.hlsl new file mode 100644 index 0000000..8dab5bc --- /dev/null +++ b/CodeWalker.Shaders/PPMSAAPS.hlsl @@ -0,0 +1,41 @@ + +struct VS_Output +{ + float4 Pos : SV_POSITION; + float2 Tex : TEXCOORD0; +}; + + +Texture2D SceneColour : register(t0); +SamplerState PointSampler : register(s0); + + +cbuffer cbPS : register(b0) +{ + uint SampleCount; + float SampleMult; + float TexelSizeX; + float TexelSizeY; +}; + +float4 main(VS_Output input) : SV_TARGET +{ + float4 vColor = 0; + + float2 ts = float2(TexelSizeX, TexelSizeY); + float2 tc = input.Tex * (1.0 - (ts * (float) (SampleCount - 1))); + + for (uint x = 0; x < SampleCount; x++) + { + for (uint y = 0; y < SampleCount; y++) + { + float2 tcxy = tc + float2(x, y) * ts; + vColor += SceneColour.Sample(PointSampler, tcxy); + } + } + + vColor *= SampleMult; + + return float4(vColor.rgb, 1); +} + diff --git a/Rendering/ShaderManager.cs b/Rendering/ShaderManager.cs index 6d51b34..a812b51 100644 --- a/Rendering/ShaderManager.cs +++ b/Rendering/ShaderManager.cs @@ -335,11 +335,20 @@ namespace CodeWalker.Rendering if (DefScene != null) { DefScene.Clear(context); + DefScene.ClearDepth(context); } if (HDR != null) { HDR.Clear(context); HDR.ClearDepth(context); + } + + if (DefScene != null) + { + DefScene.SetSceneColour(context); + } + else if (HDR != null) + { HDR.SetPrimary(context); //for rendering some things before shadowmaps... (eg sky) } else @@ -429,7 +438,7 @@ namespace CodeWalker.Rendering if (DefScene != null) { - DefScene.SetPrimary(context); + DefScene.SetGBuffers(context); } else if (HDR != null) { @@ -563,14 +572,7 @@ namespace CodeWalker.Rendering if (DefScene != null) { - if (HDR != null) - { - HDR.SetPrimary(context); - } - else - { - DXMan.SetDefaultRenderTarget(context); - } + DefScene.SetSceneColour(context); DefScene.RenderLights(context, camera, Shadowmap, GlobalLights); @@ -632,7 +634,6 @@ namespace CodeWalker.Rendering - Basic.Deferred = deferred; RenderedGeometries = GeometryCount; @@ -642,13 +643,27 @@ namespace CodeWalker.Rendering { context.Rasterizer.State = rsSolid; context.OutputMerger.BlendState = bsDefault; - context.OutputMerger.DepthStencilState = dsEnabled; + context.OutputMerger.DepthStencilState = dsDisableAll; + if (DefScene != null) + { + if (HDR != null) + { + HDR.SetPrimary(context); + } + else + { + DXMan.SetDefaultRenderTarget(context); + } + + DefScene.FinalPass(context); + } if (HDR != null) { HDR.Render(DXMan, CurrentElapsedTime); } + Basic.Deferred = deferred; } private void RenderShadowmap(DeviceContext context) diff --git a/Rendering/Shaders/DeferredScene.cs b/Rendering/Shaders/DeferredScene.cs index 4e6b037..7ac0ecf 100644 --- a/Rendering/Shaders/DeferredScene.cs +++ b/Rendering/Shaders/DeferredScene.cs @@ -41,12 +41,20 @@ namespace CodeWalker.Rendering public uint Pad1; } + public struct DeferredMSAAPSVars + { + public uint SampleCount; + public float SampleMult; + public float TexelSizeX; + public float TexelSizeY; + } public class DeferredScene { public GpuMultiTexture GBuffers; // diffuse, normals, specular, irradiance + public GpuTexture SceneColour; //final scene colour buffer SamplerState SampleStatePoint; SamplerState SampleStateLinear; @@ -69,6 +77,13 @@ namespace CodeWalker.Rendering GpuVarsBuffer LightPSVars; + int MSAASampleCount = 1; + + VertexShader FinalVS; + PixelShader MSAAPS; + + GpuVarsBuffer MSAAPSVars; + public long VramUsage { @@ -86,6 +101,8 @@ namespace CodeWalker.Rendering byte[] bLightVS = File.ReadAllBytes("Shaders\\LightVS.cso"); byte[] bLightPS = File.ReadAllBytes("Shaders\\LightPS.cso"); + byte[] bFinalVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso"); + byte[] bMSAAPS = File.ReadAllBytes("Shaders\\PPMSAAPS.cso"); LightVS = new VertexShader(device, bLightVS); LightPS = new PixelShader(device, bLightPS); @@ -102,6 +119,12 @@ namespace CodeWalker.Rendering LightVSVars = new GpuVarsBuffer(device); LightPSVars = new GpuVarsBuffer(device); + + FinalVS = new VertexShader(device, bFinalVS); + MSAAPS = new PixelShader(device, bMSAAPS); + + MSAAPSVars = new GpuVarsBuffer(device); + TextureAddressMode a = TextureAddressMode.Clamp; Color4 b = new Color4(0.0f, 0.0f, 0.0f, 0.0f); Comparison c = Comparison.Always; @@ -175,6 +198,21 @@ namespace CodeWalker.Rendering LightVS.Dispose(); LightVS = null; } + if (MSAAPSVars != null) + { + MSAAPSVars.Dispose(); + MSAAPSVars = null; + } + if (MSAAPS != null) + { + MSAAPS.Dispose(); + MSAAPS = null; + } + if (FinalVS != null) + { + FinalVS.Dispose(); + FinalVS = null; + } } public void OnWindowResize(DXManager dxman) @@ -185,8 +223,8 @@ namespace CodeWalker.Rendering - int uw = Width = dxman.backbuffer.Description.Width; - int uh = Height = dxman.backbuffer.Description.Height; + int uw = Width = dxman.backbuffer.Description.Width * MSAASampleCount; + int uh = Height = dxman.backbuffer.Description.Height * MSAASampleCount; Viewport = new ViewportF(); Viewport.Width = (float)uw; Viewport.Height = (float)uh; @@ -199,6 +237,8 @@ namespace CodeWalker.Rendering GBuffers = new GpuMultiTexture(device, uw, uh, 4, Format.R8G8B8A8_UNorm, true, Format.D32_Float); WindowSizeVramUsage += GBuffers.VramUsage; + SceneColour = new GpuTexture(device, uw, uh, Format.R32G32B32A32_Float, 1, 0, true, Format.D32_Float); + WindowSizeVramUsage += SceneColour.VramUsage; } public void DisposeBuffers() { @@ -207,25 +247,34 @@ namespace CodeWalker.Rendering GBuffers.Dispose(); GBuffers = null; } + if (SceneColour != null) + { + SceneColour.Dispose(); + SceneColour = null; + } WindowSizeVramUsage = 0; } public void Clear(DeviceContext context) { - //Color4 clearColour = new Color4(0.2f, 0.4f, 0.6f, 0.0f); - Color4 clearColour = new Color4(0.0f, 0.0f, 0.0f, 0.0f); - - GBuffers.Clear(context, clearColour); + GBuffers.Clear(context, new Color4(0.0f, 0.0f, 0.0f, 0.0f)); + SceneColour.Clear(context, new Color4(0.2f, 0.4f, 0.6f, 0.0f)); } public void ClearDepth(DeviceContext context) { GBuffers.ClearDepth(context); + SceneColour.ClearDepth(context); } - public void SetPrimary(DeviceContext context) + public void SetGBuffers(DeviceContext context) { GBuffers.SetRenderTargets(context); context.Rasterizer.SetViewport(Viewport); } + public void SetSceneColour(DeviceContext context) + { + SceneColour.SetRenderTarget(context); + context.Rasterizer.SetViewport(Viewport); + } public void RenderLights(DeviceContext context, Camera camera, Shadowmap globalShadows, ShaderGlobalLights globalLights) { @@ -371,5 +420,34 @@ namespace CodeWalker.Rendering + + public void FinalPass(DeviceContext context) + { + //do antialiasing from SceneColour into HDR primary + + context.VertexShader.Set(FinalVS); + context.PixelShader.Set(MSAAPS); + + context.PixelShader.SetShaderResources(0, SceneColour.SRV); + context.PixelShader.SetSamplers(0, SampleStatePoint); + + MSAAPSVars.Vars.SampleCount = (uint)MSAASampleCount; + MSAAPSVars.Vars.SampleMult = 1.0f / (MSAASampleCount * MSAASampleCount); + MSAAPSVars.Vars.TexelSizeX = 1.0f / Width; + MSAAPSVars.Vars.TexelSizeY = 1.0f / Height; + MSAAPSVars.Update(context); + MSAAPSVars.SetPSCBuffer(context, 0); + + context.InputAssembler.InputLayout = LightQuadLayout; + LightQuad.Draw(context); + + context.VertexShader.Set(null); + context.PixelShader.Set(null); + context.PixelShader.SetShaderResources(0, null, null, null); + context.PixelShader.SetSamplers(0, null, null); + + } + + } } diff --git a/Shaders/PPMSAAPS.cso b/Shaders/PPMSAAPS.cso new file mode 100644 index 0000000..9de6c5b Binary files /dev/null and b/Shaders/PPMSAAPS.cso differ