2019-12-03 21:52:22 +08:00
|
|
|
|
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?
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public uint SampleCount;//for MSAA
|
|
|
|
|
public float SampleMult;//for MSAA
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
2019-12-05 00:40:52 +08:00
|
|
|
|
public struct DeferredLightInstVars
|
|
|
|
|
{
|
|
|
|
|
public Vector3 InstPosition;
|
|
|
|
|
public float InstIntensity;
|
|
|
|
|
public Vector3 InstColour;
|
|
|
|
|
public float InstFalloff;
|
|
|
|
|
public Vector3 InstDirection;
|
|
|
|
|
public float InstFalloffExponent;
|
|
|
|
|
public Vector3 InstTangentX;
|
|
|
|
|
public float InstConeInnerAngle;
|
|
|
|
|
public Vector3 InstTangentY;
|
|
|
|
|
public float InstConeOuterAngle;
|
|
|
|
|
public Vector3 InstCapsuleExtent;
|
|
|
|
|
public uint InstType;
|
|
|
|
|
public Vector3 InstCullingPlaneNormal;
|
|
|
|
|
public float InstCullingPlaneOffset;
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
public struct DeferredSSAAPSVars
|
2019-12-04 01:33:27 +08:00
|
|
|
|
{
|
|
|
|
|
public uint SampleCount;
|
|
|
|
|
public float SampleMult;
|
|
|
|
|
public float TexelSizeX;
|
|
|
|
|
public float TexelSizeY;
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class DeferredScene
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public GpuMultiTexture GBuffers; // diffuse, normals, specular, irradiance
|
2019-12-04 01:33:27 +08:00
|
|
|
|
public GpuTexture SceneColour; //final scene colour buffer
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
SamplerState SampleStatePoint;
|
|
|
|
|
SamplerState SampleStateLinear;
|
|
|
|
|
BlendState BlendState;
|
|
|
|
|
long WindowSizeVramUsage = 0;
|
|
|
|
|
int Width = 0;
|
|
|
|
|
int Height = 0;
|
|
|
|
|
ViewportF Viewport;
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
VertexShader DirLightVS;
|
|
|
|
|
PixelShader DirLightPS;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
PixelShader DirLightMSPS;
|
2019-12-04 14:54:48 +08:00
|
|
|
|
VertexShader LodLightVS;
|
|
|
|
|
PixelShader LodLightPS;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
PixelShader LodLightMSPS;
|
2019-12-05 00:40:52 +08:00
|
|
|
|
VertexShader LightVS;
|
|
|
|
|
PixelShader LightPS;
|
|
|
|
|
PixelShader LightMSPS;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
UnitCone LightCone;
|
|
|
|
|
UnitSphere LightSphere;
|
|
|
|
|
UnitCapsule LightCapsule;
|
|
|
|
|
UnitQuad LightQuad;
|
|
|
|
|
InputLayout LightQuadLayout;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GpuVarsBuffer<DeferredLightVSVars> LightVSVars;
|
|
|
|
|
GpuVarsBuffer<DeferredLightPSVars> LightPSVars;
|
2019-12-05 00:40:52 +08:00
|
|
|
|
GpuVarsBuffer<DeferredLightInstVars> LightInstVars;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
|
|
|
|
VertexShader FinalVS;
|
2019-12-04 14:54:48 +08:00
|
|
|
|
PixelShader SSAAPS;
|
|
|
|
|
GpuVarsBuffer<DeferredSSAAPSVars> SSAAPSVars;
|
|
|
|
|
public int SSAASampleCount = 1;
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
public int MSAASampleCount = 4;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
public long VramUsage
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return WindowSizeVramUsage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public DeferredScene(DXManager dxman)
|
|
|
|
|
{
|
|
|
|
|
var device = dxman.device;
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
byte[] bDirLightVS = File.ReadAllBytes("Shaders\\DirLightVS.cso");
|
|
|
|
|
byte[] bDirLightPS = File.ReadAllBytes("Shaders\\DirLightPS.cso");
|
2019-12-04 17:14:11 +08:00
|
|
|
|
byte[] bDirLightMSPS = File.ReadAllBytes("Shaders\\DirLightPS_MS.cso");
|
2019-12-04 14:54:48 +08:00
|
|
|
|
byte[] bLodLightVS = File.ReadAllBytes("Shaders\\LodLightsVS.cso");
|
|
|
|
|
byte[] bLodLightPS = File.ReadAllBytes("Shaders\\LodLightsPS.cso");
|
2019-12-04 17:14:11 +08:00
|
|
|
|
byte[] bLodLightMSPS = File.ReadAllBytes("Shaders\\LodLightsPS_MS.cso");
|
2019-12-05 00:40:52 +08:00
|
|
|
|
byte[] bLightVS = File.ReadAllBytes("Shaders\\LightVS.cso");
|
|
|
|
|
byte[] bLightPS = File.ReadAllBytes("Shaders\\LightPS.cso");
|
|
|
|
|
byte[] bLightMSPS = File.ReadAllBytes("Shaders\\LightPS_MS.cso");
|
2019-12-04 01:33:27 +08:00
|
|
|
|
byte[] bFinalVS = File.ReadAllBytes("Shaders\\PPFinalPassVS.cso");
|
2019-12-04 14:54:48 +08:00
|
|
|
|
byte[] bSSAAPS = File.ReadAllBytes("Shaders\\PPSSAAPS.cso");
|
|
|
|
|
|
|
|
|
|
DirLightVS = new VertexShader(device, bDirLightVS);
|
|
|
|
|
DirLightPS = new PixelShader(device, bDirLightPS);
|
|
|
|
|
LodLightVS = new VertexShader(device, bLodLightVS);
|
|
|
|
|
LodLightPS = new PixelShader(device, bLodLightPS);
|
2019-12-05 00:40:52 +08:00
|
|
|
|
LightVS = new VertexShader(device, bLightVS);
|
|
|
|
|
LightPS = new PixelShader(device, bLightPS);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
|
|
|
|
|
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);
|
2019-12-05 00:40:52 +08:00
|
|
|
|
LightMSPS = new PixelShader(device, bLightMSPS);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
MSAASampleCount = 1; //can't do MSAA without at least 10.1 support
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
LightCone = new UnitCone(device, bLodLightVS, 4, false);
|
|
|
|
|
LightSphere = new UnitSphere(device, bLodLightVS, 4, true);
|
|
|
|
|
LightCapsule = new UnitCapsule(device, bLodLightVS, 4, false);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
LightQuad = new UnitQuad(device, true);
|
2019-12-04 14:54:48 +08:00
|
|
|
|
LightQuadLayout = new InputLayout(device, bDirLightVS, new[]
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
|
|
|
|
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);
|
2019-12-05 00:40:52 +08:00
|
|
|
|
LightInstVars = new GpuVarsBuffer<DeferredLightInstVars>(device);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
|
|
|
|
FinalVS = new VertexShader(device, bFinalVS);
|
2019-12-04 14:54:48 +08:00
|
|
|
|
SSAAPS = new PixelShader(device, bSSAAPS);
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
SSAAPSVars = new GpuVarsBuffer<DeferredSSAAPSVars>(device);
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2019-12-05 00:40:52 +08:00
|
|
|
|
if (LightInstVars != null)
|
|
|
|
|
{
|
|
|
|
|
LightInstVars.Dispose();
|
|
|
|
|
LightInstVars = null;
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2019-12-04 14:54:48 +08:00
|
|
|
|
if (DirLightPS != null)
|
|
|
|
|
{
|
|
|
|
|
DirLightPS.Dispose();
|
|
|
|
|
DirLightPS = null;
|
|
|
|
|
}
|
2019-12-04 17:14:11 +08:00
|
|
|
|
if (DirLightMSPS != null)
|
|
|
|
|
{
|
|
|
|
|
DirLightMSPS.Dispose();
|
|
|
|
|
DirLightMSPS = null;
|
|
|
|
|
}
|
2019-12-04 14:54:48 +08:00
|
|
|
|
if (DirLightVS != null)
|
|
|
|
|
{
|
|
|
|
|
DirLightVS.Dispose();
|
|
|
|
|
DirLightVS = null;
|
|
|
|
|
}
|
|
|
|
|
if (LodLightPS != null)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
2019-12-04 14:54:48 +08:00
|
|
|
|
LodLightPS.Dispose();
|
|
|
|
|
LodLightPS = null;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
2019-12-04 17:14:11 +08:00
|
|
|
|
if (LodLightMSPS != null)
|
|
|
|
|
{
|
|
|
|
|
LodLightMSPS.Dispose();
|
|
|
|
|
LodLightMSPS = null;
|
|
|
|
|
}
|
2019-12-04 14:54:48 +08:00
|
|
|
|
if (LodLightVS != null)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
2019-12-04 14:54:48 +08:00
|
|
|
|
LodLightVS.Dispose();
|
|
|
|
|
LodLightVS = null;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
2019-12-05 00:40:52 +08:00
|
|
|
|
if (LightPS != null)
|
|
|
|
|
{
|
|
|
|
|
LightPS.Dispose();
|
|
|
|
|
LightPS = null;
|
|
|
|
|
}
|
|
|
|
|
if (LightMSPS != null)
|
|
|
|
|
{
|
|
|
|
|
LightMSPS.Dispose();
|
|
|
|
|
LightMSPS = null;
|
|
|
|
|
}
|
|
|
|
|
if (LightVS != null)
|
|
|
|
|
{
|
|
|
|
|
LightVS.Dispose();
|
|
|
|
|
LightVS = null;
|
|
|
|
|
}
|
2019-12-04 14:54:48 +08:00
|
|
|
|
if (SSAAPSVars != null)
|
2019-12-04 01:33:27 +08:00
|
|
|
|
{
|
2019-12-04 14:54:48 +08:00
|
|
|
|
SSAAPSVars.Dispose();
|
|
|
|
|
SSAAPSVars = null;
|
2019-12-04 01:33:27 +08:00
|
|
|
|
}
|
2019-12-04 14:54:48 +08:00
|
|
|
|
if (SSAAPS != null)
|
2019-12-04 01:33:27 +08:00
|
|
|
|
{
|
2019-12-04 14:54:48 +08:00
|
|
|
|
SSAAPS.Dispose();
|
|
|
|
|
SSAAPS = null;
|
2019-12-04 01:33:27 +08:00
|
|
|
|
}
|
|
|
|
|
if (FinalVS != null)
|
|
|
|
|
{
|
|
|
|
|
FinalVS.Dispose();
|
|
|
|
|
FinalVS = null;
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void OnWindowResize(DXManager dxman)
|
|
|
|
|
{
|
|
|
|
|
DisposeBuffers();
|
|
|
|
|
|
|
|
|
|
var device = dxman.device;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
int uw = Width = dxman.backbuffer.Description.Width * SSAASampleCount;
|
|
|
|
|
int uh = Height = dxman.backbuffer.Description.Height * SSAASampleCount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
GBuffers = new GpuMultiTexture(device, uw, uh, 4, Format.R8G8B8A8_UNorm, true, Format.D32_Float, MSAASampleCount);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
WindowSizeVramUsage += GBuffers.VramUsage;
|
|
|
|
|
|
2019-12-04 01:33:27 +08:00
|
|
|
|
SceneColour = new GpuTexture(device, uw, uh, Format.R32G32B32A32_Float, 1, 0, true, Format.D32_Float);
|
|
|
|
|
WindowSizeVramUsage += SceneColour.VramUsage;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
public void DisposeBuffers()
|
|
|
|
|
{
|
|
|
|
|
if (GBuffers != null)
|
|
|
|
|
{
|
|
|
|
|
GBuffers.Dispose();
|
|
|
|
|
GBuffers = null;
|
|
|
|
|
}
|
2019-12-04 01:33:27 +08:00
|
|
|
|
if (SceneColour != null)
|
|
|
|
|
{
|
|
|
|
|
SceneColour.Dispose();
|
|
|
|
|
SceneColour = null;
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
WindowSizeVramUsage = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Clear(DeviceContext context)
|
|
|
|
|
{
|
2019-12-04 01:33:27 +08:00
|
|
|
|
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));
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
public void ClearDepth(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
GBuffers.ClearDepth(context);
|
2019-12-04 01:33:27 +08:00
|
|
|
|
SceneColour.ClearDepth(context);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
2019-12-04 01:33:27 +08:00
|
|
|
|
public void SetGBuffers(DeviceContext context)
|
2019-12-03 21:52:22 +08:00
|
|
|
|
{
|
|
|
|
|
GBuffers.SetRenderTargets(context);
|
|
|
|
|
context.Rasterizer.SetViewport(Viewport);
|
|
|
|
|
}
|
2019-12-04 01:33:27 +08:00
|
|
|
|
public void SetSceneColour(DeviceContext context)
|
|
|
|
|
{
|
|
|
|
|
SceneColour.SetRenderTarget(context);
|
|
|
|
|
context.Rasterizer.SetViewport(Viewport);
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
public void RenderLights(DeviceContext context, Camera camera, Shadowmap globalShadows, ShaderGlobalLights globalLights)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//first full-screen directional light pass, for sun/moon
|
|
|
|
|
//discard pixels where scene depth is 0, since nothing was rendered there
|
|
|
|
|
//blend mode: overwrite
|
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
var ps = (MSAASampleCount > 1) ? DirLightMSPS : DirLightPS;
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
context.VertexShader.Set(DirLightVS);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
context.PixelShader.Set(ps);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightVSVars.Vars.ViewProj = Matrix.Identity;
|
|
|
|
|
LightVSVars.Vars.CameraPos = Vector4.Zero;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
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);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightPSVars.Vars.CameraPos = Vector4.Zero;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
LightPSVars.Vars.EnableShadows = (globalShadows != null) ? 1u : 0u;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightPSVars.Vars.RenderMode = 0;
|
|
|
|
|
LightPSVars.Vars.RenderModeIndex = 1;
|
|
|
|
|
LightPSVars.Vars.RenderSamplerCoord = 0;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
LightPSVars.Vars.LightType = 0;
|
|
|
|
|
LightPSVars.Vars.IsLOD = 0;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightPSVars.Vars.SampleCount = (uint)MSAASampleCount;
|
|
|
|
|
LightPSVars.Vars.SampleMult = 1.0f / MSAASampleCount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
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
|
|
|
|
|
|
2019-12-04 17:14:11 +08:00
|
|
|
|
var ps = (MSAASampleCount > 1) ? LodLightMSPS : LodLightPS;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
context.VertexShader.Set(LodLightVS);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
context.PixelShader.Set(ps);
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
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.ViewProjInv = Matrix.Transpose(camera.ViewProjInvMatrix);
|
|
|
|
|
LightPSVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightPSVars.Vars.EnableShadows = 0;
|
|
|
|
|
LightPSVars.Vars.RenderMode = 0;
|
|
|
|
|
LightPSVars.Vars.RenderModeIndex = 1;
|
|
|
|
|
LightPSVars.Vars.RenderSamplerCoord = 0;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
LightPSVars.Vars.LightType = 0;
|
|
|
|
|
LightPSVars.Vars.IsLOD = 0;
|
2019-12-04 17:14:11 +08:00
|
|
|
|
LightPSVars.Vars.SampleCount = (uint)MSAASampleCount;
|
|
|
|
|
LightPSVars.Vars.SampleMult = 1.0f / MSAASampleCount;
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
|
|
|
|
context.PixelShader.SetShaderResources(0, GBuffers.DepthSRV);
|
|
|
|
|
context.PixelShader.SetShaderResources(2, GBuffers.SRVs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-05 00:40:52 +08:00
|
|
|
|
public void RenderLights(DeviceContext context, Camera camera, List<RenderableLightInst> lights)
|
|
|
|
|
{
|
|
|
|
|
//instanced rendering of all other lights, using appropriate shapes
|
|
|
|
|
//blend mode: additive
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var ps = (MSAASampleCount > 1) ? LightMSPS : LightPS;
|
|
|
|
|
|
|
|
|
|
context.VertexShader.Set(LightVS);
|
|
|
|
|
context.PixelShader.Set(ps);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
LightVSVars.Update(context);
|
|
|
|
|
LightVSVars.SetVSCBuffer(context, 0);
|
|
|
|
|
|
|
|
|
|
LightPSVars.Vars.ViewProjInv = Matrix.Transpose(camera.ViewProjInvMatrix);
|
|
|
|
|
LightPSVars.Vars.CameraPos = new Vector4(camera.Position, 0.0f);
|
|
|
|
|
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.SampleCount = (uint)MSAASampleCount;
|
|
|
|
|
LightPSVars.Vars.SampleMult = 1.0f / MSAASampleCount;
|
|
|
|
|
LightPSVars.Update(context);
|
|
|
|
|
LightPSVars.SetPSCBuffer(context, 0);
|
|
|
|
|
|
|
|
|
|
context.PixelShader.SetShaderResources(0, GBuffers.DepthSRV);
|
|
|
|
|
context.PixelShader.SetShaderResources(2, GBuffers.SRVs);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < lights.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var li = lights[i];
|
|
|
|
|
var rl = li.Light;
|
|
|
|
|
|
|
|
|
|
LightInstVars.Vars.InstPosition = li.EntityPosition + li.EntityRotation.Multiply(rl.Position) - camera.Position;
|
|
|
|
|
LightInstVars.Vars.InstDirection = li.EntityRotation.Multiply(rl.Direction);
|
|
|
|
|
LightInstVars.Vars.InstTangentX = li.EntityRotation.Multiply(rl.TangentX);
|
|
|
|
|
LightInstVars.Vars.InstTangentY = li.EntityRotation.Multiply(rl.TangentY);
|
|
|
|
|
LightInstVars.Vars.InstCapsuleExtent = li.EntityRotation.Multiply(rl.CapsuleExtent);
|
|
|
|
|
LightInstVars.Vars.InstCullingPlaneNormal = li.EntityRotation.Multiply(rl.CullingPlaneNormal);
|
|
|
|
|
LightInstVars.Vars.InstColour = rl.Colour;
|
|
|
|
|
LightInstVars.Vars.InstIntensity = rl.Intensity;
|
|
|
|
|
LightInstVars.Vars.InstFalloff = rl.Falloff;
|
|
|
|
|
LightInstVars.Vars.InstFalloffExponent = rl.FalloffExponent;
|
|
|
|
|
LightInstVars.Vars.InstConeInnerAngle = rl.ConeInnerAngle;
|
|
|
|
|
LightInstVars.Vars.InstConeOuterAngle = rl.ConeOuterAngle;
|
|
|
|
|
LightInstVars.Vars.InstType = (uint)rl.Type;
|
|
|
|
|
LightInstVars.Vars.InstCullingPlaneOffset = rl.CullingPlaneOffset;
|
|
|
|
|
LightInstVars.Update(context);
|
|
|
|
|
LightInstVars.SetVSCBuffer(context, 1);
|
|
|
|
|
LightInstVars.SetPSCBuffer(context, 2);
|
|
|
|
|
|
|
|
|
|
switch (rl.Type)
|
|
|
|
|
{
|
|
|
|
|
case LightType.Point:
|
|
|
|
|
LightSphere.Draw(context);
|
|
|
|
|
break;
|
|
|
|
|
case LightType.Spot:
|
|
|
|
|
LightCone.Draw(context);
|
|
|
|
|
break;
|
|
|
|
|
case LightType.Capsule:
|
|
|
|
|
LightCapsule.Draw(context);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-05 00:40:52 +08:00
|
|
|
|
context.VertexShader.Set(null);
|
|
|
|
|
context.PixelShader.Set(null);
|
|
|
|
|
context.PixelShader.SetShaderResources(0, null, null, null);
|
|
|
|
|
context.PixelShader.SetSamplers(0, null, null);
|
|
|
|
|
}
|
2019-12-03 21:52:22 +08:00
|
|
|
|
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
public void SSAAPass(DeviceContext context)
|
2019-12-04 01:33:27 +08:00
|
|
|
|
{
|
2019-12-04 14:54:48 +08:00
|
|
|
|
//do antialiasing from SceneColour
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
|
|
|
|
context.VertexShader.Set(FinalVS);
|
2019-12-04 14:54:48 +08:00
|
|
|
|
context.PixelShader.Set(SSAAPS);
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
|
|
|
|
context.PixelShader.SetShaderResources(0, SceneColour.SRV);
|
|
|
|
|
context.PixelShader.SetSamplers(0, SampleStatePoint);
|
|
|
|
|
|
2019-12-04 14:54:48 +08:00
|
|
|
|
SSAAPSVars.Vars.SampleCount = (uint)SSAASampleCount;
|
|
|
|
|
SSAAPSVars.Vars.SampleMult = 1.0f / (SSAASampleCount * SSAASampleCount);
|
|
|
|
|
SSAAPSVars.Vars.TexelSizeX = 1.0f / Width;
|
|
|
|
|
SSAAPSVars.Vars.TexelSizeY = 1.0f / Height;
|
|
|
|
|
SSAAPSVars.Update(context);
|
|
|
|
|
SSAAPSVars.SetPSCBuffer(context, 0);
|
2019-12-04 01:33:27 +08:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-12-03 21:52:22 +08:00
|
|
|
|
}
|
|
|
|
|
}
|