mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-08-20 17:09:19 +08:00
689 lines
24 KiB
C#
689 lines
24 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Text;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using Device = SharpDX.Direct3D11.Device;
|
|||
|
using Buffer = SharpDX.Direct3D11.Buffer;
|
|||
|
using MapFlags = SharpDX.Direct3D11.MapFlags;
|
|||
|
using SharpDX.Direct3D11;
|
|||
|
using System.IO;
|
|||
|
using CodeWalker.GameFiles;
|
|||
|
using CodeWalker.World;
|
|||
|
using SharpDX;
|
|||
|
using SharpDX.DXGI;
|
|||
|
using SharpDX.Mathematics.Interop;
|
|||
|
|
|||
|
namespace CodeWalker.Rendering
|
|||
|
{
|
|||
|
|
|||
|
public struct PostProcessorReduceCSVars
|
|||
|
{
|
|||
|
public uint dimx;
|
|||
|
public uint dimy;
|
|||
|
public uint Width;
|
|||
|
public uint Height;
|
|||
|
}
|
|||
|
public struct PostProcessorLumBlendCSVars
|
|||
|
{
|
|||
|
public Vector4 blend;
|
|||
|
}
|
|||
|
public struct PostProcessorFilterSampleWeights
|
|||
|
{
|
|||
|
public Vector4 avSampleWeights00; //[15];
|
|||
|
public Vector4 avSampleWeights01;
|
|||
|
public Vector4 avSampleWeights02;
|
|||
|
public Vector4 avSampleWeights03;
|
|||
|
public Vector4 avSampleWeights04;
|
|||
|
public Vector4 avSampleWeights05;
|
|||
|
public Vector4 avSampleWeights06;
|
|||
|
public Vector4 avSampleWeights07;
|
|||
|
public Vector4 avSampleWeights08;
|
|||
|
public Vector4 avSampleWeights09;
|
|||
|
public Vector4 avSampleWeights10;
|
|||
|
public Vector4 avSampleWeights11;
|
|||
|
public Vector4 avSampleWeights12;
|
|||
|
public Vector4 avSampleWeights13;
|
|||
|
public Vector4 avSampleWeights14;
|
|||
|
|
|||
|
public Vector4 Get(int i)
|
|||
|
{
|
|||
|
switch (i)
|
|||
|
{
|
|||
|
default:
|
|||
|
case 0: return avSampleWeights00;
|
|||
|
case 1: return avSampleWeights01;
|
|||
|
case 2: return avSampleWeights02;
|
|||
|
case 3: return avSampleWeights03;
|
|||
|
case 4: return avSampleWeights04;
|
|||
|
case 5: return avSampleWeights05;
|
|||
|
case 6: return avSampleWeights06;
|
|||
|
case 7: return avSampleWeights07;
|
|||
|
case 8: return avSampleWeights08;
|
|||
|
case 9: return avSampleWeights09;
|
|||
|
case 10: return avSampleWeights10;
|
|||
|
case 11: return avSampleWeights11;
|
|||
|
case 12: return avSampleWeights12;
|
|||
|
case 13: return avSampleWeights13;
|
|||
|
case 14: return avSampleWeights14;
|
|||
|
}
|
|||
|
}
|
|||
|
public void Set(int i, Vector4 v)
|
|||
|
{
|
|||
|
switch (i)
|
|||
|
{
|
|||
|
case 0: avSampleWeights00 = v; break;
|
|||
|
case 1: avSampleWeights01 = v; break;
|
|||
|
case 2: avSampleWeights02 = v; break;
|
|||
|
case 3: avSampleWeights03 = v; break;
|
|||
|
case 4: avSampleWeights04 = v; break;
|
|||
|
case 5: avSampleWeights05 = v; break;
|
|||
|
case 6: avSampleWeights06 = v; break;
|
|||
|
case 7: avSampleWeights07 = v; break;
|
|||
|
case 8: avSampleWeights08 = v; break;
|
|||
|
case 9: avSampleWeights09 = v; break;
|
|||
|
case 10: avSampleWeights10 = v; break;
|
|||
|
case 11: avSampleWeights11 = v; break;
|
|||
|
case 12: avSampleWeights12 = v; break;
|
|||
|
case 13: avSampleWeights13 = v; break;
|
|||
|
case 14: avSampleWeights14 = v; break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
public struct PostProcessorFilterBPHCSVars
|
|||
|
{
|
|||
|
public PostProcessorFilterSampleWeights avSampleWeights;
|
|||
|
public uint outputwidth;
|
|||
|
public float finverse;
|
|||
|
public int inputsize0;
|
|||
|
public int inputsize1;
|
|||
|
}
|
|||
|
public struct PostProcessorFilterVCSVars
|
|||
|
{
|
|||
|
public PostProcessorFilterSampleWeights avSampleWeights;
|
|||
|
public int outputsize0;
|
|||
|
public int outputsize1;
|
|||
|
public int inputsize0;
|
|||
|
public int inputsize1;
|
|||
|
}
|
|||
|
public struct PostProcessorFinalPSVars
|
|||
|
{
|
|||
|
public Vector4 invPixelCount;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public class PostProcessor
|
|||
|
{
|
|||
|
ComputeShader ReduceTo1DCS;
|
|||
|
ComputeShader ReduceTo0DCS;
|
|||
|
ComputeShader LumBlendCS;
|
|||
|
ComputeShader BloomFilterBPHCS;
|
|||
|
ComputeShader BloomFilterVCS;
|
|||
|
PixelShader CopyPixelsPS;
|
|||
|
VertexShader FinalPassVS;
|
|||
|
PixelShader FinalPassPS;
|
|||
|
UnitQuad FinalPassQuad;
|
|||
|
InputLayout FinalPassLayout;
|
|||
|
GpuVarsBuffer<PostProcessorReduceCSVars> ReduceCSVars;
|
|||
|
GpuVarsBuffer<PostProcessorLumBlendCSVars> LumBlendCSVars;
|
|||
|
GpuVarsBuffer<PostProcessorFilterBPHCSVars> FilterBPHCSVars;
|
|||
|
GpuVarsBuffer<PostProcessorFilterVCSVars> FilterVCSVars;
|
|||
|
GpuVarsBuffer<PostProcessorFinalPSVars> FinalPSVars;
|
|||
|
|
|||
|
GpuTexture Primary;
|
|||
|
|
|||
|
GpuBuffer<float> Reduction0;
|
|||
|
GpuBuffer<float> Reduction1;
|
|||
|
|
|||
|
GpuBuffer<float> LumBlendResult;
|
|||
|
|
|||
|
GpuBuffer<Vector4> Bloom0;
|
|||
|
GpuBuffer<Vector4> Bloom1;
|
|||
|
GpuTexture Bloom;
|
|||
|
|
|||
|
SamplerState SampleStatePoint;
|
|||
|
SamplerState SampleStateLinear;
|
|||
|
BlendState BlendState;
|
|||
|
long WindowSizeVramUsage = 0;
|
|||
|
int Width = 0;
|
|||
|
int Height = 0;
|
|||
|
ViewportF Viewport;
|
|||
|
bool Multisampled = false;
|
|||
|
bool EnableBloom = true;
|
|||
|
float ElapsedTime = 0.0f;
|
|||
|
public float LumBlendSpeed = 1.0f;
|
|||
|
|
|||
|
bool CS_FULL_PIXEL_REDUCTION = false;
|
|||
|
|
|||
|
public long VramUsage
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return WindowSizeVramUsage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RawViewportF[] vpOld = new RawViewportF[15];
|
|||
|
|
|||
|
public PostProcessor(DXManager dxman)
|
|||
|
{
|
|||
|
var device = dxman.device;
|
|||
|
|
|||
|
byte[] bReduceTo1DCS = File.ReadAllBytes("Shaders\\PPReduceTo1DCS.cso");
|
|||
|
byte[] bReduceTo0DCS = File.ReadAllBytes("Shaders\\PPReduceTo0DCS.cso");
|
|||
|
byte[] bLumBlendCS = File.ReadAllBytes("Shaders\\PPLumBlendCS.cso");
|
|||
|
byte[] bBloomFilterBPHCS = File.ReadAllBytes("Shaders\\PPBloomFilterBPHCS.cso");
|
|||
|
byte[] bBloomFilterVCS = File.ReadAllBytes("Shaders\\PPBloomFilterVCS.cso");
|
|||
|
byte[] bCopyPixelsPS = File.ReadAllBytes("Shaders\\PPCopyPixelsPS.cso");
|
|||
|
byte[] bFinalPassVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso");
|
|||
|
byte[] bFinalPassPS = File.ReadAllBytes("Shaders\\PPFinalPassPS.cso");
|
|||
|
|
|||
|
ReduceTo1DCS = new ComputeShader(device, bReduceTo1DCS);
|
|||
|
ReduceTo0DCS = new ComputeShader(device, bReduceTo0DCS);
|
|||
|
LumBlendCS = new ComputeShader(device, bLumBlendCS);
|
|||
|
BloomFilterBPHCS = new ComputeShader(device, bBloomFilterBPHCS);
|
|||
|
BloomFilterVCS = new ComputeShader(device, bBloomFilterVCS);
|
|||
|
CopyPixelsPS = new PixelShader(device, bCopyPixelsPS);
|
|||
|
FinalPassVS = new VertexShader(device, bFinalPassVS);
|
|||
|
FinalPassPS = new PixelShader(device, bFinalPassPS);
|
|||
|
FinalPassQuad = new UnitQuad(device, true);
|
|||
|
FinalPassLayout = new InputLayout(device, bFinalPassVS, new[]
|
|||
|
{
|
|||
|
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
|||
|
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
|
|||
|
});
|
|||
|
|
|||
|
|
|||
|
ReduceCSVars = new GpuVarsBuffer<PostProcessorReduceCSVars>(device);
|
|||
|
LumBlendCSVars = new GpuVarsBuffer<PostProcessorLumBlendCSVars>(device);
|
|||
|
FilterBPHCSVars = new GpuVarsBuffer<PostProcessorFilterBPHCSVars>(device);
|
|||
|
FilterVCSVars = new GpuVarsBuffer<PostProcessorFilterVCSVars>(device);
|
|||
|
FinalPSVars = new GpuVarsBuffer<PostProcessorFinalPSVars>(device);
|
|||
|
|
|||
|
TextureAddressMode a = TextureAddressMode.Clamp;
|
|||
|
Color4 b = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
|
|||
|
Comparison c = Comparison.Always;
|
|||
|
SampleStatePoint = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipPoint, 0, 1.0f, 1.0f, 0.0f);
|
|||
|
SampleStateLinear = DXUtility.CreateSamplerState(device, a, b, c, Filter.MinMagMipLinear, 0, 1.0f, 1.0f, 0.0f);
|
|||
|
|
|||
|
BlendState = DXUtility.CreateBlendState(device, false, BlendOperation.Add, BlendOption.One, BlendOption.Zero, BlendOperation.Add, BlendOption.One, BlendOption.Zero, ColorWriteMaskFlags.All);
|
|||
|
|
|||
|
GetSampleWeights(ref FilterVCSVars.Vars.avSampleWeights, 3.0f, 1.25f); //init sample weights
|
|||
|
FilterBPHCSVars.Vars.avSampleWeights = FilterVCSVars.Vars.avSampleWeights;
|
|||
|
}
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
DisposeBuffers();
|
|||
|
|
|||
|
if (BlendState != null)
|
|||
|
{
|
|||
|
BlendState.Dispose();
|
|||
|
BlendState = null;
|
|||
|
}
|
|||
|
if (SampleStateLinear != null)
|
|||
|
{
|
|||
|
SampleStateLinear.Dispose();
|
|||
|
SampleStateLinear = null;
|
|||
|
}
|
|||
|
if (SampleStatePoint != null)
|
|||
|
{
|
|||
|
SampleStatePoint.Dispose();
|
|||
|
SampleStatePoint = null;
|
|||
|
}
|
|||
|
if (FinalPSVars != null)
|
|||
|
{
|
|||
|
FinalPSVars.Dispose();
|
|||
|
FinalPSVars = null;
|
|||
|
}
|
|||
|
if (FilterVCSVars != null)
|
|||
|
{
|
|||
|
FilterVCSVars.Dispose();
|
|||
|
FilterVCSVars = null;
|
|||
|
}
|
|||
|
if (FilterBPHCSVars != null)
|
|||
|
{
|
|||
|
FilterBPHCSVars.Dispose();
|
|||
|
FilterBPHCSVars = null;
|
|||
|
}
|
|||
|
if (LumBlendCSVars != null)
|
|||
|
{
|
|||
|
LumBlendCSVars.Dispose();
|
|||
|
LumBlendCSVars = null;
|
|||
|
}
|
|||
|
if (ReduceCSVars != null)
|
|||
|
{
|
|||
|
ReduceCSVars.Dispose();
|
|||
|
ReduceCSVars = null;
|
|||
|
}
|
|||
|
if (FinalPassLayout != null)
|
|||
|
{
|
|||
|
FinalPassLayout.Dispose();
|
|||
|
FinalPassLayout = null;
|
|||
|
}
|
|||
|
if (FinalPassQuad != null)
|
|||
|
{
|
|||
|
FinalPassQuad.Dispose();
|
|||
|
FinalPassQuad = null;
|
|||
|
}
|
|||
|
if (FinalPassPS != null)
|
|||
|
{
|
|||
|
FinalPassPS.Dispose();
|
|||
|
FinalPassPS = null;
|
|||
|
}
|
|||
|
if (FinalPassVS != null)
|
|||
|
{
|
|||
|
FinalPassVS.Dispose();
|
|||
|
FinalPassVS = null;
|
|||
|
}
|
|||
|
if (CopyPixelsPS != null)
|
|||
|
{
|
|||
|
CopyPixelsPS.Dispose();
|
|||
|
CopyPixelsPS = null;
|
|||
|
}
|
|||
|
if (BloomFilterVCS != null)
|
|||
|
{
|
|||
|
BloomFilterVCS.Dispose();
|
|||
|
BloomFilterVCS = null;
|
|||
|
}
|
|||
|
if (BloomFilterBPHCS != null)
|
|||
|
{
|
|||
|
BloomFilterBPHCS.Dispose();
|
|||
|
BloomFilterBPHCS = null;
|
|||
|
}
|
|||
|
if (LumBlendCS != null)
|
|||
|
{
|
|||
|
LumBlendCS.Dispose();
|
|||
|
LumBlendCS = null;
|
|||
|
}
|
|||
|
if (ReduceTo0DCS != null)
|
|||
|
{
|
|||
|
ReduceTo0DCS.Dispose();
|
|||
|
ReduceTo0DCS = null;
|
|||
|
}
|
|||
|
if (ReduceTo1DCS != null)
|
|||
|
{
|
|||
|
ReduceTo1DCS.Dispose();
|
|||
|
ReduceTo1DCS = null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void OnWindowResize(DXManager dxman)
|
|||
|
{
|
|||
|
DisposeBuffers();
|
|||
|
|
|||
|
var device = dxman.device;
|
|||
|
|
|||
|
|
|||
|
int sc = dxman.multisamplecount;
|
|||
|
int sq = dxman.multisamplequality;
|
|||
|
Multisampled = (sc > 1);
|
|||
|
|
|||
|
int uw = Width = dxman.backbuffer.Description.Width;
|
|||
|
int uh = Height = dxman.backbuffer.Description.Height;
|
|||
|
Viewport = new ViewportF();
|
|||
|
Viewport.Width = (float)uw;
|
|||
|
Viewport.Height = (float)uh;
|
|||
|
Viewport.MinDepth = 0.0f;
|
|||
|
Viewport.MaxDepth = 1.0f;
|
|||
|
Viewport.X = 0.0f;
|
|||
|
Viewport.Y = 0.0f;
|
|||
|
|
|||
|
|
|||
|
Format f = Format.R32G32B32A32_Float;
|
|||
|
Format df = Format.D32_Float;
|
|||
|
|
|||
|
|
|||
|
Primary = new GpuTexture(device, uw, uh, f, sc, sq, true, df);
|
|||
|
WindowSizeVramUsage += Primary.VramUsage;
|
|||
|
|
|||
|
|
|||
|
int rc = (int)(Math.Ceiling(uw / 8.0f) * Math.Ceiling(uh / 8.0f));
|
|||
|
|
|||
|
Reduction0 = new GpuBuffer<float>(device, 1, rc);
|
|||
|
Reduction1 = new GpuBuffer<float>(device, 1, rc);
|
|||
|
WindowSizeVramUsage += sizeof(float) * rc * 2;
|
|||
|
|
|||
|
LumBlendResult = new GpuBuffer<float>(device, 1, 1);
|
|||
|
WindowSizeVramUsage += sizeof(float); //because 4 bytes matter
|
|||
|
|
|||
|
int tw = uw / 8;
|
|||
|
int th = uh / 8;
|
|||
|
rc = tw * th;
|
|||
|
f = Format.R8G8B8A8_UNorm;
|
|||
|
|
|||
|
Bloom0 = new GpuBuffer<Vector4>(device, 1, rc);
|
|||
|
Bloom1 = new GpuBuffer<Vector4>(device, 1, rc);
|
|||
|
WindowSizeVramUsage += /*sizeof(V4F)*/ 16 * rc * 2;
|
|||
|
|
|||
|
Bloom = new GpuTexture(device, tw, th, f, 1, 0, false, df);
|
|||
|
WindowSizeVramUsage += Bloom.VramUsage;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
public void DisposeBuffers()
|
|||
|
{
|
|||
|
if (Bloom != null)
|
|||
|
{
|
|||
|
Bloom.Dispose();
|
|||
|
Bloom = null;
|
|||
|
}
|
|||
|
if (Bloom0 != null)
|
|||
|
{
|
|||
|
Bloom0.Dispose();
|
|||
|
Bloom0 = null;
|
|||
|
}
|
|||
|
if (Bloom1 != null)
|
|||
|
{
|
|||
|
Bloom1.Dispose();
|
|||
|
Bloom1 = null;
|
|||
|
}
|
|||
|
if (LumBlendResult != null)
|
|||
|
{
|
|||
|
LumBlendResult.Dispose();
|
|||
|
LumBlendResult = null;
|
|||
|
}
|
|||
|
if (Reduction0 != null)
|
|||
|
{
|
|||
|
Reduction0.Dispose();
|
|||
|
Reduction0 = null;
|
|||
|
}
|
|||
|
if (Reduction1 != null)
|
|||
|
{
|
|||
|
Reduction1.Dispose();
|
|||
|
Reduction1 = null;
|
|||
|
}
|
|||
|
if (Primary != null)
|
|||
|
{
|
|||
|
Primary.Dispose();
|
|||
|
Primary = 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);
|
|||
|
|
|||
|
Primary.Clear(context, clearColour);
|
|||
|
}
|
|||
|
public void ClearDepth(DeviceContext context)
|
|||
|
{
|
|||
|
Primary.ClearDepth(context);
|
|||
|
}
|
|||
|
public void SetPrimary(DeviceContext context)
|
|||
|
{
|
|||
|
Primary.SetRenderTarget(context);
|
|||
|
context.Rasterizer.SetViewport(Viewport);
|
|||
|
}
|
|||
|
|
|||
|
public void Render(DXManager dxman, float elapsed)
|
|||
|
{
|
|||
|
ElapsedTime = elapsed;
|
|||
|
|
|||
|
var context = dxman.context;
|
|||
|
|
|||
|
if (Multisampled)
|
|||
|
{
|
|||
|
int sr = 0;// D3D11CalcSubresource(0, 0, 1);
|
|||
|
context.ResolveSubresource(Primary.TextureMS, sr, Primary.Texture, sr, Format.R32G32B32A32_Float);
|
|||
|
}
|
|||
|
|
|||
|
context.OutputMerger.SetRenderTargets((RenderTargetView)null);
|
|||
|
|
|||
|
ProcessLuminance(context);
|
|||
|
ProcessBloom(context);
|
|||
|
|
|||
|
dxman.SetDefaultRenderTarget(context);
|
|||
|
context.OutputMerger.SetBlendState(BlendState, null, 0xFFFFFFFF);
|
|||
|
FinalPass(context);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void ProcessLuminance(DeviceContext context)
|
|||
|
{
|
|||
|
uint dimx, dimy;
|
|||
|
if (CS_FULL_PIXEL_REDUCTION)
|
|||
|
{
|
|||
|
dimx = (uint)(Math.Ceiling(Width / 8.0f));
|
|||
|
dimx = (uint)(Math.Ceiling(dimx / 2.0f));
|
|||
|
dimy = (uint)(Math.Ceiling(Height / 8.0f));
|
|||
|
dimy = (uint)(Math.Ceiling(dimy / 2.0f));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
dimx = (uint)(Math.Ceiling(81.0f / 8.0f)); //ToneMappingTexSize = (int)pow(3.0f, NUM_TONEMAP_TEXTURES-1);
|
|||
|
dimy = dimx;
|
|||
|
}
|
|||
|
|
|||
|
ReduceCSVars.Vars.dimx = dimx;
|
|||
|
ReduceCSVars.Vars.dimy = dimy;
|
|||
|
ReduceCSVars.Vars.Width = (uint)Width;
|
|||
|
ReduceCSVars.Vars.Height = (uint)Height;
|
|||
|
ReduceCSVars.Update(context);
|
|||
|
|
|||
|
Compute(context, ReduceTo1DCS, ReduceCSVars.Buffer, Reduction0.UAV, (int)dimx, (int)dimy, 1, Primary.SRV);
|
|||
|
|
|||
|
uint dim = dimx * dimy;
|
|||
|
uint nNumToReduce = dim;
|
|||
|
dim = (uint)(Math.Ceiling(dim / 128.0f));
|
|||
|
if (nNumToReduce > 1)
|
|||
|
{
|
|||
|
for (;;)
|
|||
|
{
|
|||
|
ReduceCSVars.Vars.dimx = nNumToReduce;
|
|||
|
ReduceCSVars.Vars.dimy = dim;
|
|||
|
ReduceCSVars.Vars.Width = 0;
|
|||
|
ReduceCSVars.Vars.Height = 0;
|
|||
|
ReduceCSVars.Update(context);
|
|||
|
|
|||
|
Compute(context, ReduceTo0DCS, ReduceCSVars.Buffer, Reduction1.UAV, (int)dim, 1, 1, Reduction0.SRV);
|
|||
|
|
|||
|
nNumToReduce = dim;
|
|||
|
dim = (uint)(Math.Ceiling(dim / 128.0f));
|
|||
|
|
|||
|
if (nNumToReduce == 1) break;
|
|||
|
|
|||
|
var r0 = Reduction0;
|
|||
|
Reduction0 = Reduction1;
|
|||
|
Reduction1 = r0;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
var r0 = Reduction0;
|
|||
|
Reduction0 = Reduction1;
|
|||
|
Reduction1 = r0;
|
|||
|
}
|
|||
|
|
|||
|
LumBlendCSVars.Vars.blend = new Vector4(Math.Min(ElapsedTime * LumBlendSpeed, 1.0f));
|
|||
|
LumBlendCSVars.Update(context);
|
|||
|
|
|||
|
Compute(context, LumBlendCS, LumBlendCSVars.Buffer, LumBlendResult.UAV, 1, 1, 1, Reduction1.SRV);
|
|||
|
|
|||
|
}
|
|||
|
private void ProcessBloom(DeviceContext context)
|
|||
|
{
|
|||
|
if (EnableBloom)
|
|||
|
{
|
|||
|
|
|||
|
// Bright pass and horizontal blur
|
|||
|
|
|||
|
ShaderResourceView view = Primary.SRV;
|
|||
|
|
|||
|
ShaderResourceView[] aRViews = { view, LumBlendResult.SRV };
|
|||
|
//BloomFilterShaderVars cbFilter;
|
|||
|
//GetSampleWeights(cbFilter.avSampleWeights, 3.0f, 1.25f);
|
|||
|
FilterBPHCSVars.Vars.outputwidth = (uint)(Width / 8);
|
|||
|
if (CS_FULL_PIXEL_REDUCTION)
|
|||
|
{
|
|||
|
FilterBPHCSVars.Vars.finverse = 1.0f / (Width * Height);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
FilterBPHCSVars.Vars.finverse = 1.0f / (81 * 81); //(ToneMappingTexSize*ToneMappingTexSize);
|
|||
|
}
|
|||
|
FilterBPHCSVars.Vars.inputsize0 = (int)Width;
|
|||
|
FilterBPHCSVars.Vars.inputsize1 = (int)Height;
|
|||
|
FilterBPHCSVars.Update(context);
|
|||
|
|
|||
|
int x = (int)(Math.Ceiling((float)FilterBPHCSVars.Vars.outputwidth / (128 - 7 * 2)));
|
|||
|
int y = (Height / 8);
|
|||
|
Compute(context, BloomFilterBPHCS, FilterBPHCSVars.Buffer, Bloom1.UAV, x, y, 1, view, LumBlendResult.SRV);
|
|||
|
|
|||
|
// Vertical blur
|
|||
|
FilterVCSVars.Vars.outputsize0 = (int)(Width / 8);
|
|||
|
FilterVCSVars.Vars.outputsize1 = (int)(Height / 8);
|
|||
|
FilterVCSVars.Vars.inputsize0 = (int)(Width / 8);
|
|||
|
FilterVCSVars.Vars.inputsize1 = (int)(Height / 8);
|
|||
|
FilterVCSVars.Update(context);
|
|||
|
x = Width / 8;
|
|||
|
y = (int)(Math.Ceiling((float)FilterVCSVars.Vars.outputsize1 / (128 - 7 * 2)));
|
|||
|
|
|||
|
Compute(context, BloomFilterVCS, FilterVCSVars.Buffer, Bloom0.UAV, x, y, 1, Bloom1.SRV, LumBlendResult.SRV);
|
|||
|
}
|
|||
|
|
|||
|
CopyPixels(context, Width / 8, Height / 8, Bloom0.SRV, Bloom.RTV);
|
|||
|
|
|||
|
}
|
|||
|
private void FinalPass(DeviceContext context)
|
|||
|
{
|
|||
|
context.Rasterizer.SetViewport(Viewport);
|
|||
|
context.VertexShader.Set(FinalPassVS);
|
|||
|
context.PixelShader.Set(FinalPassPS);
|
|||
|
|
|||
|
context.PixelShader.SetShaderResources(0, Primary.SRV, LumBlendResult.SRV, EnableBloom ? Bloom.SRV : null);
|
|||
|
|
|||
|
if (CS_FULL_PIXEL_REDUCTION)
|
|||
|
{
|
|||
|
//pcbCS[0] = 1.0f / (Width * Height);
|
|||
|
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (Width * Height));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//pcbCS[0] = 1.0f / (81 * 81); //ToneMappingTexSize*ToneMappingTexSize
|
|||
|
FinalPSVars.Vars.invPixelCount = new Vector4(1.0f / (81 * 81));
|
|||
|
}
|
|||
|
FinalPSVars.Update(context);
|
|||
|
FinalPSVars.SetPSCBuffer(context, 0);
|
|||
|
|
|||
|
context.PixelShader.SetSamplers(0, SampleStatePoint, SampleStateLinear);
|
|||
|
|
|||
|
context.InputAssembler.InputLayout = FinalPassLayout;
|
|||
|
FinalPassQuad.Draw(context);
|
|||
|
|
|||
|
context.VertexShader.Set(null);
|
|||
|
context.PixelShader.Set(null);
|
|||
|
context.PixelShader.SetShaderResources(0, null, null, null);
|
|||
|
context.PixelShader.SetSamplers(0, null, null);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
private float GaussianDistribution(float x, float y, float rho)
|
|||
|
{
|
|||
|
float g = 1.0f / (float)Math.Sqrt(2.0f * 3.14159265f * rho * rho);
|
|||
|
g *= (float)Math.Exp(-(x * x + y * y) / (2 * rho * rho));
|
|||
|
return g;
|
|||
|
}
|
|||
|
private void GetSampleWeights(ref PostProcessorFilterSampleWeights w, float fDeviation, float fMultiplier)
|
|||
|
{
|
|||
|
// Fill the center texel
|
|||
|
float weight = 1.0f * GaussianDistribution(0, 0, fDeviation);
|
|||
|
w.Set(7, new Vector4(weight, weight, weight, 1.0f));
|
|||
|
|
|||
|
// Fill the right side
|
|||
|
for (int i = 1; i < 8; i++)
|
|||
|
{
|
|||
|
weight = fMultiplier * GaussianDistribution((float)i, 0, fDeviation);
|
|||
|
w.Set(7 - i, new Vector4(weight, weight, weight, 1.0f));
|
|||
|
}
|
|||
|
|
|||
|
// Copy to the left side
|
|||
|
for (int i = 8; i < 15; i++)
|
|||
|
{
|
|||
|
w.Set(i, w.Get(14 - i));
|
|||
|
}
|
|||
|
|
|||
|
// Debug convolution kernel which doesn't transform input data
|
|||
|
/*ZeroMemory( avColorWeight, sizeof(D3DXVECTOR4)*15 );
|
|||
|
w.Set(7, new Vector4( 1, 1, 1, 1 ));*/
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void Compute(DeviceContext context, ComputeShader cs, Buffer constantBuffer, UnorderedAccessView unorderedAccessView, int X, int Y, int Z, params ShaderResourceView[] resourceViews)
|
|||
|
{
|
|||
|
context.ComputeShader.Set(cs);
|
|||
|
context.ComputeShader.SetShaderResources(0, resourceViews);
|
|||
|
context.ComputeShader.SetUnorderedAccessView(0, unorderedAccessView);
|
|||
|
|
|||
|
if (constantBuffer != null)
|
|||
|
{
|
|||
|
//make sure buffer is updated first...
|
|||
|
//D3D11_MAPPED_SUBRESOURCE mappedResource;
|
|||
|
//dc->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
|||
|
//memcpy(mappedResource.pData, constantData, constantDataSize);
|
|||
|
//dc->Unmap(constantBuffer, 0);
|
|||
|
context.ComputeShader.SetConstantBuffer(0, constantBuffer); //dc->CSSetConstantBuffers(0, 1, &constantBuffer);
|
|||
|
}
|
|||
|
|
|||
|
context.Dispatch(X, Y, Z);
|
|||
|
|
|||
|
ShaderResourceView[] ppSRVNULL = { null, null, null };
|
|||
|
context.ComputeShader.SetUnorderedAccessView(0, null);
|
|||
|
context.ComputeShader.SetShaderResources(0, 3, ppSRVNULL);
|
|||
|
context.ComputeShader.SetConstantBuffer(0, null);
|
|||
|
}
|
|||
|
|
|||
|
private void CopyPixels(DeviceContext context, int w, int h, ShaderResourceView fromSRV, RenderTargetView toRTV)
|
|||
|
{
|
|||
|
context.VertexShader.Set(FinalPassVS);
|
|||
|
context.PixelShader.Set(CopyPixelsPS);
|
|||
|
|
|||
|
ShaderResourceView[] aRViews = { fromSRV };
|
|||
|
context.PixelShader.SetShaderResource(0, fromSRV);
|
|||
|
|
|||
|
RenderTargetView[] aRTViews = { toRTV };
|
|||
|
context.OutputMerger.SetRenderTargets(toRTV);
|
|||
|
|
|||
|
//D3D11_MAPPED_SUBRESOURCE mappedResource;
|
|||
|
//dc->Map(ReduceCSVars.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
|
|||
|
//UINT* p = (UINT*)mappedResource.pData;
|
|||
|
//p[0] = w;
|
|||
|
//p[1] = h;
|
|||
|
//dc->Unmap(ReduceCSVars.Get(), 0);
|
|||
|
//ID3D11Buffer* ppCB[1] = { ReduceCSVars.Get() };
|
|||
|
//dc->PSSetConstantBuffers(0, 1, ppCB);
|
|||
|
ReduceCSVars.Vars.dimx = (uint)w;
|
|||
|
ReduceCSVars.Vars.dimy = (uint)h;
|
|||
|
ReduceCSVars.Update(context);
|
|||
|
ReduceCSVars.SetPSCBuffer(context, 0);
|
|||
|
|
|||
|
//DrawFullScreenQuad11( pd3dImmediateContext, g_pDumpBufferPS, dwWidth, dwHeight );
|
|||
|
//ViewportF[] vpOld = new ViewportF[15];// [D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX];
|
|||
|
//UINT nViewPorts = 1;
|
|||
|
//dc->RSGetViewports(&nViewPorts, vpOld);
|
|||
|
context.Rasterizer.GetViewports(vpOld);
|
|||
|
|
|||
|
// Setup the viewport to match the backbuffer
|
|||
|
ViewportF vp;
|
|||
|
vp.Width = (float)Width;
|
|||
|
vp.Height = (float)Height;
|
|||
|
vp.MinDepth = 0.0f;
|
|||
|
vp.MaxDepth = 1.0f;
|
|||
|
vp.X = 0;
|
|||
|
vp.Y = 0;
|
|||
|
context.Rasterizer.SetViewport(vp);
|
|||
|
|
|||
|
context.InputAssembler.InputLayout = FinalPassLayout;
|
|||
|
FinalPassQuad.Draw(context);
|
|||
|
|
|||
|
|
|||
|
context.Rasterizer.SetViewports(vpOld); //reverting viewports maybe not necessary...
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|