Deferred shading

This commit is contained in:
dexy
2019-12-04 00:52:22 +11:00
Unverified
parent 755477590d
commit 9a53c2147b
60 changed files with 2724 additions and 509 deletions
+6 -1
View File
@@ -145,6 +145,7 @@ namespace CodeWalker.Rendering
VertexShader basicvscapsule;
VertexShader basicvscylinder;
PixelShader basicps;
PixelShader basicpsdef;
GpuVarsBuffer<BasicShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<BasicShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<BasicShaderVSModelVars> VSModelVars;
@@ -174,6 +175,7 @@ namespace CodeWalker.Rendering
public int RenderTextureSamplerCoord = 1;
public ShaderParamNames RenderTextureSampler = ShaderParamNames.DiffuseSampler;
public bool SpecularEnable = true;
public bool Deferred = false;
Matrix3_s[] defaultBoneMatrices;
bool defaultBoneMatricesBound = false;
@@ -209,6 +211,7 @@ namespace CodeWalker.Rendering
byte[] vscapsulebytes = File.ReadAllBytes("Shaders\\BasicVS_Capsule.cso");
byte[] vscylinderbytes = File.ReadAllBytes("Shaders\\BasicVS_Cylinder.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\BasicPS.cso");
byte[] psdefbytes = File.ReadAllBytes("Shaders\\BasicPS_Deferred.cso");
basicvspnct = new VertexShader(device, vspnctbytes);
basicvspnctt = new VertexShader(device, vspncttbytes);
@@ -235,6 +238,7 @@ namespace CodeWalker.Rendering
basicvscapsule = new VertexShader(device, vscapsulebytes);
basicvscylinder = new VertexShader(device, vscylinderbytes);
basicps = new PixelShader(device, psbytes);
basicpsdef = new PixelShader(device, psdefbytes);
VSSceneVars = new GpuVarsBuffer<BasicShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<BasicShaderVSEntityVars>(device);
@@ -491,7 +495,7 @@ namespace CodeWalker.Rendering
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(basicps);
context.PixelShader.Set(Deferred ? basicpsdef : basicps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
@@ -1035,6 +1039,7 @@ namespace CodeWalker.Rendering
ClothVertices.Dispose();
basicps.Dispose();
basicpsdef.Dispose();
basicvspnct.Dispose();
basicvspnctt.Dispose();
basicvspncttt.Dispose();
+6 -1
View File
@@ -67,6 +67,7 @@ namespace CodeWalker.Rendering
VertexShader vs;
PixelShader ps;
PixelShader psdef;
GpuVarsBuffer<CableShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<CableShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<CableShaderVSModelVars> VSModelVars;
@@ -80,6 +81,7 @@ namespace CodeWalker.Rendering
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public ShaderParamNames RenderTextureSampler = ShaderParamNames.DiffuseSampler;
public bool Deferred = false;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
@@ -88,9 +90,11 @@ namespace CodeWalker.Rendering
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\CableVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\CablePS.cso");
byte[] psdefbytes = File.ReadAllBytes("Shaders\\CablePS_Deferred.cso");
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
psdef = new PixelShader(device, psdefbytes);
VSSceneVars = new GpuVarsBuffer<CableShaderVSSceneVars>(device);
@@ -137,7 +141,7 @@ namespace CodeWalker.Rendering
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(ps);
context.PixelShader.Set(Deferred ? psdef : ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
@@ -344,6 +348,7 @@ namespace CodeWalker.Rendering
ps.Dispose();
psdef.Dispose();
vs.Dispose();
disposed = true;
+375
View File
@@ -0,0 +1,375 @@
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 DeferredLightVSVars
{
public Matrix ViewProj;
public Vector4 CameraPos;
public uint LightType; //0=directional, 1=Point, 2=Spot, 4=Capsule
public uint IsLOD; //useful or not?
public uint Pad0;
public uint Pad1;
}
public struct DeferredLightPSVars
{
public ShaderGlobalLightParams GlobalLights;
public Matrix ViewProjInv;
public Vector4 CameraPos;
public uint EnableShadows;
public uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct
public uint RenderModeIndex; //colour/texcoord index
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 class DeferredScene
{
public GpuMultiTexture GBuffers; // diffuse, normals, specular, irradiance
SamplerState SampleStatePoint;
SamplerState SampleStateLinear;
BlendState BlendState;
long WindowSizeVramUsage = 0;
int Width = 0;
int Height = 0;
ViewportF Viewport;
VertexShader LightVS;
PixelShader LightPS;
UnitCone LightCone;
UnitSphere LightSphere;
UnitCapsule LightCapsule;
UnitQuad LightQuad;
InputLayout LightQuadLayout;
GpuVarsBuffer<DeferredLightVSVars> LightVSVars;
GpuVarsBuffer<DeferredLightPSVars> LightPSVars;
public long VramUsage
{
get
{
return WindowSizeVramUsage;
}
}
public DeferredScene(DXManager dxman)
{
var device = dxman.device;
byte[] bLightVS = File.ReadAllBytes("Shaders\\LightVS.cso");
byte[] bLightPS = File.ReadAllBytes("Shaders\\LightPS.cso");
LightVS = new VertexShader(device, bLightVS);
LightPS = new PixelShader(device, bLightPS);
LightCone = new UnitCone(device, bLightVS, 4, false);
LightSphere = new UnitSphere(device, bLightVS, 4, true);
LightCapsule = new UnitCapsule(device, bLightVS, 4, false);
LightQuad = new UnitQuad(device, true);
LightQuadLayout = new InputLayout(device, bLightVS, new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0),
});
LightVSVars = new GpuVarsBuffer<DeferredLightVSVars>(device);
LightPSVars = new GpuVarsBuffer<DeferredLightPSVars>(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);
}
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 (LightVSVars != null)
{
LightVSVars.Dispose();
LightVSVars = null;
}
if (LightPSVars != null)
{
LightPSVars.Dispose();
LightPSVars = null;
}
if (LightQuadLayout != null)
{
LightQuadLayout.Dispose();
LightQuadLayout = null;
}
if (LightQuad != null)
{
LightQuad.Dispose();
LightQuad = null;
}
if (LightCone != null)
{
LightCone.Dispose();
LightCone = null;
}
if (LightSphere != null)
{
LightSphere.Dispose();
LightSphere = null;
}
if (LightCapsule != null)
{
LightCapsule.Dispose();
LightCapsule = null;
}
if (LightPS != null)
{
LightPS.Dispose();
LightPS = null;
}
if (LightVS != null)
{
LightVS.Dispose();
LightVS = null;
}
}
public void OnWindowResize(DXManager dxman)
{
DisposeBuffers();
var device = dxman.device;
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;
GBuffers = new GpuMultiTexture(device, uw, uh, 4, Format.R8G8B8A8_UNorm, true, Format.D32_Float);
WindowSizeVramUsage += GBuffers.VramUsage;
}
public void DisposeBuffers()
{
if (GBuffers != null)
{
GBuffers.Dispose();
GBuffers = 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);
}
public void ClearDepth(DeviceContext context)
{
GBuffers.ClearDepth(context);
}
public void SetPrimary(DeviceContext context)
{
GBuffers.SetRenderTargets(context);
context.Rasterizer.SetViewport(Viewport);
}
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(LightVS);
context.PixelShader.Set(LightPS);
LightVSVars.Vars.ViewProj = Matrix.Identity; //Matrix.Transpose(camera.ViewProjMatrix);
LightVSVars.Vars.CameraPos = Vector4.Zero; //new Vector4(camera.Position, 0.0f);
LightVSVars.Vars.LightType = 0;
LightVSVars.Vars.IsLOD = 0;
LightVSVars.Vars.Pad0 = 0;
LightVSVars.Vars.Pad1 = 0;
LightVSVars.Update(context);
LightVSVars.SetVSCBuffer(context, 0);
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.EnableShadows = (globalShadows != null) ? 1u : 0u;
LightPSVars.Vars.RenderMode = rendermode;
LightPSVars.Vars.RenderModeIndex = rendermodeind;
LightPSVars.Vars.RenderSamplerCoord = 0;// (uint)RenderTextureSamplerCoord;
LightPSVars.Vars.LightType = 0;
LightPSVars.Vars.IsLOD = 0;
LightPSVars.Vars.Pad0 = 0;
LightPSVars.Vars.Pad1 = 0;
LightPSVars.Update(context);
LightPSVars.SetPSCBuffer(context, 0);
context.PixelShader.SetShaderResources(0, GBuffers.DepthSRV);
context.PixelShader.SetShaderResources(2, GBuffers.SRVs);
if (globalShadows != null)
{
globalShadows.SetFinalRenderResources(context);
}
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);
}
public void RenderLights(DeviceContext context, Camera camera, List<RenderableLODLights> lodlights)
{
//instanced rendering of all other lights, using appropriate shapes
//blend mode: additive
context.VertexShader.Set(LightVS);
context.PixelShader.Set(LightPS);
LightVSVars.Vars.ViewProj = Matrix.Transpose(camera.ViewProjMatrix);
LightVSVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
LightVSVars.Vars.LightType = 0;
LightVSVars.Vars.IsLOD = 0;
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.LightType = 0;
LightPSVars.Vars.IsLOD = 0;
LightPSVars.Vars.Pad0 = 0;
LightPSVars.Vars.Pad1 = 0;
context.PixelShader.SetShaderResources(0, GBuffers.DepthSRV);
context.PixelShader.SetShaderResources(2, GBuffers.SRVs);
//if (globalShadows != null)
//{
// globalShadows.SetFinalRenderResources(context);
//}
foreach (var rll in lodlights)
{
if (rll.PointsBuffer != null)
{
context.VertexShader.SetShaderResources(0, rll.PointsBuffer.SRV);
context.PixelShader.SetShaderResources(6, rll.PointsBuffer.SRV);
LightVSVars.Vars.LightType = 1;
LightVSVars.Update(context);
LightVSVars.SetVSCBuffer(context, 0);
LightPSVars.Vars.LightType = 1;
LightPSVars.Update(context);
LightPSVars.SetPSCBuffer(context, 0);
LightSphere.DrawInstanced(context, rll.PointsBuffer.StructCount);
}
if (rll.SpotsBuffer != null)
{
context.VertexShader.SetShaderResources(0, rll.SpotsBuffer.SRV);
context.PixelShader.SetShaderResources(6, rll.SpotsBuffer.SRV);
LightVSVars.Vars.LightType = 2;
LightVSVars.Update(context);
LightVSVars.SetVSCBuffer(context, 0);
LightPSVars.Vars.LightType = 2;
LightPSVars.Update(context);
LightPSVars.SetPSCBuffer(context, 0);
LightCone.DrawInstanced(context, rll.SpotsBuffer.StructCount);
}
if (rll.CapsBuffer != null)
{
context.VertexShader.SetShaderResources(0, rll.CapsBuffer.SRV);
context.PixelShader.SetShaderResources(6, rll.CapsBuffer.SRV);
LightVSVars.Vars.LightType = 4;
LightVSVars.Update(context);
LightVSVars.SetVSCBuffer(context, 0);
LightPSVars.Vars.LightType = 4;
LightPSVars.Update(context);
LightPSVars.SetPSCBuffer(context, 0);
LightCapsule.DrawInstanced(context, rll.CapsBuffer.StructCount);
}
}
context.VertexShader.Set(null);
context.PixelShader.Set(null);
context.PixelShader.SetShaderResources(0, null, null, null);
context.PixelShader.SetSamplers(0, null, null);
}
}
}
+6 -1
View File
@@ -78,6 +78,7 @@ namespace CodeWalker.Rendering
VertexShader pnctttxvs;
VertexShader pncttxvs;
PixelShader terrainps;
PixelShader terrainpsdef;
GpuVarsBuffer<TerrainShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<TerrainShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<TerrainShaderVSModelVars> VSModelVars;
@@ -93,6 +94,7 @@ namespace CodeWalker.Rendering
public int RenderTextureCoordIndex = 1;
public int RenderTextureSamplerCoord = 1;
public ShaderParamNames RenderTextureSampler = ShaderParamNames.DiffuseSampler;
public bool Deferred = false;
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
@@ -107,6 +109,7 @@ namespace CodeWalker.Rendering
byte[] vspnctttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTTX.cso");
byte[] vspncttx = File.ReadAllBytes("Shaders\\TerrainVS_PNCTTX.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\TerrainPS.cso");
byte[] psdefbytes = File.ReadAllBytes("Shaders\\TerrainPS_Deferred.cso");
pncctvs = new VertexShader(device, vspncct);
pnccttvs = new VertexShader(device, vspncctt);
@@ -116,6 +119,7 @@ namespace CodeWalker.Rendering
pnctttxvs = new VertexShader(device, vspnctttx);
pncttxvs = new VertexShader(device, vspncttx);
terrainps = new PixelShader(device, psbytes);
terrainpsdef = new PixelShader(device, psdefbytes);
VSSceneVars = new GpuVarsBuffer<TerrainShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<TerrainShaderVSEntityVars>(device);
@@ -259,7 +263,7 @@ namespace CodeWalker.Rendering
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(terrainps);
context.PixelShader.Set(Deferred ? terrainpsdef : terrainps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
@@ -639,6 +643,7 @@ namespace CodeWalker.Rendering
PSGeomVars.Dispose();
terrainps.Dispose();
terrainpsdef.Dispose();
pncctvs.Dispose();
pnccttvs.Dispose();
pnccttxvs.Dispose();
+14 -8
View File
@@ -59,8 +59,9 @@ namespace CodeWalker.Rendering
{
bool disposed = false;
VertexShader basicvs;
PixelShader basicps;
VertexShader vs;
PixelShader ps;
PixelShader psdef;
GpuVarsBuffer<TreesLodShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<TreesLodShaderVSEntityVars> VSEntityVars;
GpuVarsBuffer<TreesLodShaderVSModelVars> VSModelVars;
@@ -71,14 +72,18 @@ namespace CodeWalker.Rendering
private Dictionary<VertexType, InputLayout> layouts = new Dictionary<VertexType, InputLayout>();
public bool Deferred = false;
public TreesLodShader(Device device)
{
byte[] vsbytes = File.ReadAllBytes("Shaders\\TreesLodVS.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\TreesLodPS.cso");
byte[] psdefbytes = File.ReadAllBytes("Shaders\\TreesLodPS_Deferred.cso");
basicvs = new VertexShader(device, vsbytes);
basicps = new PixelShader(device, psbytes);
vs = new VertexShader(device, vsbytes);
ps = new PixelShader(device, psbytes);
psdef = new PixelShader(device, psdefbytes);
VSSceneVars = new GpuVarsBuffer<TreesLodShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<TreesLodShaderVSEntityVars>(device);
@@ -112,8 +117,8 @@ namespace CodeWalker.Rendering
public override void SetShader(DeviceContext context)
{
context.VertexShader.Set(basicvs);
context.PixelShader.Set(basicps);
context.VertexShader.Set(vs);
context.PixelShader.Set(Deferred ? psdef : ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
@@ -311,8 +316,9 @@ namespace CodeWalker.Rendering
PSSceneVars.Dispose();
PSEntityVars.Dispose();
basicps.Dispose();
basicvs.Dispose();
psdef.Dispose();
ps.Dispose();
vs.Dispose();
disposed = true;
}
+6 -1
View File
@@ -84,6 +84,7 @@ namespace CodeWalker.Rendering
VertexShader vspnct;
VertexShader vspnctx;
PixelShader ps;
PixelShader psdef;
GpuVarsBuffer<WaterShaderVSSceneVars> VSSceneVars;
GpuVarsBuffer<WaterShaderVSEntityVars> VSEntityVars;
@@ -107,6 +108,7 @@ namespace CodeWalker.Rendering
public double CurrentRealTime = 0;
public float CurrentElapsedTime = 0;
public bool SpecularEnable = true;
public bool Deferred = false;
public RenderableTexture waterbump { get; set; }
@@ -124,6 +126,7 @@ namespace CodeWalker.Rendering
byte[] vspnctbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCT.cso");
byte[] vspnctxbytes = File.ReadAllBytes("Shaders\\WaterVS_PNCTX.cso");
byte[] psbytes = File.ReadAllBytes("Shaders\\WaterPS.cso");
byte[] psdefbytes = File.ReadAllBytes("Shaders\\WaterPS_Deferred.cso");
vspt = new VertexShader(device, vsptbytes);
@@ -131,6 +134,7 @@ namespace CodeWalker.Rendering
vspnct = new VertexShader(device, vspnctbytes);
vspnctx = new VertexShader(device, vspnctxbytes);
ps = new PixelShader(device, psbytes);
psdef = new PixelShader(device, psdefbytes);
VSSceneVars = new GpuVarsBuffer<WaterShaderVSSceneVars>(device);
VSEntityVars = new GpuVarsBuffer<WaterShaderVSEntityVars>(device);
@@ -213,7 +217,7 @@ namespace CodeWalker.Rendering
public override void SetShader(DeviceContext context)
{
context.PixelShader.Set(ps);
context.PixelShader.Set(Deferred ? psdef : ps);
}
public override bool SetInputLayout(DeviceContext context, VertexType type)
@@ -552,6 +556,7 @@ namespace CodeWalker.Rendering
PSGeomVars.Dispose();
ps.Dispose();
psdef.Dispose();
vspt.Dispose();
vspct.Dispose();
vspnct.Dispose();