From 9a53c2147b0176e5fc64ea451bf8ddae52c3a890 Mon Sep 17 00:00:00 2001 From: dexy Date: Wed, 4 Dec 2019 00:52:22 +1100 Subject: [PATCH] Deferred shading --- App.config | 3 + .../GameFiles/FileTypes/YmapFile.cs | 1 + .../GameFiles/Resources/Drawable.cs | 29 +- CodeWalker.Core/Utils/Vectors.cs | 21 + CodeWalker.Shaders/BasicPS.hlsl | 62 +-- CodeWalker.Shaders/BasicPS.hlsli | 71 +++ CodeWalker.Shaders/BasicPS_Deferred.hlsl | 171 ++++++++ CodeWalker.Shaders/CablePS.hlsl | 39 +- CodeWalker.Shaders/CablePS.hlsli | 46 ++ CodeWalker.Shaders/CablePS_Deferred.hlsl | 71 +++ CodeWalker.Shaders/CodeWalker.Shaders.vcxproj | 75 ++++ .../CodeWalker.Shaders.vcxproj.filters | 412 ++++++++++++++---- CodeWalker.Shaders/Common.hlsli | 2 +- CodeWalker.Shaders/LightPS.hlsl | 161 +++++++ CodeWalker.Shaders/LightVS.hlsl | 76 ++++ CodeWalker.Shaders/TerrainPS.hlsl | 59 +-- CodeWalker.Shaders/TerrainPS.hlsli | 67 +++ CodeWalker.Shaders/TerrainPS_Deferred.hlsl | 227 ++++++++++ CodeWalker.Shaders/TreesLodPS.hlsl | 28 +- CodeWalker.Shaders/TreesLodPS.hlsli | 35 ++ CodeWalker.Shaders/TreesLodPS_Deferred.hlsl | 35 ++ CodeWalker.Shaders/WaterPS.hlsl | 126 +----- CodeWalker.Shaders/WaterPS.hlsli | 133 ++++++ CodeWalker.Shaders/WaterPS_Deferred.hlsl | 105 +++++ CodeWalker.csproj | 2 + Forms/ModelForm.cs | 3 + PedsForm.cs | 2 + Project/Panels/GenerateLODLightsPanel.cs | 8 +- Properties/Settings.Designer.cs | 12 + Properties/Settings.settings | 3 + Rendering/Renderable.cs | 154 ++++++- Rendering/RenderableCache.cs | 17 +- Rendering/Renderer.cs | 39 +- Rendering/ShaderManager.cs | 128 +++++- Rendering/Shaders/BasicShader.cs | 7 +- Rendering/Shaders/CableShader.cs | 7 +- Rendering/Shaders/DeferredScene.cs | 375 ++++++++++++++++ Rendering/Shaders/TerrainShader.cs | 7 +- Rendering/Shaders/TreesLodShader.cs | 22 +- Rendering/Shaders/WaterShader.cs | 7 +- Rendering/Utils/GpuBuffers.cs | 129 ++++++ Rendering/Utils/UnitCapsule.cs | 6 +- Rendering/Utils/UnitCone.cs | 152 +++++++ Rendering/Utils/UnitSphere.cs | 6 +- Shaders/BasicPS.cso | Bin 11048 -> 11076 bytes Shaders/BasicPS_Deferred.cso | Bin 0 -> 6468 bytes Shaders/CablePS.cso | Bin 7084 -> 7112 bytes Shaders/CablePS_Deferred.cso | Bin 0 -> 3088 bytes Shaders/LightPS.cso | Bin 0 -> 10036 bytes Shaders/LightVS.cso | Bin 0 -> 3056 bytes Shaders/TerrainPS.cso | Bin 13296 -> 13324 bytes Shaders/TerrainPS_Deferred.cso | Bin 0 -> 9312 bytes Shaders/TreesLodPS.cso | Bin 2056 -> 2084 bytes Shaders/TreesLodPS_Deferred.cso | Bin 0 -> 1352 bytes Shaders/WaterPS.cso | Bin 10084 -> 9888 bytes Shaders/WaterPS_Deferred.cso | Bin 0 -> 5832 bytes VehicleForm.cs | 2 + WorldForm.Designer.cs | 32 +- WorldForm.cs | 10 + WorldForm.resx | 48 +- 60 files changed, 2724 insertions(+), 509 deletions(-) create mode 100644 CodeWalker.Shaders/BasicPS.hlsli create mode 100644 CodeWalker.Shaders/BasicPS_Deferred.hlsl create mode 100644 CodeWalker.Shaders/CablePS.hlsli create mode 100644 CodeWalker.Shaders/CablePS_Deferred.hlsl create mode 100644 CodeWalker.Shaders/LightPS.hlsl create mode 100644 CodeWalker.Shaders/LightVS.hlsl create mode 100644 CodeWalker.Shaders/TerrainPS.hlsli create mode 100644 CodeWalker.Shaders/TerrainPS_Deferred.hlsl create mode 100644 CodeWalker.Shaders/TreesLodPS.hlsli create mode 100644 CodeWalker.Shaders/TreesLodPS_Deferred.hlsl create mode 100644 CodeWalker.Shaders/WaterPS.hlsli create mode 100644 CodeWalker.Shaders/WaterPS_Deferred.hlsl create mode 100644 Rendering/Shaders/DeferredScene.cs create mode 100644 Rendering/Utils/UnitCone.cs create mode 100644 Shaders/BasicPS_Deferred.cso create mode 100644 Shaders/CablePS_Deferred.cso create mode 100644 Shaders/LightPS.cso create mode 100644 Shaders/LightVS.cso create mode 100644 Shaders/TerrainPS_Deferred.cso create mode 100644 Shaders/TreesLodPS_Deferred.cso create mode 100644 Shaders/WaterPS_Deferred.cso diff --git a/App.config b/App.config index b4b2dcc..337f17b 100644 --- a/App.config +++ b/App.config @@ -202,6 +202,9 @@ Windows + + True + diff --git a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs index fa43fc6..6aa15e3 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/YmapFile.cs @@ -38,6 +38,7 @@ namespace CodeWalker.GameFiles public YmapEntityDef[] RootEntities; public YmapEntityDef[] MloEntities; + public YmapFile Parent { get; set; } public YmapFile[] ChildYmaps = null; public bool MergedWithParent = false; diff --git a/CodeWalker.Core/GameFiles/Resources/Drawable.cs b/CodeWalker.Core/GameFiles/Resources/Drawable.cs index c0c3e7f..b5888db 100644 --- a/CodeWalker.Core/GameFiles/Resources/Drawable.cs +++ b/CodeWalker.Core/GameFiles/Resources/Drawable.cs @@ -2335,14 +2335,19 @@ namespace CodeWalker.GameFiles } + public enum LightType : byte + { + Point = 1, + Spot = 2, + Capsule = 4, + } + [TypeConverter(typeof(ExpandableObjectConverter))] public struct LightAttributes_s { // structure data public uint Unknown_0h { get; set; } // 0x00000000 public uint Unknown_4h { get; set; } // 0x00000000 - public float PositionX { get; set; } - public float PositionY { get; set; } - public float PositionZ { get; set; } + public Vector3 Position { get; set; } public uint Unknown_14h { get; set; } // 0x00000000 public byte ColorR { get; set; } public byte ColorG { get; set; } @@ -2351,14 +2356,12 @@ namespace CodeWalker.GameFiles public float Intensity { get; set; } public uint Flags { get; set; } public ushort BoneId { get; set; } - public byte Type { get; set; } + public LightType Type { get; set; } public byte GroupId { get; set; } public uint TimeFlags { get; set; } public float Falloff { get; set; } public float FalloffExponent { get; set; } - public float CullingPlaneNormalX { get; set; } - public float CullingPlaneNormalY { get; set; } - public float CullingPlaneNormalZ { get; set; } + public Vector3 CullingPlaneNormal { get; set; } public float CullingPlaneOffset { get; set; } public byte ShadowBlur { get; set; } public byte Unknown_45h { get; set; } @@ -2380,17 +2383,11 @@ namespace CodeWalker.GameFiles public float ShadowNearClip { get; set; } public float CoronaIntensity { get; set; } public float CoronaZBias { get; set; } - public float DirectionX { get; set; } - public float DirectionY { get; set; } - public float DirectionZ { get; set; } - public float TangentX { get; set; } - public float TangentY { get; set; } - public float TangentZ { get; set; } + public Vector3 Direction { get; set; } + public Vector3 Tangent { get; set; } public float ConeInnerAngle { get; set; } public float ConeOuterAngle { get; set; } - public float ExtentX { get; set; } - public float ExtentY { get; set; } - public float ExtentZ { get; set; } + public Vector3 Extent { get; set; } public uint ProjectedTextureHash { get; set; } public uint Unknown_A4h { get; set; } // 0x00000000 } diff --git a/CodeWalker.Core/Utils/Vectors.cs b/CodeWalker.Core/Utils/Vectors.cs index b7552bd..ee8d91e 100644 --- a/CodeWalker.Core/Utils/Vectors.cs +++ b/CodeWalker.Core/Utils/Vectors.cs @@ -20,6 +20,27 @@ namespace CodeWalker return new Vector3((float)Math.Round(v.X), (float)Math.Round(v.Y), (float)Math.Round(v.Z)); } + public static Vector3 GetPerpVec(this Vector3 n) + { + //make a vector perpendicular to the given one + float nx = Math.Abs(n.X); + float ny = Math.Abs(n.Y); + float nz = Math.Abs(n.Z); + if ((nx < ny) && (nx < nz)) + { + return Vector3.Cross(n, Vector3.Right); + } + else if (ny < nz) + { + return Vector3.Cross(n, Vector3.Up); + } + else + { + return Vector3.Cross(n, Vector3.ForwardLH); + } + } + + public static Vector4 Floor(this Vector4 v) { return new Vector4((float)Math.Floor(v.X), (float)Math.Floor(v.Y), (float)Math.Floor(v.Z), (float)Math.Floor(v.W)); diff --git a/CodeWalker.Shaders/BasicPS.hlsl b/CodeWalker.Shaders/BasicPS.hlsl index 51524c6..1dfe4e8 100644 --- a/CodeWalker.Shaders/BasicPS.hlsl +++ b/CodeWalker.Shaders/BasicPS.hlsl @@ -1,64 +1,4 @@ -#include "Shadowmap.hlsli" - -Texture2D Colourmap : register(t0); -Texture2D Bumpmap : register(t2); -Texture2D Specmap : register(t3); -Texture2D Detailmap : register(t4); -Texture2D Colourmap2 : register(t5); -Texture2D TintPalette : register(t6); -SamplerState TextureSS : register(s0); - - -cbuffer PSSceneVars : register(b0) -{ - ShaderGlobalLightParams GlobalLights; - uint EnableShadows; - uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct - uint RenderModeIndex; - uint RenderSamplerCoord; -} -cbuffer PSGeomVars : register(b2) -{ - uint EnableTexture;//1+=diffuse1, 2+=diffuse2 - uint EnableTint;//1=default, 2=weapons (use diffuse.a for tint lookup) - uint EnableNormalMap; - uint EnableSpecMap; - uint EnableDetailMap; - uint IsDecal; - uint IsEmissive; - uint IsDistMap; - float bumpiness; - float AlphaScale; - float HardAlphaBlend; - float useTessellation; - float4 detailSettings; - float3 specMapIntMask; - float specularIntensityMult; - float specularFalloffMult; - float specularFresnel; - float wetnessMultiplier; - uint SpecOnly; - float4 TextureAlphaMask; -} - - -struct VS_OUTPUT -{ - float4 Position : SV_POSITION; - float3 Normal : NORMAL; - float2 Texcoord0 : TEXCOORD0; - float2 Texcoord1 : TEXCOORD1; - float2 Texcoord2 : TEXCOORD2; - float4 Shadows : TEXCOORD3; - float4 LightShadow : TEXCOORD4; - float4 Colour0 : COLOR0; - float4 Colour1 : COLOR1; - float4 Tint : COLOR2; - float4 Tangent : TEXCOORD5; - float4 Bitangent : TEXCOORD6; - float3 CamRelPos : TEXCOORD7; -}; - +#include "BasicPS.hlsli" float4 main(VS_OUTPUT input) : SV_TARGET diff --git a/CodeWalker.Shaders/BasicPS.hlsli b/CodeWalker.Shaders/BasicPS.hlsli new file mode 100644 index 0000000..6b6b559 --- /dev/null +++ b/CodeWalker.Shaders/BasicPS.hlsli @@ -0,0 +1,71 @@ +#include "Shadowmap.hlsli" + +Texture2D Colourmap : register(t0); +Texture2D Bumpmap : register(t2); +Texture2D Specmap : register(t3); +Texture2D Detailmap : register(t4); +Texture2D Colourmap2 : register(t5); +Texture2D TintPalette : register(t6); +SamplerState TextureSS : register(s0); + + +cbuffer PSSceneVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; + uint EnableShadows; + uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct + uint RenderModeIndex; + uint RenderSamplerCoord; +} +cbuffer PSGeomVars : register(b2) +{ + uint EnableTexture;//1+=diffuse1, 2+=diffuse2 + uint EnableTint;//1=default, 2=weapons (use diffuse.a for tint lookup) + uint EnableNormalMap; + uint EnableSpecMap; + uint EnableDetailMap; + uint IsDecal; + uint IsEmissive; + uint IsDistMap; + float bumpiness; + float AlphaScale; + float HardAlphaBlend; + float useTessellation; + float4 detailSettings; + float3 specMapIntMask; + float specularIntensityMult; + float specularFalloffMult; + float specularFresnel; + float wetnessMultiplier; + uint SpecOnly; + float4 TextureAlphaMask; +} + + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + float3 Normal : NORMAL; + float2 Texcoord0 : TEXCOORD0; + float2 Texcoord1 : TEXCOORD1; + float2 Texcoord2 : TEXCOORD2; + float4 Shadows : TEXCOORD3; + float4 LightShadow : TEXCOORD4; + float4 Colour0 : COLOR0; + float4 Colour1 : COLOR1; + float4 Tint : COLOR2; + float4 Tangent : TEXCOORD5; + float4 Bitangent : TEXCOORD6; + float3 CamRelPos : TEXCOORD7; +}; + +struct PS_OUTPUT +{ + float4 Diffuse : SV_Target0; + float4 Normal : SV_Target1; + float4 Specular : SV_Target2; + float4 Irradiance : SV_Target3; +}; + + + diff --git a/CodeWalker.Shaders/BasicPS_Deferred.hlsl b/CodeWalker.Shaders/BasicPS_Deferred.hlsl new file mode 100644 index 0000000..6dcda36 --- /dev/null +++ b/CodeWalker.Shaders/BasicPS_Deferred.hlsl @@ -0,0 +1,171 @@ +#include "BasicPS.hlsli" + + +PS_OUTPUT main(VS_OUTPUT input) +{ + float4 c = float4(0.5, 0.5, 0.5, 1); + if (RenderMode == 0) c = float4(1, 1, 1, 1); + if (EnableTexture > 0) + { + float2 texc = input.Texcoord0; + if (RenderMode >= 5) + { + if (RenderSamplerCoord == 2) + texc = input.Texcoord1; + else if (RenderSamplerCoord == 3) + texc = input.Texcoord2; + } + + c = Colourmap.Sample(TextureSS, texc); + + if (EnableTexture > 1) //2+ enables diffuse2 + { + float4 c2 = Colourmap2.Sample(TextureSS, input.Texcoord1); + c = c2.a * c2 + (1 - c2.a) * c; + } + if (EnableTint == 2) + { + //weapon tint + float tx = (round(c.a * 255.009995) - 32.0) * 0.007813; //okay R* this is just silly + float ty = 0.03125 * 0.5; // //1;//what to use for Y value? cb12[2].w in R* shader + float4 c3 = TintPalette.Sample(TextureSS, float2(tx, ty)); + c.rgb *= c3.rgb; + c.a = 1; + } + + if (IsDistMap) c = float4(c.rgb * 2, (c.r + c.g + c.b) - 1); + if ((IsDecal == 0) && (c.a <= 0.33)) discard; + if ((IsDecal == 1) && (c.a <= 0.0)) discard; + if (IsDecal == 0) c.a = 1; + if (IsDecal == 2) + { + float4 mask = TextureAlphaMask * c; + c.a = saturate(mask.r + mask.g + mask.b + mask.a); + c.rgb = 0; + } + c.a = saturate(c.a * AlphaScale); + } + if (EnableTint == 1) + { + c.rgb *= input.Tint.rgb; + } + if (IsDecal == 1) + { + c.a *= input.Colour0.a; + } + + float3 norm = normalize(input.Normal); + + if (RenderMode == 1) //normals + { + c.rgb = norm * 0.5 + 0.5; + } + else if (RenderMode == 2) //tangents + { + c.rgb = normalize(input.Tangent.rgb) * 0.5 + 0.5; + } + else if (RenderMode == 3) //colours + { + c.rgb = input.Colour0.rgb; + if (RenderModeIndex == 2) + c.rgb = input.Colour1.rgb; + } + else if (RenderMode == 4) //texcoords + { + c.rgb = float3(input.Texcoord0, 0); + if (RenderModeIndex == 2) c.rgb = float3(input.Texcoord1, 0); + if (RenderModeIndex == 3) c.rgb = float3(input.Texcoord2, 0); + } + + + float3 spec = 0; + + if (RenderMode == 0) + { + + float4 nv = Bumpmap.Sample(TextureSS, input.Texcoord0); + float4 sv = Specmap.Sample(TextureSS, input.Texcoord0); + + + float2 nmv = nv.xy; + float4 r0 = 0, r1, r2, r3; + + if (EnableNormalMap) + { + if (EnableDetailMap) + { + //detail normalmapp + r0.xy = input.Texcoord0 * detailSettings.zw; + r0.zw = r0.xy * 3.17; + r0.xy = Detailmap.Sample(TextureSS, r0.xy).xy - 0.5; + r0.zw = Detailmap.Sample(TextureSS, r0.zw).xy - 0.5; + r0.xy = r0.xy + r0.zw; + r0.yz = r0.xy * detailSettings.y; //r0.x = -r0.x*detailSettings.x; + nmv = r0.yz * sv.w + nv.xy; //add detail to normal, using specmap(!) + } + + norm = NormalMap(nmv, bumpiness, input.Normal.xyz, input.Tangent.xyz, input.Bitangent.xyz); + + + } + + + + if (EnableSpecMap == 0) + { + sv = float4(0.1, 0.1, 0.1, 0.1); + } + + float r1y = norm.z - 0.35; + + float3 globalScalars = float3(0.5, 0.5, 0.5); + float globalScalars2z = 1; // 0.65; //wet darkness? + float wetness = 0; // 10.0; + + r0.x = 0; // .5; + r0.z = 1 - globalScalars2z; + r0.y = saturate(r1y * 1.538462); + r0.y = r0.y * wetness; + r0.y = r0.y * r0.z; + r1.yz = input.Colour0.xy * globalScalars.zy; + r0.y = r0.y * r1.y; + r0.x = r0.x * sv.w + 1.0; + sv.xy = sv.xy * sv.xy; + r0.z = sv.w * specularFalloffMult; + r3.y = r0.z * 0.001953125; // (1/512) + r0.z = dot(sv.xyz, specMapIntMask); + r0.z = r0.z * specularIntensityMult; + r3.x = r0.x * r0.z; + r0.z = saturate(r0.z * r0.x + 0.4); + r0.z = 1 - r3.x * 0.5; + r0.z = r0.z * r0.y; + r0.y = r0.y * wetnessMultiplier; + r0.z = 1 - r0.z * 0.5; + + float3 tc = c.rgb * r0.x; + c.rgb = tc * r0.z; //diffuse factors... + + + spec.xy = sqrt(r3.xy); + spec.z = r0.z; + + } + + + float emiss = (IsEmissive == 1) ? 1.0 : 0.0; + + c.a = saturate(c.a); + + + + PS_OUTPUT output; + output.Diffuse = c; + output.Normal = float4(saturate(norm * 0.5 + 0.5), c.a); + output.Specular = float4(spec, c.a); + output.Irradiance = float4(input.Colour0.rg, emiss, c.a); + + return output; +} + + + diff --git a/CodeWalker.Shaders/CablePS.hlsl b/CodeWalker.Shaders/CablePS.hlsl index 7cc16d5..44d0326 100644 --- a/CodeWalker.Shaders/CablePS.hlsl +++ b/CodeWalker.Shaders/CablePS.hlsl @@ -1,41 +1,4 @@ -#include "Shadowmap.hlsli" - -Texture2D Colourmap : register(t0); -SamplerState TextureSS : register(s0); - - -cbuffer PSSceneVars : register(b0) -{ - ShaderGlobalLightParams GlobalLights; - uint EnableShadows; - uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct - uint RenderModeIndex; - uint RenderSamplerCoord; -} -cbuffer PSGeomVars : register(b2) -{ - uint EnableTexture; - uint EnableTint; - uint Pad100; - uint Pad101; -} - - -struct VS_OUTPUT -{ - float4 Position : SV_POSITION; - float3 Normal : NORMAL; - float2 Texcoord0 : TEXCOORD0; - float2 Texcoord1 : TEXCOORD1; - float2 Texcoord2 : TEXCOORD2; - float4 Shadows : TEXCOORD3; - float4 LightShadow : TEXCOORD4; - float4 Colour0 : COLOR0; - float4 Colour1 : COLOR1; - float4 Tint : COLOR2; - float4 Tangent : TANGENT; -}; - +#include "CablePS.hlsli" float4 main(VS_OUTPUT input) : SV_TARGET diff --git a/CodeWalker.Shaders/CablePS.hlsli b/CodeWalker.Shaders/CablePS.hlsli new file mode 100644 index 0000000..a1e64ab --- /dev/null +++ b/CodeWalker.Shaders/CablePS.hlsli @@ -0,0 +1,46 @@ +#include "Shadowmap.hlsli" + +Texture2D Colourmap : register(t0); +SamplerState TextureSS : register(s0); + + +cbuffer PSSceneVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; + uint EnableShadows; + uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct + uint RenderModeIndex; + uint RenderSamplerCoord; +} +cbuffer PSGeomVars : register(b2) +{ + uint EnableTexture; + uint EnableTint; + uint Pad100; + uint Pad101; +} + + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + float3 Normal : NORMAL; + float2 Texcoord0 : TEXCOORD0; + float2 Texcoord1 : TEXCOORD1; + float2 Texcoord2 : TEXCOORD2; + float4 Shadows : TEXCOORD3; + float4 LightShadow : TEXCOORD4; + float4 Colour0 : COLOR0; + float4 Colour1 : COLOR1; + float4 Tint : COLOR2; + float4 Tangent : TANGENT; +}; + +struct PS_OUTPUT +{ + float4 Diffuse : SV_Target0; + float4 Normal : SV_Target1; + float4 Specular : SV_Target2; + float4 Irradiance : SV_Target3; +}; + diff --git a/CodeWalker.Shaders/CablePS_Deferred.hlsl b/CodeWalker.Shaders/CablePS_Deferred.hlsl new file mode 100644 index 0000000..91b89e8 --- /dev/null +++ b/CodeWalker.Shaders/CablePS_Deferred.hlsl @@ -0,0 +1,71 @@ +#include "CablePS.hlsli" + + +PS_OUTPUT main(VS_OUTPUT input) +{ + float4 c = float4(0.2, 0.2, 0.2, 1); + if (EnableTexture == 1) + { + float2 texc = input.Texcoord0; + if (RenderMode >= 5) + { + if (RenderSamplerCoord == 2) texc = input.Texcoord1; + else if (RenderSamplerCoord == 3) texc = input.Texcoord2; + } + + c = Colourmap.Sample(TextureSS, texc); + //c = Depthmap.SampleLevel(DepthmapSS, input.Texcoord, 0); c.a = 1; + //if ((IsDecal == 0) && (c.a <= 0.33)) discard; + //if ((IsDecal == 1) && (c.a <= 0.0)) discard; + //if(IsDecal==0) c.a = 1; + c.a = 1; + } + //else //if(RenderMode!=8)// + //{ + // c = float4(input.Colour0.rgb, 1); + //} + if (EnableTint > 0) + { + c.rgb *= input.Tint.rgb; + } + //if (IsDecal == 1) + //{ + // c.a *= input.Colour0.a; + //} + + float3 norm = normalize(input.Normal); + + if (RenderMode == 1) //normals + { + c.rgb = norm*0.5+0.5; + } + else if (RenderMode == 2) //tangents + { + c.rgb = normalize(input.Tangent.rgb)*0.5+0.5; + } + else if (RenderMode == 3) //colours + { + c.rgb = input.Colour0.rgb; + if (RenderModeIndex == 2) c.rgb = input.Colour1.rgb; + } + else if (RenderMode == 4) //texcoords + { + c.rgb = float3(input.Texcoord0, 0); + if (RenderModeIndex == 2) c.rgb = float3(input.Texcoord1, 0); + if (RenderModeIndex == 3) c.rgb = float3(input.Texcoord2, 0); + } + + + + float3 spec = 0; + + c.a = saturate(c.a); + + PS_OUTPUT output; + output.Diffuse = c; + output.Normal = float4(saturate(norm * 0.5 + 0.5), c.a); + output.Specular = float4(spec, c.a); + output.Irradiance = float4(input.Colour0.rg, 0, c.a); + + return output; +} \ No newline at end of file diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj index 64cf840..6c40aed 100644 --- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj +++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj @@ -132,6 +132,16 @@ Pixel Pixel + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Vertex Vertex @@ -344,6 +354,16 @@ Pixel Pixel + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Vertex Vertex @@ -374,6 +394,26 @@ Vertex Vertex + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + + + Vertex + 4.0 + Vertex + 4.0 + Vertex + 4.0 + Vertex + 4.0 + Pixel Pixel @@ -548,6 +588,16 @@ Pixel Pixel + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Vertex Vertex @@ -596,6 +646,16 @@ Pixel Pixel + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Vertex Vertex @@ -608,6 +668,16 @@ Pixel Pixel + + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Pixel + 4.0 + Vertex Vertex @@ -646,13 +716,18 @@ + + + + + diff --git a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters index 1d5f731..ba0924b 100644 --- a/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters +++ b/CodeWalker.Shaders/CodeWalker.Shaders.vcxproj.filters @@ -1,90 +1,336 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Basic + + + Bounds + + + Bounds + + + Bounds + + + Cable + + + Cable + + + Cable + + + Sky + + + Sky + + + Sky + + + Sky + + + Sky + + + Sky + + + Sky + + + Sky + + + Markers + + + Markers + + + Paths + + + Paths + + + Paths + + + Paths + + + Paths + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + PostProcessor + + + Shadows + + + Shadows + + + Shadows + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Terrain + + + Trees + + + Trees + + + Trees + + + Water + + + Water + + + Water + + + Water + + + Water + + + Water + + + Widget + + + Widget + + + Lights + + + Lights + + + Lights + + + Lights + - - - - - - - - + + Basic + + + Basic + + + Cable + + + Sky + + + Sky + + + Common + + + Common + + + Shadows + + + Terrain + + + Terrain + + + Trees + + + Water + + + Water + + + + + {2d5fa9c1-ac2c-4820-b3a2-e3417e5b4a75} + + + {7b12481e-7e7c-45a2-aa19-26cf35acf33d} + + + {2fa3ba6e-67fe-49a0-bd2c-2b3b45702285} + + + {5fdc8b34-5e82-4786-9d6d-1af2248575b2} + + + {0b5779e8-ab81-41e3-88e4-849c66a7a171} + + + {8f404e01-a627-4d6d-9037-c073a687d61d} + + + {6d63039e-7ce7-48f9-a503-76ec3782b5b0} + + + {1d840a5b-3c41-4c7a-a363-6607e269b27b} + + + {baaa8dee-0bc4-4b05-95a1-882640344212} + + + {03608a54-3337-4feb-b010-3a454a02c4c0} + + + {f43e28c7-ea51-4960-a602-db412ac6bd2a} + + + {342884aa-960f-460a-9d63-93cacab48de5} + + + {160d1dee-4be7-43ad-a6a8-511a8bb13865} + + + {215eb704-917e-43c0-8d5b-d24e75403db3} + \ No newline at end of file diff --git a/CodeWalker.Shaders/Common.hlsli b/CodeWalker.Shaders/Common.hlsli index 68bc413..8f4747e 100644 --- a/CodeWalker.Shaders/Common.hlsli +++ b/CodeWalker.Shaders/Common.hlsli @@ -139,7 +139,7 @@ float3 GlobalLighting(float3 diff, float3 norm, float4 vc0, float lf, uniform Sh { float3 c = saturate(diff); float3 fc = c; - float naturalDiffuseFactor = 1.0; + float naturalDiffuseFactor = vc0.r; float artificialDiffuseFactor = saturate(vc0.g); c *= BasicLighting(globalLights.LightDirColour, globalLights.LightDirAmbColour, lf); c += AmbientLight(fc, norm.z, globalLights.LightNaturalAmbUp, globalLights.LightNaturalAmbDown, naturalDiffuseFactor); diff --git a/CodeWalker.Shaders/LightPS.hlsl b/CodeWalker.Shaders/LightPS.hlsl new file mode 100644 index 0000000..a6a9404 --- /dev/null +++ b/CodeWalker.Shaders/LightPS.hlsl @@ -0,0 +1,161 @@ +#include "Shadowmap.hlsli" + + +struct LODLight +{ + float3 Position; + uint Colour; + float3 Direction; + uint TimeAndStateFlags; + float4 TangentX; + float4 TangentY; + float Falloff; + float FalloffExponent; + float InnerAngle; //for cone + float OuterAngleOrCapExt; //outer angle for cone, cap extent for capsule +}; + +struct VS_Output +{ + float4 Pos : SV_POSITION; + float4 Screen : TEXCOORD0; + uint IID : SV_INSTANCEID; +}; + +struct PS_OUTPUT +{ + float4 Colour : SV_TARGET; + float Depth : SV_DEPTH; +}; + + +Texture2D DepthTex : register(t0); +Texture2D DiffuseTex : register(t2); +Texture2D NormalTex : register(t3); +Texture2D SpecularTex : register(t4); +Texture2D IrradianceTex : register(t5); + + + +cbuffer PSLightVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; + float4x4 ViewProjInv; + float4 CameraPos; + uint EnableShadows; + uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct + uint RenderModeIndex; + uint RenderSamplerCoord; + uint LightType; //0=directional, 1=Point, 2=Spot, 4=Capsule + uint IsLOD; //useful or not? + uint Pad0; + uint Pad1; +} + +StructuredBuffer LODLights : register(t6); + + + + +PS_OUTPUT main(VS_Output input) +{ + PS_OUTPUT output; + output.Depth = input.Pos.z; + + uint3 ssloc = uint3(input.Pos.xy, 0); //pixel location + float depth = DepthTex.Load(ssloc).r; + float4 diffuse = DiffuseTex.Load(ssloc); + float4 normal = NormalTex.Load(ssloc); + float4 specular = SpecularTex.Load(ssloc); + float4 irradiance = IrradianceTex.Load(ssloc); + + if (depth == 0) discard; //no existing pixel rendered here + + switch (RenderMode) + { + case 5: output.Colour = float4(diffuse.rgb, 1); return output; + case 6: output.Colour = float4(normal.rgb, 1); return output; + case 7: output.Colour = float4(specular.rgb, 1); return output; + } + + + float4 spos = float4(input.Screen.xy/input.Screen.w, depth, 1); + float4 cpos = mul(spos, ViewProjInv); + float3 camRel = cpos.xyz * (1/cpos.w); + + float3 norm = normal.xyz * 2 - 1; + + float3 incident = normalize(camRel); + float3 refl = normalize(reflect(incident, norm)); + + if (LightType == 0) //directional light + { + float specb = saturate(dot(refl, GlobalLights.LightDir)); + float specp = max(exp(specb * 10) - 1, 0); + float3 spec = GlobalLights.LightDirColour.rgb * 0.00006 * specp * specular.r; + float4 lightspacepos; + float shadowdepth = ShadowmapSceneDepth(camRel, lightspacepos); + float3 c = FullLighting(diffuse.rgb, spec, norm, irradiance, GlobalLights, EnableShadows, shadowdepth, lightspacepos); + + c += diffuse.rgb * irradiance.b;//emissive multiplier + + PS_OUTPUT output; + output.Colour = float4(c, 1); + output.Depth = depth; + return output; + } + + float3 wpos = camRel + CameraPos.xyz; + + LODLight lodlight = LODLights[input.IID]; + float3 srpos = lodlight.Position - wpos; //light position relative to surface position + float ldist = length(srpos); + if (ldist > lodlight.Falloff) discard; //out of range of the light... TODO: capsules! + if (ldist <= 0) discard; + + float4 rgbi = Unpack4x8UNF(lodlight.Colour).gbar; + float3 lcol = rgbi.rgb * rgbi.a * 5.0f; + + float3 ldir = srpos / ldist; + float pclit = saturate(dot(ldir, norm)); + float lamt = 1; + + if (LightType == 1)//point (sphere) + { + lamt *= saturate(1 - (ldist / lodlight.Falloff)); + } + else if (LightType == 2)//spot (cone) + { + float ang = acos(-dot(ldir, lodlight.Direction)); + float iang = lodlight.InnerAngle * 0.01745329; + float oang = lodlight.OuterAngleOrCapExt * 0.01745329 * 0.5; + if (ang > oang) discard; + lamt *= saturate(1 - ((ang - iang) / (oang - iang))); + lamt *= saturate(1 - (ldist / lodlight.Falloff)); + } + else if (LightType == 4)//capsule + { + lamt *= saturate(1 - (ldist / lodlight.Falloff)); //TODO! proper capsule lighting... (use point-line dist!) + } + + pclit *= lamt; + + if (pclit <= 0) discard; + + float specb = saturate(dot(refl, ldir)); + float specp = max(exp(specb * 10) - 1, 0); + float3 spec = lcol * (0.00006 * specp * specular.r * lamt); + + + lcol = lcol * diffuse.rgb * pclit + spec; + + + output.Colour = float4(lcol, 0.5); + return output; + + //return float4(diffuse.rgb, 1); + //return float4(normal.rgb, 1); + //return float4(specular.rgb, 1); + //return float4(irradiance.rgb, 1); +} + diff --git a/CodeWalker.Shaders/LightVS.hlsl b/CodeWalker.Shaders/LightVS.hlsl new file mode 100644 index 0000000..e22ab5f --- /dev/null +++ b/CodeWalker.Shaders/LightVS.hlsl @@ -0,0 +1,76 @@ +#include "Common.hlsli" + + +struct LODLight +{ + float3 Position; + uint Colour; + float3 Direction; + uint TimeAndStateFlags; + float4 TangentX; + float4 TangentY; + float Falloff; + float FalloffExponent; + float InnerAngle; //for cone + float OuterAngleOrCapExt; //outer angle for cone, cap extent for capsule +}; + +struct VS_Output +{ + float4 Pos : SV_POSITION; + float4 Screen : TEXCOORD0; + uint IID : SV_INSTANCEID; +}; + + +cbuffer VSLightVars : register(b0) +{ + float4x4 ViewProj; + float4 CameraPos; + uint LightType; //0=directional, 1=Point, 2=Spot, 4=Capsule + uint IsLOD; //useful or not? + uint Pad0; + uint Pad1; +} + +StructuredBuffer LODLights : register(t0); + + +VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID) +{ + float3 opos = 0; + if (LightType > 0) + { + LODLight lodlight = LODLights[iid]; + float extent = lodlight.Falloff; + + if (LightType == 1)//point (sphere) + { + opos = ipos.xyz * extent; + } + else if (LightType == 2)//spot (cone) + { + float arads = lodlight.OuterAngleOrCapExt * 0.01745329 * 1.5;//is this right? + float3 cpos = ipos.xyz * (atan(arads) * extent); + cpos.y += ipos.w * extent; + opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz); + } + else if (LightType == 4)//capsule + { + float3 cpos = ipos.xyz * extent; + cpos.y += (ipos.w*2-1) * lodlight.OuterAngleOrCapExt * 0.1; + opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz); + } + opos += (lodlight.Position - CameraPos.xyz); + } + else + { + opos = ipos.xyz; + } + float4 spos = mul(float4(opos, 1), ViewProj); + VS_Output output; + output.Pos = spos; + output.Screen = spos; + output.IID = iid; + return output; +} diff --git a/CodeWalker.Shaders/TerrainPS.hlsl b/CodeWalker.Shaders/TerrainPS.hlsl index dfdf94a..d11a6cd 100644 --- a/CodeWalker.Shaders/TerrainPS.hlsl +++ b/CodeWalker.Shaders/TerrainPS.hlsl @@ -1,61 +1,4 @@ -#include "Shadowmap.hlsli" - -Texture2D Colourmap0 : register(t0); -Texture2D Colourmap1 : register(t2); -Texture2D Colourmap2 : register(t3); -Texture2D Colourmap3 : register(t4); -Texture2D Colourmap4 : register(t5); -Texture2D Colourmask : register(t6); -Texture2D Normalmap0 : register(t7); -Texture2D Normalmap1 : register(t8); -Texture2D Normalmap2 : register(t9); -Texture2D Normalmap3 : register(t10); -Texture2D Normalmap4 : register(t11); -SamplerState TextureSS : register(s0); - - -cbuffer PSSceneVars : register(b0) -{ - ShaderGlobalLightParams GlobalLights; - uint EnableShadows; - uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct - uint RenderModeIndex; //colour or texcoord index - uint RenderSamplerCoord; -} -cbuffer PSEntityVars : register(b2) -{ - uint EnableTexture0; - uint EnableTexture1; - uint EnableTexture2; - uint EnableTexture3; - uint EnableTexture4; - uint EnableTextureMask; - uint EnableNormalMap; - uint ShaderName; - uint EnableTint; - uint EnableVertexColour; - float bumpiness; - uint Pad102; -} - - -struct VS_OUTPUT -{ - float4 Position : SV_POSITION; - float3 Normal : NORMAL; - float4 Colour0 : COLOR0; - float4 Colour1 : COLOR1; - float4 Tint : COLOR2; - float2 Texcoord0 : TEXCOORD0; - float2 Texcoord1 : TEXCOORD1; - float2 Texcoord2 : TEXCOORD2; - float4 Shadows : TEXCOORD4; - float4 LightShadow : TEXCOORD5; - float4 Tangent : TEXCOORD6; - float4 Bitangent : TEXCOORD7; - float3 CamRelPos : TEXCOORD8; -}; - +#include "TerrainPS.hlsli" float4 main(VS_OUTPUT input) : SV_TARGET diff --git a/CodeWalker.Shaders/TerrainPS.hlsli b/CodeWalker.Shaders/TerrainPS.hlsli new file mode 100644 index 0000000..b8cefdd --- /dev/null +++ b/CodeWalker.Shaders/TerrainPS.hlsli @@ -0,0 +1,67 @@ +#include "Shadowmap.hlsli" + +Texture2D Colourmap0 : register(t0); +Texture2D Colourmap1 : register(t2); +Texture2D Colourmap2 : register(t3); +Texture2D Colourmap3 : register(t4); +Texture2D Colourmap4 : register(t5); +Texture2D Colourmask : register(t6); +Texture2D Normalmap0 : register(t7); +Texture2D Normalmap1 : register(t8); +Texture2D Normalmap2 : register(t9); +Texture2D Normalmap3 : register(t10); +Texture2D Normalmap4 : register(t11); +SamplerState TextureSS : register(s0); + + +cbuffer PSSceneVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; + uint EnableShadows; + uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct + uint RenderModeIndex; //colour or texcoord index + uint RenderSamplerCoord; +} +cbuffer PSEntityVars : register(b2) +{ + uint EnableTexture0; + uint EnableTexture1; + uint EnableTexture2; + uint EnableTexture3; + uint EnableTexture4; + uint EnableTextureMask; + uint EnableNormalMap; + uint ShaderName; + uint EnableTint; + uint EnableVertexColour; + float bumpiness; + uint Pad102; +} + + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + float3 Normal : NORMAL; + float4 Colour0 : COLOR0; + float4 Colour1 : COLOR1; + float4 Tint : COLOR2; + float2 Texcoord0 : TEXCOORD0; + float2 Texcoord1 : TEXCOORD1; + float2 Texcoord2 : TEXCOORD2; + float4 Shadows : TEXCOORD4; + float4 LightShadow : TEXCOORD5; + float4 Tangent : TEXCOORD6; + float4 Bitangent : TEXCOORD7; + float3 CamRelPos : TEXCOORD8; +}; + +struct PS_OUTPUT +{ + float4 Diffuse : SV_Target0; + float4 Normal : SV_Target1; + float4 Specular : SV_Target2; + float4 Irradiance : SV_Target3; +}; + + diff --git a/CodeWalker.Shaders/TerrainPS_Deferred.hlsl b/CodeWalker.Shaders/TerrainPS_Deferred.hlsl new file mode 100644 index 0000000..aeb1ab3 --- /dev/null +++ b/CodeWalker.Shaders/TerrainPS_Deferred.hlsl @@ -0,0 +1,227 @@ +#include "TerrainPS.hlsli" + + +PS_OUTPUT main(VS_OUTPUT input) +{ + float4 vc0 = input.Colour0; + float4 vc1 = input.Colour1; + float2 tc0 = input.Texcoord0; + float2 tc1 = input.Texcoord1; + float2 tc2 = input.Texcoord2; + + float2 sc0 = tc0; + float2 sc1 = tc0; + float2 sc2 = tc0; + float2 sc3 = tc0; + float2 sc4 = tc0; + float2 scm = tc1; + + ////switch (ShaderName) + ////{ + //// case 3965214311: //terrain_cb_w_4lyr_cm_pxm_tnt vt: PNCTTTX_3 //vb_35_beache + //// case 4186046662: //terrain_cb_w_4lyr_cm_pxm vt: PNCTTTX_3 //cs6_08_struct08 + //// //vc1 = vc0; + //// //sc1 = tc0*25; + //// //sc2 = sc1; + //// //sc3 = sc1; + //// //sc4 = sc1; + //// //scm = tc0; + //// break; + ////} + + float4 bc0 = float4(0.5, 0.5, 0.5, 1); + //if (EnableVertexColour) + //{ + // bc0 = vc0; + //} + + if (RenderMode == 8) //direct texture - choose texcoords + { + if (RenderSamplerCoord == 2) sc0 = tc1; + else if (RenderSamplerCoord == 3) sc0 = tc2; + } + + + float4 c0 = (EnableTexture0 == 1) ? Colourmap0.Sample(TextureSS, sc0) : bc0; + float4 c1 = (EnableTexture1 == 1) ? Colourmap1.Sample(TextureSS, sc1) : bc0; + float4 c2 = (EnableTexture2 == 1) ? Colourmap2.Sample(TextureSS, sc2) : bc0; + float4 c3 = (EnableTexture3 == 1) ? Colourmap3.Sample(TextureSS, sc3) : bc0; + float4 c4 = (EnableTexture4 == 1) ? Colourmap4.Sample(TextureSS, sc4) : bc0; + float4 m = (EnableTextureMask == 1) ? Colourmask.Sample(TextureSS, scm) : vc1; + float4 b0 = (EnableNormalMap == 1) ? Normalmap0.Sample(TextureSS, sc0) : float4(0.5, 0.5, 0.5, 1);// float4(input.Normal, 0); + float4 b1 = (EnableNormalMap == 1) ? Normalmap1.Sample(TextureSS, sc1) : b0; + float4 b2 = (EnableNormalMap == 1) ? Normalmap2.Sample(TextureSS, sc2) : b0; + float4 b3 = (EnableNormalMap == 1) ? Normalmap3.Sample(TextureSS, sc3) : b0; + float4 b4 = (EnableNormalMap == 1) ? Normalmap4.Sample(TextureSS, sc4) : b0; + + float4 tv=0, nv=0; + float4 t1, t2, n1, n2; + + switch (ShaderName) + { + case 137526804: //terrain_cb_w_4lyr_lod vt: PNCCT //brdgeplatform_01_lod.. + //return float4(vc1.rgb, vc1.a*0.5 + 0.5); + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + default: + case 2535953532: //terrain_cb_w_4lyr_2tex_blend_lod vt: PNCCTT //cs1_12_riverbed1_lod.. + //return float4(vc0.rgb, vc0.a*0.5 + 0.5); + //return float4(vc1.rgb, vc1.a*0.5 + 0.5); + vc1 = m*(1 - vc0.a) + vc1*vc0.a; + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + + case 653544224: //terrain_cb_w_4lyr_2tex_blend_pxm_spm vt: PNCCTTTX //ch2_04_land06, rd_04_20.. + case 2486206885: //terrain_cb_w_4lyr_2tex_blend_pxm vt: PNCCTTTX //cs2_06c_lkbed_05.. + case 1888432890: //terrain_cb_w_4lyr_2tex_pxm vt: PNCCTTTX //ch1_04b_vineland01.. + //return float4(0, 1, 0, 1); + vc1 = m*(1 - vc0.a) + vc1*vc0.a; //perhaps another sampling of the mask is needed here + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + + case 3051127652: //terrain_cb_w_4lyr vt: PNCCTX //ss1_05_gr.. + case 646532852: //terrain_cb_w_4lyr_spec vt: PNCCTX //hw1_07_grnd_c.. + //return float4(1, 1, 0, 1); + vc1 = m*(1 - vc0.a) + vc1*vc0.a; //perhaps another sampling of the mask is needed here + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + + case 2316006813: //terrain_cb_w_4lyr_2tex_blend vt: PNCCTTX //ch2_04_land02b, vb_34_beachn_01.. + case 3112820305: //terrain_cb_w_4lyr_2tex vt: PNCCTTX //ch1_05_land5.. + case 2601000386: //terrain_cb_w_4lyr_spec_pxm vt: PNCCTTX_2 //ch2_03_land05, grnd_low2.. _road + case 4105814572: //terrain_cb_w_4lyr_pxm vt: PNCCTTX_2 //ch2_06_house02.. vb_35_beache + case 3400824277: //terrain_cb_w_4lyr_pxm_spm vt: PNCCTTX_2 //ch2_04_land02b, ch2_06_terrain01a .. vb_35_beacha + //return float4(1, 1, 1, 1); + vc1 = m*(1 - vc0.a) + vc1*vc0.a; //perhaps another sampling of the mask is needed here + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + + case 295525123: //terrain_cb_w_4lyr_cm vt: PNCTTX //_prewtrproxy_2.. + case 417637541: //terrain_cb_w_4lyr_cm_tnt vt: PNCTTX //_prewtrproxy_2.. //golf course.. + //tv = 1;// c1;// *vc0.r; //TODO! + //nv = b0; + vc1 = m; //needs work! + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + case 3965214311: //terrain_cb_w_4lyr_cm_pxm_tnt vt: PNCTTTX_3 //vb_35_beache + case 4186046662: //terrain_cb_w_4lyr_cm_pxm vt: PNCTTTX_3 //cs6_08_struct08 + //m = min(m, vc0); + //return float4(m.rgb, m.a*0.5 + 0.5); + //return float4(vc0.rgb, vc0.a*0.5 + 0.5); + //return float4(0, 1, 1, 1); + //m = vc0; + vc1 = m; //needs work! + t1 = c1*(1 - vc1.b) + c2*vc1.b; + t2 = c3*(1 - vc1.b) + c4*vc1.b; + tv = t1*(1 - vc1.g) + t2*vc1.g; + n1 = b1*(1 - vc1.b) + b2*vc1.b; + n2 = b3*(1 - vc1.b) + b4*vc1.b; + nv = n1*(1 - vc1.g) + n2*vc1.g; + break; + + } + if (EnableTint == 1) + { + tv.rgb *= input.Tint.rgb; + } + + + if (RenderMode == 1) //normals + { + tv.rgb = normalize(input.Normal)*0.5+0.5; + } + else if (RenderMode == 2) //tangents + { + tv.rgb = normalize(input.Tangent.xyz)*0.5+0.5; + } + else if (RenderMode == 3) //colours + { + tv.rgb = input.Colour0.rgb; + if (RenderModeIndex == 2) tv.rgb = input.Colour1.rgb; + } + else if (RenderMode == 4) //texcoords + { + tv.rgb = float3(input.Texcoord0, 0); + if (RenderModeIndex == 2) tv.rgb = float3(input.Texcoord1, 0); + if (RenderModeIndex == 3) tv.rgb = float3(input.Texcoord2, 0); + } + else if (RenderMode == 5) //render diffuse maps + { + //nothing to do here yet, diffuse maps rendered by default + } + else if (RenderMode == 6) //render normalmaps + { + tv.rgb = nv.rgb; + } + else if (RenderMode == 7) //render spec maps + { + tv.rgb = 0.5; //nothing to see here yet... + } + else if (RenderMode == 8) //render direct texture + { + tv = c0; + } + + //nv = normalize(nv*2-1); + //float4 tang = input.Tangent; + float3 nz = normalize(input.Normal); + //float3 nx = normalize(tang.xyz); + //float3 ny = normalize(cross(nz, nx)); + ////float3 norm = normalize(nx*nv.x + ny*nv.y + nz*nv.z); + float3 norm = nz;// normalize(input.Normal) + + + if ((RenderMode == 0) && (EnableNormalMap == 1)) + { + norm = NormalMap(nv.xy, bumpiness, input.Normal.xyz, input.Tangent.xyz, input.Bitangent.xyz); + } + + float3 spec = float3(0, 0, 1); + + tv.a = saturate(tv.a); + + + PS_OUTPUT output; + output.Diffuse = tv; + output.Normal = float4(saturate(norm * 0.5 + 0.5), tv.a); + output.Specular = float4(spec, tv.a); + output.Irradiance = float4(input.Colour0.rg, 0, tv.a); + + return output; +} diff --git a/CodeWalker.Shaders/TreesLodPS.hlsl b/CodeWalker.Shaders/TreesLodPS.hlsl index 94cbedc..8549079 100644 --- a/CodeWalker.Shaders/TreesLodPS.hlsl +++ b/CodeWalker.Shaders/TreesLodPS.hlsl @@ -1,30 +1,4 @@ -#include "Common.hlsli" - -Texture2D Colourmap : register(t0); -SamplerState TextureSS : register(s0); - - -cbuffer PSSceneVars : register(b0) -{ - ShaderGlobalLightParams GlobalLights; -} -cbuffer PSEntityVars : register(b1) -{ - uint EnableTexture; - uint Pad1; - uint Pad2; - uint Pad3; -} - - -struct VS_OUTPUT -{ - float4 Position : SV_POSITION; - float3 Normal : NORMAL; - float2 Texcoord : TEXCOORD0; - float4 Colour : COLOR0; -}; - +#include "TreesLodPS.hlsli" float4 main(VS_OUTPUT input) : SV_TARGET diff --git a/CodeWalker.Shaders/TreesLodPS.hlsli b/CodeWalker.Shaders/TreesLodPS.hlsli new file mode 100644 index 0000000..da8562f --- /dev/null +++ b/CodeWalker.Shaders/TreesLodPS.hlsli @@ -0,0 +1,35 @@ +#include "Common.hlsli" + +Texture2D Colourmap : register(t0); +SamplerState TextureSS : register(s0); + + +cbuffer PSSceneVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; +} +cbuffer PSEntityVars : register(b1) +{ + uint EnableTexture; + uint Pad1; + uint Pad2; + uint Pad3; +} + + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + float3 Normal : NORMAL; + float2 Texcoord : TEXCOORD0; + float4 Colour : COLOR0; +}; + +struct PS_OUTPUT +{ + float4 Diffuse : SV_Target0; + float4 Normal : SV_Target1; + float4 Specular : SV_Target2; + float4 Irradiance : SV_Target3; +}; + diff --git a/CodeWalker.Shaders/TreesLodPS_Deferred.hlsl b/CodeWalker.Shaders/TreesLodPS_Deferred.hlsl new file mode 100644 index 0000000..9e7e819 --- /dev/null +++ b/CodeWalker.Shaders/TreesLodPS_Deferred.hlsl @@ -0,0 +1,35 @@ +#include "TreesLodPS.hlsli" + + +PS_OUTPUT main(VS_OUTPUT input) +{ + //return float4(1,0,0,1);//red + + float4 c = 0; // float4(input.Colour.rgb, 1); + //return c; + + if (EnableTexture == 1) + { + //c = Colourmap.SampleLevel(TextureSS, input.Texcoord, 0); + c = Colourmap.Sample(TextureSS, input.Texcoord); + if (c.a <= 0.25) discard; + c.a = 1; + // c = float4(input.Colour.rgb, 1); + } + + float3 norm = input.Normal; + + + float3 spec = 0; + + c.a = saturate(c.a); + + PS_OUTPUT output; + output.Diffuse = c; + output.Normal = float4(saturate(norm * 0.5 + 0.5), c.a); + output.Specular = float4(spec, c.a); + output.Irradiance = float4(1, 0, 0, c.a); + + return output; + +} \ No newline at end of file diff --git a/CodeWalker.Shaders/WaterPS.hlsl b/CodeWalker.Shaders/WaterPS.hlsl index 1a3ac40..dfcedf0 100644 --- a/CodeWalker.Shaders/WaterPS.hlsl +++ b/CodeWalker.Shaders/WaterPS.hlsl @@ -1,128 +1,4 @@ -#include "Shadowmap.hlsli" - -Texture2D Colourmap : register(t0); -Texture2D Bumpmap : register(t2); -Texture2D Foammap : register(t3); -Texture2D WaterBumpSampler : register(t4);// graphics.ytd, waterbump and waterbump2 -Texture2D WaterBumpSampler2 : register(t5); -Texture2D WaterFog : register(t6); -SamplerState TextureSS : register(s0); - - -cbuffer PSSceneVars : register(b0) -{ - ShaderGlobalLightParams GlobalLights; - uint EnableShadows; - uint RenderMode;//0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct - uint RenderModeIndex; - uint RenderSamplerCoord; - uint EnableWaterbumps;//if the waterbump textures are ready.. - uint EnableFogtex; //if the fog texture is ready - uint ScnPad1; - uint ScnPad2; - float4 gFlowParams; - float4 CameraPos; - float4 WaterFogParams; //xy = base location, zw = inverse size -} -cbuffer PSGeomVars : register(b2) -{ - uint EnableTexture; - uint EnableBumpMap; - uint EnableFoamMap; - uint ShaderMode; - float SpecularIntensity; - float SpecularFalloff; - float GeoPad1; - float GeoPad2; - float WaveOffset; //for terrainfoam - float WaterHeight; //for terrainfoam - float WaveMovement; //for terrainfoam - float HeightOpacity; //for terrainfoam - float RippleSpeed; - float RippleScale; - float RippleBumpiness; - float GeoPad3; -} - - -struct VS_OUTPUT -{ - float4 Position : SV_POSITION; - float3 Normal : NORMAL; - float2 Texcoord0 : TEXCOORD0; - float4 Flow : TEXCOORD1; - float4 Shadows : TEXCOORD3; - float4 LightShadow : TEXCOORD4; - float4 Colour0 : COLOR0; - float4 Tangent : TEXCOORD5; - float4 Bitangent : TEXCOORD6; - float3 CamRelPos : TEXCOORD7; -}; - - - - -float3 RippleNormal(VS_OUTPUT input, float3 worldpos) -{ - //// - //// Input signature: - //// - //// Name Index Mask Register SysValue Format Used - //// -------------------- ----- ------ -------- -------- ------- ------ - //// SV_Position 0 xyzw 0 POS float - //// TEXCOORD 0 xyzw 1 NONE float xyzw - //// TEXCOORD 1 xyzw 2 NONE float xyzw - //// TEXCOORD 2 xyzw 3 NONE float zw - //// TEXCOORD 3 xyzw 4 NONE float xyzw //NORMAL +half - //// TEXCOORD 4 xyzw 5 NONE float zw //FLOW - //// - // - - float3 norm = input.Normal.xyz; - float v2w = input.Colour0.r; //vertex red channel - - float4 r0, r1, r2, r3, r4; - - r0.xy = input.Flow.zw * RippleSpeed; //mul r0.xy, v5.zwzz, RippleSpeed - r1 = -r0.xyxy * gFlowParams.xxyy + worldpos.xyxy; //mad r1.xyzw, -r0.xyxy, gFlowParams.xxyy, v2.xyxy - r0.x = min(sqrt(dot(r0.xy, r0.xy)), 1.0); //dp2 r0.x, r0.xyxx, r0.xyxx //sqrt r0.x, r0.x //min r0.x, r0.x, l(1.000000) - r0.yz = r1.xy * RippleScale; //mul r0.yz, r1.xxyx, RippleScale - r1.xy = r1.zw * RippleScale + 0.5; //mad r1.xy, r1.zwzz, RippleScale, l(0.500000, 0.500000, 0.000000, 0.000000) - r1.xy = r1.xy * 2.3; //mul r1.xy, r1.xyxx, l(2.300000, 2.300000, 0.000000, 0.000000) - r0.yz = r0.yz * 2.3; //mul r0.yz, r0.yyzy, l(0.000000, 2.300000, 2.300000, 0.000000) - r2 = WaterBumpSampler2.Sample(TextureSS, r0.yz); //sample r2.xyzw, r0.yzyy, WaterBumpSampler2.xyzw, s14 - r3 = WaterBumpSampler.Sample(TextureSS, r0.yz); //sample r3.xyzw, r0.yzyy, WaterBumpSampler.xyzw, s10 - r4 = WaterBumpSampler2.Sample(TextureSS, r1.xy); //sample r4.xyzw, r1.xyxx, WaterBumpSampler2.xyzw, s14 - r1 = WaterBumpSampler.Sample(TextureSS, r1.xy); //sample r1.xyzw, r1.xyxx, WaterBumpSampler.xyzw, s10 - r3.zw = r1.xy; //mov r3.zw, r1.xxxy - r2.zw = r4.xy; //mov r2.zw, r4.xxxy - r1 = r2 + r3; //add r1.xyzw, r2.xyzw, r3.xyzw - r2 = r3 + 0.5; //add r2.xyzw, r3.xyzw, l(0.500000, 0.500000, 0.500000, 0.500000) - r1 = r1 - r2; //add r1.xyzw, r1.xyzw, -r2.xyzw - r0 = r1 * r0.x + r2; //mad r0.xyzw, r0.xxxx, r1.xyzw, r2.xyzw - r0 = r0 * 2 - 2; //mad r0.xyzw, r0.xyzw, l(2.000000, 2.000000, 2.000000, 2.000000), l(-2.000000, -2.000000, -2.000000, -2.000000) - r0 = r0 * gFlowParams.zzww; //mul r0.xyzw, r0.xyzw, gFlowParams.zzww - r0.xy = r0.xy + r0.zw; //add r0.xy, r0.zwzz, r0.xyxx - r0.zw = r0.xy * RippleBumpiness;//mul r0.zw, r0.xxxy, RippleBumpiness - //r0.x = sqrt(dot(r0.xy, r0.xy)); //dp2 r0.x, r0.xyxx, r0.xyxx //sqrt r0.x, r0.x - //r0.x = r0.x * 0.27 + 0.44; //mad r0.x, r0.x, l(0.270000), l(0.440000) - r1.xy = r0.zw * v2w + norm.xy; //mad r1.xy, r0.zwzz, v2.wwww, v4.xyxx - r1.z = norm.z; //mov r1.z, v4.z - //return normalize(r1.xyz); - r0.y = dot(r1.xyz, r1.xyz); //dp3 r0.y, r1.xyzx, r1.xyzx - r0.y = 1.0 / sqrt(r0.y); //rsq r0.y, r0.y - r2.xyz = -r1.xyz * r0.y + float3(0, 0, 1); //mad r2.xyz, -r1.xyzx, r0.yyyy, l(0.000000, 0.000000, 1.000000, 0.000000) - r0.yzw = r1.xyz * r0.y; //mul r0.yzw, r0.yyyy, r1.xxyz - //r1.xyz = r2.xyz * 0.833333 + r0.yzw; //mad r1.xyz, r2.xyzx, l(0.833333, 0.833333, 0.833333, 0.000000), r0.yzwy - //r2.xyz = worldpos - //add r2.xyz, v2.xyzx, -gViewInverse[3].xyzx - - return r0.yzw; - //return r0.wzy; - ////return float3(r0.w, r0.z, r0.y); - - ////return normalize(input.Normal); -} - +#include "WaterPS.hlsli" float4 main(VS_OUTPUT input) : SV_TARGET diff --git a/CodeWalker.Shaders/WaterPS.hlsli b/CodeWalker.Shaders/WaterPS.hlsli new file mode 100644 index 0000000..78bfdd7 --- /dev/null +++ b/CodeWalker.Shaders/WaterPS.hlsli @@ -0,0 +1,133 @@ +#include "Shadowmap.hlsli" + +Texture2D Colourmap : register(t0); +Texture2D Bumpmap : register(t2); +Texture2D Foammap : register(t3); +Texture2D WaterBumpSampler : register(t4); // graphics.ytd, waterbump and waterbump2 +Texture2D WaterBumpSampler2 : register(t5); +Texture2D WaterFog : register(t6); +SamplerState TextureSS : register(s0); + + +cbuffer PSSceneVars : register(b0) +{ + ShaderGlobalLightParams GlobalLights; + uint EnableShadows; + uint RenderMode; //0=default, 1=normals, 2=tangents, 3=colours, 4=texcoords, 5=diffuse, 6=normalmap, 7=spec, 8=direct + uint RenderModeIndex; + uint RenderSamplerCoord; + uint EnableWaterbumps; //if the waterbump textures are ready.. + uint EnableFogtex; //if the fog texture is ready + uint ScnPad1; + uint ScnPad2; + float4 gFlowParams; + float4 CameraPos; + float4 WaterFogParams; //xy = base location, zw = inverse size +} +cbuffer PSGeomVars : register(b2) +{ + uint EnableTexture; + uint EnableBumpMap; + uint EnableFoamMap; + uint ShaderMode; + float SpecularIntensity; + float SpecularFalloff; + float GeoPad1; + float GeoPad2; + float WaveOffset; //for terrainfoam + float WaterHeight; //for terrainfoam + float WaveMovement; //for terrainfoam + float HeightOpacity; //for terrainfoam + float RippleSpeed; + float RippleScale; + float RippleBumpiness; + float GeoPad3; +} + + +struct VS_OUTPUT +{ + float4 Position : SV_POSITION; + float3 Normal : NORMAL; + float2 Texcoord0 : TEXCOORD0; + float4 Flow : TEXCOORD1; + float4 Shadows : TEXCOORD3; + float4 LightShadow : TEXCOORD4; + float4 Colour0 : COLOR0; + float4 Tangent : TEXCOORD5; + float4 Bitangent : TEXCOORD6; + float3 CamRelPos : TEXCOORD7; +}; + +struct PS_OUTPUT +{ + float4 Diffuse : SV_Target0; + float4 Normal : SV_Target1; + float4 Specular : SV_Target2; + float4 Irradiance : SV_Target3; +}; + + + + + +float3 RippleNormal(VS_OUTPUT input, float3 worldpos) +{ + //// + //// Input signature: + //// + //// Name Index Mask Register SysValue Format Used + //// -------------------- ----- ------ -------- -------- ------- ------ + //// SV_Position 0 xyzw 0 POS float + //// TEXCOORD 0 xyzw 1 NONE float xyzw + //// TEXCOORD 1 xyzw 2 NONE float xyzw + //// TEXCOORD 2 xyzw 3 NONE float zw + //// TEXCOORD 3 xyzw 4 NONE float xyzw //NORMAL +half + //// TEXCOORD 4 xyzw 5 NONE float zw //FLOW + //// + // + + float3 norm = input.Normal.xyz; + float v2w = input.Colour0.r; //vertex red channel + + float4 r0, r1, r2, r3, r4; + + r0.xy = input.Flow.zw * RippleSpeed; //mul r0.xy, v5.zwzz, RippleSpeed + r1 = -r0.xyxy * gFlowParams.xxyy + worldpos.xyxy; //mad r1.xyzw, -r0.xyxy, gFlowParams.xxyy, v2.xyxy + r0.x = min(sqrt(dot(r0.xy, r0.xy)), 1.0); //dp2 r0.x, r0.xyxx, r0.xyxx //sqrt r0.x, r0.x //min r0.x, r0.x, l(1.000000) + r0.yz = r1.xy * RippleScale; //mul r0.yz, r1.xxyx, RippleScale + r1.xy = r1.zw * RippleScale + 0.5; //mad r1.xy, r1.zwzz, RippleScale, l(0.500000, 0.500000, 0.000000, 0.000000) + r1.xy = r1.xy * 2.3; //mul r1.xy, r1.xyxx, l(2.300000, 2.300000, 0.000000, 0.000000) + r0.yz = r0.yz * 2.3; //mul r0.yz, r0.yyzy, l(0.000000, 2.300000, 2.300000, 0.000000) + r2 = WaterBumpSampler2.Sample(TextureSS, r0.yz); //sample r2.xyzw, r0.yzyy, WaterBumpSampler2.xyzw, s14 + r3 = WaterBumpSampler.Sample(TextureSS, r0.yz); //sample r3.xyzw, r0.yzyy, WaterBumpSampler.xyzw, s10 + r4 = WaterBumpSampler2.Sample(TextureSS, r1.xy); //sample r4.xyzw, r1.xyxx, WaterBumpSampler2.xyzw, s14 + r1 = WaterBumpSampler.Sample(TextureSS, r1.xy); //sample r1.xyzw, r1.xyxx, WaterBumpSampler.xyzw, s10 + r3.zw = r1.xy; //mov r3.zw, r1.xxxy + r2.zw = r4.xy; //mov r2.zw, r4.xxxy + r1 = r2 + r3; //add r1.xyzw, r2.xyzw, r3.xyzw + r2 = r3 + 0.5; //add r2.xyzw, r3.xyzw, l(0.500000, 0.500000, 0.500000, 0.500000) + r1 = r1 - r2; //add r1.xyzw, r1.xyzw, -r2.xyzw + r0 = r1 * r0.x + r2; //mad r0.xyzw, r0.xxxx, r1.xyzw, r2.xyzw + r0 = r0 * 2 - 2; //mad r0.xyzw, r0.xyzw, l(2.000000, 2.000000, 2.000000, 2.000000), l(-2.000000, -2.000000, -2.000000, -2.000000) + r0 = r0 * gFlowParams.zzww; //mul r0.xyzw, r0.xyzw, gFlowParams.zzww + r0.xy = r0.xy + r0.zw; //add r0.xy, r0.zwzz, r0.xyxx + r0.zw = r0.xy * RippleBumpiness; //mul r0.zw, r0.xxxy, RippleBumpiness + //r0.x = sqrt(dot(r0.xy, r0.xy)); //dp2 r0.x, r0.xyxx, r0.xyxx //sqrt r0.x, r0.x + //r0.x = r0.x * 0.27 + 0.44; //mad r0.x, r0.x, l(0.270000), l(0.440000) + r1.xy = r0.zw * v2w + norm.xy; //mad r1.xy, r0.zwzz, v2.wwww, v4.xyxx + r1.z = norm.z; //mov r1.z, v4.z + //return normalize(r1.xyz); + r0.y = dot(r1.xyz, r1.xyz); //dp3 r0.y, r1.xyzx, r1.xyzx + r0.y = 1.0 / sqrt(r0.y); //rsq r0.y, r0.y + r2.xyz = -r1.xyz * r0.y + float3(0, 0, 1); //mad r2.xyz, -r1.xyzx, r0.yyyy, l(0.000000, 0.000000, 1.000000, 0.000000) + r0.yzw = r1.xyz * r0.y; //mul r0.yzw, r0.yyyy, r1.xxyz + //r1.xyz = r2.xyz * 0.833333 + r0.yzw; //mad r1.xyz, r2.xyzx, l(0.833333, 0.833333, 0.833333, 0.000000), r0.yzwy + //r2.xyz = worldpos - //add r2.xyz, v2.xyzx, -gViewInverse[3].xyzx + + return r0.yzw; + //return r0.wzy; + ////return float3(r0.w, r0.z, r0.y); + + ////return normalize(input.Normal); +} diff --git a/CodeWalker.Shaders/WaterPS_Deferred.hlsl b/CodeWalker.Shaders/WaterPS_Deferred.hlsl new file mode 100644 index 0000000..fef2848 --- /dev/null +++ b/CodeWalker.Shaders/WaterPS_Deferred.hlsl @@ -0,0 +1,105 @@ +#include "WaterPS.hlsli" + + +PS_OUTPUT main(VS_OUTPUT input) +{ + float4 c = float4(0.1, 0.18, 0.25, 0.8); + //if (RenderMode == 0) c = float4(1, 1, 1, 1); + + //c.a *= input.Colour0.a; + + float3 camrel = input.CamRelPos; + float3 worldpos = camrel + CameraPos.xyz; + if ((EnableFoamMap == 0) && (EnableFogtex == 1)) + { + float2 fogtc = saturate((worldpos.xy - WaterFogParams.xy) * WaterFogParams.zw); + fogtc.y = 1.0 - fogtc.y; + c = WaterFog.Sample(TextureSS, fogtc); + c.a = 0.9; + } + + + float3 norm = EnableFoamMap ? normalize(input.Normal) : RippleNormal(input, worldpos); // normalize(input.Normal); + + if (RenderMode == 1) //normals + { + c.rgb = norm * 0.5 + 0.5; + } + else if (RenderMode == 2) //tangents + { + c.rgb = normalize(input.Tangent.rgb) * 0.5 + 0.5; + } + else if (RenderMode == 3) //colours + { + c.rgb = input.Colour0.rgb; + } + else if (RenderMode == 4) //texcoords + { + c.rgb = float3(input.Texcoord0, 0); + } + else if ((RenderMode == 8) || (EnableTexture == 1)) //single texture or diffuse enabled + { + c.rgb = Colourmap.Sample(TextureSS, input.Texcoord0).rgb; + } + else if (EnableFoamMap) + { + c = Foammap.Sample(TextureSS, input.Texcoord0); + } + + + float3 spec = 0; + + if (RenderMode == 0) + { + + float4 nv = Bumpmap.Sample(TextureSS, input.Texcoord0); //sample r1.xyzw, v2.xyxx, t3.xyzw, s3 (BumpSampler) + + + float2 nmv = nv.xy; + float4 r0 = 0, r1, r2, r3; + + float bumpiness = 0.5; + + if (EnableBumpMap) + { + norm = NormalMap(nmv, bumpiness, input.Normal.xyz, input.Tangent.xyz, input.Bitangent.xyz); + } + + + float3 tc = c.rgb; + c.rgb = tc; // *r0.z; //diffuse factors... + + + spec.xy = sqrt(10.0 * SpecularIntensity); + spec.z = 1;//r0.z; + + + + if (ShaderMode == 1) //river foam + { + c.a *= input.Colour0.g; + } + else if (ShaderMode == 2) //terrain foam + { + c.a *= c.r; + c.a *= input.Colour0.r; + } + else + { + ///c.a = 1; + } + } + + c.a = saturate(c.a); + + PS_OUTPUT output; + output.Diffuse = c; + output.Normal = float4(saturate(norm * 0.5 + 0.5), c.a); + output.Specular = float4(spec, c.a); + output.Irradiance = float4(1, 0, 0, c.a); + + return output; +} + + + diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 59a671c..e936ae0 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -137,6 +137,8 @@ + + Form diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index f6cbeb2..375038c 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -214,6 +214,9 @@ namespace CodeWalker.Forms camera.TargetRotation.X = 0.5f * (float)Math.PI; camera.CurrentRotation.X = 0.5f * (float)Math.PI; + Renderer.shaders.deferred = false; //no point using this here yet + + LoadSettings(); diff --git a/PedsForm.cs b/PedsForm.cs index 9ef4142..ce915ad 100644 --- a/PedsForm.cs +++ b/PedsForm.cs @@ -181,6 +181,8 @@ namespace CodeWalker.Peds camera.TargetRotation.X = 1.0f * (float)Math.PI; camera.CurrentRotation.X = 1.0f * (float)Math.PI; + Renderer.shaders.deferred = false; //no point using this here yet + LoadSettings(); diff --git a/Project/Panels/GenerateLODLightsPanel.cs b/Project/Panels/GenerateLODLightsPanel.cs index 7e27c42..b8d1948 100644 --- a/Project/Panels/GenerateLODLightsPanel.cs +++ b/Project/Panels/GenerateLODLightsPanel.cs @@ -195,8 +195,8 @@ namespace CodeWalker.Project.Panels - Vector3 lpos = new Vector3(la.PositionX, la.PositionY, la.PositionZ); - Vector3 ldir = new Vector3(la.DirectionX, la.DirectionY, la.DirectionZ); + Vector3 lpos = la.Position; + Vector3 ldir = la.Direction; Vector3 bpos = xform.Multiply(lpos); Vector3 bdir = xform.MultiplyRot(ldir); Vector3 epos = ent.Orientation.Multiply(bpos) + ent.Position; @@ -229,11 +229,11 @@ namespace CodeWalker.Project.Panels //1 = point //2 = spot //4 = capsule - uint type = la.Type; + uint type = (uint)la.Type; uint unk = isStreetLight ? 1u : 0;//2 bits - isStreetLight low bit, unk high bit uint t = la.TimeFlags | (type << 26) | (unk << 24); - var maxext = (byte)Math.Max(Math.Max(la.ExtentX, la.ExtentY), la.ExtentZ); + var maxext = (byte)Math.Max(Math.Max(la.Extent.X, la.Extent.Y), la.Extent.Z); diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs index 17a998e..c5d4952 100644 --- a/Properties/Settings.Designer.cs +++ b/Properties/Settings.Designer.cs @@ -734,5 +734,17 @@ namespace CodeWalker.Properties { this["ExplorerWindowTheme"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool Deferred { + get { + return ((bool)(this["Deferred"])); + } + set { + this["Deferred"] = value; + } + } } } diff --git a/Properties/Settings.settings b/Properties/Settings.settings index 0e1a98f..819c463 100644 --- a/Properties/Settings.settings +++ b/Properties/Settings.settings @@ -192,5 +192,8 @@ Windows + + True + \ No newline at end of file diff --git a/Rendering/Renderable.cs b/Rendering/Renderable.cs index 35bbd84..f5b3246 100644 --- a/Rendering/Renderable.cs +++ b/Rendering/Renderable.cs @@ -1355,6 +1355,136 @@ namespace CodeWalker.Rendering } } + + public class RenderableLODLights : RenderableCacheItem + { + public struct LODLight + { + public Vector3 Position; + public uint Colour; + public Vector3 Direction; + public uint TimeAndStateFlags; + public Vector4 TangentX; + public Vector4 TangentY; + public float Falloff; + public float FalloffExponent; + public float InnerAngle;//for cone + public float OuterAngleOrCapExt;//outer angle for cone, cap extent for capsule + } + + public LODLight[] Points; + public LODLight[] Spots; + public LODLight[] Caps; + + public GpuSBuffer PointsBuffer { get; set; } + public GpuSBuffer SpotsBuffer { get; set; } + public GpuSBuffer CapsBuffer { get; set; } + + + public override void Init(YmapFile key) + { + Key = key; + + var ll = key.LODLights; + var dll = key.Parent?.DistantLODLights; + + if (ll == null) return; + if (dll == null) return; + + var n = dll.positions?.Length ?? 0; + n = Math.Min(n, dll.colours?.Length ?? 0); + n = Math.Min(n, ll.direction?.Length ?? 0); + n = Math.Min(n, ll.falloff?.Length ?? 0); + n = Math.Min(n, ll.falloffExponent?.Length ?? 0); + n = Math.Min(n, ll.timeAndStateFlags?.Length ?? 0); + n = Math.Min(n, ll.hash?.Length ?? 0); + n = Math.Min(n, ll.coneInnerAngle?.Length ?? 0); + n = Math.Min(n, ll.coneOuterAngleOrCapExt?.Length ?? 0); + n = Math.Min(n, ll.coronaIntensity?.Length ?? 0); + + if (n <= 0) + { return; } + + + var points = new List(); + var spots = new List(); + var caps = new List(); + + for (int i = 0; i < n; i++) + { + var light = new LODLight(); + light.Position = dll.positions[i].ToVector3(); + light.Colour = dll.colours[i]; + light.Direction = ll.direction[i].ToVector3(); + light.TimeAndStateFlags = ll.timeAndStateFlags[i]; + light.TangentX = new Vector4(Vector3.Normalize(light.Direction.GetPerpVec()), 0.0f); + light.TangentY = new Vector4(Vector3.Cross(light.Direction, light.TangentX.XYZ()), 0.0f); + light.Falloff = ll.falloff[i]; + light.FalloffExponent = ll.falloffExponent[i]; + light.InnerAngle = ll.coneInnerAngle[i]; + light.OuterAngleOrCapExt = ll.coneOuterAngleOrCapExt[i]; + var type = (LightType)((light.TimeAndStateFlags >> 26) & 7); + switch (type) + { + case LightType.Point: + points.Add(light); + break; + case LightType.Spot: + spots.Add(light); + break; + case LightType.Capsule: + caps.Add(light); + break; + default: break;//just checking... + } + } + + Points = points.ToArray(); + Spots = spots.ToArray(); + Caps = caps.ToArray(); + + } + + public override void Load(Device device) + { + if ((Points != null) && (Points.Length > 0)) + { + PointsBuffer = new GpuSBuffer(device, Points); + } + if ((Spots != null) && (Spots.Length > 0)) + { + SpotsBuffer = new GpuSBuffer(device, Spots); + } + if ((Caps != null) && (Caps.Length > 0)) + { + CapsBuffer = new GpuSBuffer(device, Caps); + } + + IsLoaded = true; + } + + public override void Unload() + { + IsLoaded = false; + + if (PointsBuffer != null) + { + PointsBuffer.Dispose(); + PointsBuffer = null; + } + if (SpotsBuffer != null) + { + SpotsBuffer.Dispose(); + SpotsBuffer = null; + } + if (CapsBuffer != null) + { + CapsBuffer.Dispose(); + CapsBuffer = null; + } + } + } + public class RenderableDistantLODLights : RenderableCacheItem { public struct DistLODLight @@ -1815,7 +1945,7 @@ namespace CodeWalker.Rendering p2 = bgeom.GetVertex(bcap.capsuleIndex2); a1 = p2 - p1; n1 = Vector3.Normalize(a1); - p3 = Vector3.Normalize(GetPerpVec(n1)); + p3 = Vector3.Normalize(n1.GetPerpVec()); //p4 = Vector3.Normalize(Vector3.Cross(n1, p3)); Quaternion q1 = Quaternion.Invert(Quaternion.LookAtRH(Vector3.Zero, p3, n1)); rcapsules[curcapsule].Point1 = p1; @@ -1848,7 +1978,7 @@ namespace CodeWalker.Rendering p2 = bgeom.GetVertex(pcyl.cylinderIndex2); a1 = p2 - p1; n1 = Vector3.Normalize(a1); - p3 = Vector3.Normalize(GetPerpVec(n1)); + p3 = Vector3.Normalize(n1.GetPerpVec()); //p4 = Vector3.Normalize(Vector3.Cross(n1, p3)); Quaternion q2 = Quaternion.Invert(Quaternion.LookAtRH(Vector3.Zero, p3, n1)); rcylinders[curcylinder].Point1 = p1; @@ -1898,26 +2028,6 @@ namespace CodeWalker.Rendering index++; } - private Vector3 GetPerpVec(Vector3 n) - { - //make a vector perpendicular to the given one - float nx = Math.Abs(n.X); - float ny = Math.Abs(n.Y); - float nz = Math.Abs(n.Z); - if ((nx < ny) && (nx < nz)) - { - return Vector3.Cross(n, Vector3.Right); - } - else if (ny < nz) - { - return Vector3.Cross(n, Vector3.Up); - } - else - { - return Vector3.Cross(n, Vector3.ForwardLH); - } - } - public void Load(Device device) { diff --git a/Rendering/RenderableCache.cs b/Rendering/RenderableCache.cs index d05194a..facc1ad 100644 --- a/Rendering/RenderableCache.cs +++ b/Rendering/RenderableCache.cs @@ -29,8 +29,9 @@ namespace CodeWalker.Rendering return renderables.CacheUse + textures.CacheUse + boundcomps.CacheUse - + instbatches.CacheUse - + distlodlights.CacheUse + + instbatches.CacheUse + + lodlights.CacheUse + + distlodlights.CacheUse + pathbatches.CacheUse + waterquads.CacheUse; } @@ -43,6 +44,7 @@ namespace CodeWalker.Rendering + textures.CurrentLoadedCount + boundcomps.CurrentLoadedCount + instbatches.CurrentLoadedCount + + lodlights.CurrentLoadedCount + distlodlights.CurrentLoadedCount + pathbatches.CurrentLoadedCount + waterquads.CurrentLoadedCount; @@ -56,6 +58,7 @@ namespace CodeWalker.Rendering + textures.QueueLength + boundcomps.QueueLength + instbatches.QueueLength + + lodlights.QueueLength + distlodlights.QueueLength + pathbatches.QueueLength + waterquads.QueueLength; @@ -95,6 +98,7 @@ namespace CodeWalker.Rendering private RenderableCacheLookup textures = new RenderableCacheLookup(Settings.Default.GPUTextureCacheSize, Settings.Default.GPUCacheTime); private RenderableCacheLookup boundcomps = new RenderableCacheLookup(Settings.Default.GPUBoundCompCacheSize, Settings.Default.GPUCacheTime); private RenderableCacheLookup instbatches = new RenderableCacheLookup(67108864, Settings.Default.GPUCacheTime); //64MB - todo: make this a setting + private RenderableCacheLookup lodlights = new RenderableCacheLookup(33554432, Settings.Default.GPUCacheTime); //32MB - todo: make this a setting private RenderableCacheLookup distlodlights = new RenderableCacheLookup(33554432, Settings.Default.GPUCacheTime); //32MB - todo: make this a setting private RenderableCacheLookup pathbatches = new RenderableCacheLookup(536870912 /*33554432*/, Settings.Default.GPUCacheTime); // 512MB /*32MB*/ - todo: make this a setting private RenderableCacheLookup waterquads = new RenderableCacheLookup(4194304, Settings.Default.GPUCacheTime); //4MB - todo: make this a setting @@ -117,6 +121,7 @@ namespace CodeWalker.Rendering textures.Clear(); boundcomps.Clear(); instbatches.Clear(); + lodlights.Clear(); distlodlights.Clear(); pathbatches.Clear(); waterquads.Clear(); @@ -134,6 +139,7 @@ namespace CodeWalker.Rendering int texturecount = textures.LoadProc(currentDevice, MaxItemsPerLoop); int boundcompcount = boundcomps.LoadProc(currentDevice, MaxItemsPerLoop); int instbatchcount = instbatches.LoadProc(currentDevice, MaxItemsPerLoop); + int lodlightcount = lodlights.LoadProc(currentDevice, MaxItemsPerLoop); int distlodlightcount = distlodlights.LoadProc(currentDevice, MaxItemsPerLoop); int pathbatchcount = pathbatches.LoadProc(currentDevice, MaxItemsPerLoop); int waterquadcount = waterquads.LoadProc(currentDevice, MaxItemsPerLoop); @@ -144,6 +150,7 @@ namespace CodeWalker.Rendering (texturecount >= MaxItemsPerLoop) || (boundcompcount >= MaxItemsPerLoop) || (instbatchcount >= MaxItemsPerLoop) || + (lodlightcount >= MaxItemsPerLoop) || (distlodlightcount >= MaxItemsPerLoop) || (pathbatchcount >= MaxItemsPerLoop) || (waterquadcount >= MaxItemsPerLoop); @@ -161,6 +168,7 @@ namespace CodeWalker.Rendering textures.UnloadProc(); boundcomps.UnloadProc(); instbatches.UnloadProc(); + lodlights.UnloadProc(); distlodlights.UnloadProc(); pathbatches.UnloadProc(); waterquads.UnloadProc(); @@ -182,6 +190,7 @@ namespace CodeWalker.Rendering textures.RenderThreadSync(); boundcomps.RenderThreadSync(); instbatches.RenderThreadSync(); + lodlights.RenderThreadSync(); distlodlights.RenderThreadSync(); pathbatches.RenderThreadSync(); waterquads.RenderThreadSync(); @@ -207,6 +216,10 @@ namespace CodeWalker.Rendering { return distlodlights.Get(lights); } + public RenderableLODLights GetRenderableLODLights(YmapFile ymap) + { + return lodlights.Get(ymap); + } public RenderablePathBatch GetRenderablePathBatch(BasePathData pathdata) { return pathbatches.Get(pathdata); diff --git a/Rendering/Renderer.cs b/Rendering/Renderer.cs index 7c8f770..af04ba5 100644 --- a/Rendering/Renderer.cs +++ b/Rendering/Renderer.cs @@ -102,7 +102,9 @@ namespace CodeWalker.Rendering public bool renderchildents = false;//when rendering single ymap, render root only or not... public bool renderentities = true; public bool rendergrass = true; - public bool renderdistlodlights = true; + public bool renderlights = false; //render individual drawable lights (TODO!) + public bool renderlodlights = true; //render LOD lights from ymaps + public bool renderdistlodlights = true; //render distant lod lights (coronas) public bool rendercars = false; public bool rendercollisionmeshes = Settings.Default.ShowCollisionMeshes; @@ -1575,10 +1577,14 @@ namespace CodeWalker.Rendering for (int y = 0; y < VisibleYmaps.Count; y++) { var ymap = VisibleYmaps[y]; + YmapFile pymap = ymap.Parent; + if ((pymap == null) && (ymap._CMapData.parent != 0)) + { + renderworldVisibleYmapDict.TryGetValue(ymap._CMapData.parent, out pymap); + ymap.Parent = pymap; + } if (ymap.RootEntities != null) { - YmapFile pymap; - renderworldVisibleYmapDict.TryGetValue(ymap._CMapData.parent, out pymap); for (int i = 0; i < ymap.RootEntities.Length; i++) { var ent = ymap.RootEntities[i]; @@ -1699,6 +1705,17 @@ namespace CodeWalker.Rendering } } } + if (renderlodlights && shaders.deferred) + { + for (int y = 0; y < VisibleYmaps.Count; y++) + { + var ymap = VisibleYmaps[y]; + if (ymap.LODLights != null) + { + RenderYmapLODLights(ymap); + } + } + } } private bool RenderWorldYmapIsVisible(YmapFile ymap) { @@ -2185,6 +2202,20 @@ namespace CodeWalker.Rendering } + + + private void RenderYmapLODLights(YmapFile ymap) + { + if (ymap.LODLights == null) return; + if (ymap.Parent?.DistantLODLights == null) return; //need to get lodlights positions from parent (distlodlights) + + RenderableLODLights lights = renderableCache.GetRenderableLODLights(ymap); + if (!lights.IsLoaded) return; + + shaders.Enqueue(lights); + + } + private void RenderYmapDistantLODLights(YmapFile ymap) { //enqueue ymap DistantLODLights instance batch for rendering @@ -2211,7 +2242,7 @@ namespace CodeWalker.Rendering Texture lighttex = null; if ((graphicsytd != null) && (graphicsytd.Loaded) && (graphicsytd.TextureDict != null) && (graphicsytd.TextureDict.Dict != null)) { - graphicsytd.TextureDict.Dict.TryGetValue(texhash, out lighttex); //starfield hash + graphicsytd.TextureDict.Dict.TryGetValue(texhash, out lighttex); } if (lighttex == null) return; diff --git a/Rendering/ShaderManager.cs b/Rendering/ShaderManager.cs index ad58aca..6d51b34 100644 --- a/Rendering/ShaderManager.cs +++ b/Rendering/ShaderManager.cs @@ -32,9 +32,11 @@ namespace CodeWalker.Rendering DepthStencilState dsDisableAll; DepthStencilState dsDisableComp; DepthStencilState dsDisableWrite; + DepthStencilState dsDisableWriteRev; + public DeferredScene DefScene { get; set; } public PostProcessor HDR { get; set; } public BasicShader Basic { get; set; } public CableShader Cable { get; set; } @@ -57,6 +59,7 @@ namespace CodeWalker.Rendering List shadowbatches = new List(); int shadowcastercount = 0; //total casters rendered + public bool deferred = Settings.Default.Deferred; public bool hdr = Settings.Default.HDR; public float hdrLumBlendSpeed = 1.0f; int Width; @@ -68,6 +71,7 @@ namespace CodeWalker.Rendering public List RenderBuckets = new List(); public List RenderBoundGeoms = new List(); public List RenderInstBatches = new List(); + public List RenderLODLights = new List(); public List RenderDistLODLights = new List(); public List RenderPathBatches = new List(); public List RenderWaterQuads = new List(); @@ -94,6 +98,10 @@ namespace CodeWalker.Rendering get { long u = 0; + if (DefScene != null) + { + u += DefScene.VramUsage; + } if (HDR != null) { u += HDR.VramUsage; @@ -163,6 +171,9 @@ namespace CodeWalker.Rendering bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; bsd.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero; bsd.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; + bsd.RenderTarget[1] = bsd.RenderTarget[0]; + bsd.RenderTarget[2] = bsd.RenderTarget[0]; + bsd.RenderTarget[3] = bsd.RenderTarget[0]; bsDefault = new BlendState(device, bsd); bsd.AlphaToCoverageEnable = true; @@ -198,6 +209,8 @@ namespace CodeWalker.Rendering dsEnabled = new DepthStencilState(device, dsd); dsd.DepthWriteMask = DepthWriteMask.Zero; dsDisableWrite = new DepthStencilState(device, dsd); + dsd.DepthComparison = Comparison.LessEqual; + dsDisableWriteRev = new DepthStencilState(device, dsd); dsd.DepthComparison = Comparison.Always; dsDisableComp = new DepthStencilState(device, dsd); dsd.IsDepthEnabled = false; @@ -212,6 +225,7 @@ namespace CodeWalker.Rendering disposed = true; dsEnabled.Dispose(); + dsDisableWriteRev.Dispose(); dsDisableWrite.Dispose(); dsDisableComp.Dispose(); dsDisableAll.Dispose(); @@ -235,6 +249,13 @@ namespace CodeWalker.Rendering Cable.Dispose(); Water.Dispose(); + + if (DefScene != null) + { + DefScene.Dispose(); + DefScene = null; + } + if (HDR != null) { HDR.Dispose(); @@ -286,6 +307,16 @@ namespace CodeWalker.Rendering HDR.Dispose(); HDR = null; } + if (deferred && (DefScene == null)) + { + DefScene = new DeferredScene(DXMan); + DefScene.OnWindowResize(DXMan); + } + if (!deferred && (DefScene != null)) + { + DefScene.Dispose(); + DefScene = null; + } foreach (var bucket in RenderBuckets) @@ -295,10 +326,16 @@ namespace CodeWalker.Rendering RenderBoundGeoms.Clear(); RenderInstBatches.Clear(); + RenderLODLights.Clear(); RenderDistLODLights.Clear(); RenderPathBatches.Clear(); RenderWaterQuads.Clear(); + + if (DefScene != null) + { + DefScene.Clear(context); + } if (HDR != null) { HDR.Clear(context); @@ -312,6 +349,12 @@ namespace CodeWalker.Rendering Skydome.EnableHDR = hdr; Clouds.EnableHDR = hdr; + + Basic.Deferred = deferred; + Cable.Deferred = deferred; + Water.Deferred = deferred; + Terrain.Deferred = deferred; + TreesLod.Deferred = deferred; } @@ -384,7 +427,11 @@ namespace CodeWalker.Rendering } - if (HDR != null) + if (DefScene != null) + { + DefScene.SetPrimary(context); + } + else if (HDR != null) { HDR.SetPrimary(context); } @@ -459,22 +506,6 @@ namespace CodeWalker.Rendering context.OutputMerger.BlendState = bsDefault; } - if (RenderDistLODLights.Count > 0) //LOD lights pass - { - context.Rasterizer.State = rsSolidDblSided; - context.OutputMerger.BlendState = bsAdd; //additive blend for distant lod lights... - context.OutputMerger.DepthStencilState = dsDisableWrite; - DistLights.SetShader(context); - DistLights.SetSceneVars(context, Camera, Shadowmap, GlobalLights); - for (int i = 0; i < RenderDistLODLights.Count; i++) - { - DistLights.RenderBatch(context, RenderDistLODLights[i]); - } - DistLights.UnbindResources(context); - context.OutputMerger.BlendState = bsDefault; - context.OutputMerger.DepthStencilState = dsEnabled; - } - @@ -505,6 +536,9 @@ namespace CodeWalker.Rendering Water.UnbindResources(context); } + + + //TODO: needs second gbuffer pass? Basic.DecalMode = true; for (int i = 0; i < RenderBuckets.Count; i++) //alphablended and glass pass { @@ -525,6 +559,54 @@ namespace CodeWalker.Rendering + + + if (DefScene != null) + { + if (HDR != null) + { + HDR.SetPrimary(context); + } + else + { + DXMan.SetDefaultRenderTarget(context); + } + + DefScene.RenderLights(context, camera, Shadowmap, GlobalLights); + + if (RenderLODLights.Count > 0) //LOD lights pass + { + context.Rasterizer.State = rsSolid; + context.OutputMerger.BlendState = bsAdd; //additive blend for lights... + context.OutputMerger.DepthStencilState = dsDisableWriteRev;//only render parts behind or at surface + DefScene.RenderLights(context, camera, RenderLODLights); + } + } + + Basic.Deferred = false; + + + + + + if (RenderDistLODLights.Count > 0) //distant LOD lights pass + { + context.Rasterizer.State = rsSolidDblSided; + context.OutputMerger.BlendState = bsAdd; //additive blend for distant lod lights... + context.OutputMerger.DepthStencilState = dsDisableWrite; + DistLights.SetShader(context); + DistLights.SetSceneVars(context, Camera, Shadowmap, GlobalLights); + for (int i = 0; i < RenderDistLODLights.Count; i++) + { + DistLights.RenderBatch(context, RenderDistLODLights[i]); + } + DistLights.UnbindResources(context); + context.OutputMerger.BlendState = bsDefault; + context.OutputMerger.DepthStencilState = dsEnabled; + } + + + if (RenderBoundGeoms.Count > 0) //collision meshes pass { ClearDepth(context); //draw over everything else @@ -550,6 +632,8 @@ namespace CodeWalker.Rendering + Basic.Deferred = deferred; + RenderedGeometries = GeometryCount; } @@ -696,7 +780,7 @@ namespace CodeWalker.Rendering { Basic.RenderMode = WorldRenderMode.VertexColour; Basic.SetShader(context); - Basic.SetSceneVars(context, Camera, Shadowmap, GlobalLights); + Basic.SetSceneVars(context, Camera, /*Shadowmap*/ null, GlobalLights);//should this be using shadows?? Basic.SetInputLayout(context, VertexType.Default); GeometryCount += batch.Count; @@ -764,6 +848,10 @@ namespace CodeWalker.Rendering { RenderInstBatches.Add(batch); } + public void Enqueue(RenderableLODLights lights) + { + RenderLODLights.Add(lights); + } public void Enqueue(RenderableDistantLODLights lights) { RenderDistLODLights.Add(lights); @@ -880,6 +968,10 @@ namespace CodeWalker.Rendering { Width = w; Height = h; + if (DefScene != null) + { + DefScene.OnWindowResize(DXMan); + } if (HDR != null) { HDR.OnWindowResize(DXMan); diff --git a/Rendering/Shaders/BasicShader.cs b/Rendering/Shaders/BasicShader.cs index aca8662..b229667 100644 --- a/Rendering/Shaders/BasicShader.cs +++ b/Rendering/Shaders/BasicShader.cs @@ -145,6 +145,7 @@ namespace CodeWalker.Rendering VertexShader basicvscapsule; VertexShader basicvscylinder; PixelShader basicps; + PixelShader basicpsdef; GpuVarsBuffer VSSceneVars; GpuVarsBuffer VSEntityVars; GpuVarsBuffer 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(device); VSEntityVars = new GpuVarsBuffer(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(); diff --git a/Rendering/Shaders/CableShader.cs b/Rendering/Shaders/CableShader.cs index d2e79c2..37ca112 100644 --- a/Rendering/Shaders/CableShader.cs +++ b/Rendering/Shaders/CableShader.cs @@ -67,6 +67,7 @@ namespace CodeWalker.Rendering VertexShader vs; PixelShader ps; + PixelShader psdef; GpuVarsBuffer VSSceneVars; GpuVarsBuffer VSEntityVars; GpuVarsBuffer 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 layouts = new Dictionary(); @@ -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(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; diff --git a/Rendering/Shaders/DeferredScene.cs b/Rendering/Shaders/DeferredScene.cs new file mode 100644 index 0000000..4e6b037 --- /dev/null +++ b/Rendering/Shaders/DeferredScene.cs @@ -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 LightVSVars; + GpuVarsBuffer 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(device); + LightPSVars = new GpuVarsBuffer(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 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); + + + + + } + + + + } +} diff --git a/Rendering/Shaders/TerrainShader.cs b/Rendering/Shaders/TerrainShader.cs index ade9fdd..ef56252 100644 --- a/Rendering/Shaders/TerrainShader.cs +++ b/Rendering/Shaders/TerrainShader.cs @@ -78,6 +78,7 @@ namespace CodeWalker.Rendering VertexShader pnctttxvs; VertexShader pncttxvs; PixelShader terrainps; + PixelShader terrainpsdef; GpuVarsBuffer VSSceneVars; GpuVarsBuffer VSEntityVars; GpuVarsBuffer 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 layouts = new Dictionary(); @@ -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(device); VSEntityVars = new GpuVarsBuffer(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(); diff --git a/Rendering/Shaders/TreesLodShader.cs b/Rendering/Shaders/TreesLodShader.cs index 12430fa..ac16b83 100644 --- a/Rendering/Shaders/TreesLodShader.cs +++ b/Rendering/Shaders/TreesLodShader.cs @@ -59,8 +59,9 @@ namespace CodeWalker.Rendering { bool disposed = false; - VertexShader basicvs; - PixelShader basicps; + VertexShader vs; + PixelShader ps; + PixelShader psdef; GpuVarsBuffer VSSceneVars; GpuVarsBuffer VSEntityVars; GpuVarsBuffer VSModelVars; @@ -71,14 +72,18 @@ namespace CodeWalker.Rendering private Dictionary layouts = new Dictionary(); + 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(device); VSEntityVars = new GpuVarsBuffer(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; } diff --git a/Rendering/Shaders/WaterShader.cs b/Rendering/Shaders/WaterShader.cs index 93fb882..57c32dd 100644 --- a/Rendering/Shaders/WaterShader.cs +++ b/Rendering/Shaders/WaterShader.cs @@ -84,6 +84,7 @@ namespace CodeWalker.Rendering VertexShader vspnct; VertexShader vspnctx; PixelShader ps; + PixelShader psdef; GpuVarsBuffer VSSceneVars; GpuVarsBuffer 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(device); VSEntityVars = new GpuVarsBuffer(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(); diff --git a/Rendering/Utils/GpuBuffers.cs b/Rendering/Utils/GpuBuffers.cs index 353ce4b..d67cf32 100644 --- a/Rendering/Utils/GpuBuffers.cs +++ b/Rendering/Utils/GpuBuffers.cs @@ -421,4 +421,133 @@ namespace CodeWalker.Rendering } + public class GpuMultiTexture //multiple texture and render targets (depth). + { + public Texture2D[] Textures; + public Texture2D Depth; + public RenderTargetView[] RTVs; + public DepthStencilView DSV; + public ShaderResourceView[] SRVs; + public ShaderResourceView DepthSRV; + public int VramUsage; + public bool UseDepth; + public int Count; + + public void Init(Device device, int w, int h, int count, Format f, bool depth, Format df) + { + Count = count; + VramUsage = 0; + UseDepth = depth; + 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; + DepthStencilViewDimension dsvd = DepthStencilViewDimension.Texture2D; + + 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); + 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); + } + if (depth) + { + Format dtexf = Format.R32_Typeless; + Format dsrvf = Format.R32_Float; + switch (df) + { + case Format.D16_UNorm: + dtexf = Format.R16_Typeless; + dsrvf = Format.R16_UNorm; + break; + case Format.D24_UNorm_S8_UInt: + dtexf = Format.R24G8_Typeless; + dsrvf = Format.R24_UNorm_X8_Typeless; + break; + case Format.D32_Float: + dtexf = Format.R32_Typeless; + dsrvf = Format.R32_Float; + break; + case Format.D32_Float_S8X24_UInt: + dtexf = Format.R32G8X24_Typeless;//is this right? who uses this anyway?? + dsrvf = Format.R32_Float_X8X24_Typeless; + break; + } + + Depth = DXUtility.CreateTexture2D(device, w, h, 1, 1, dtexf, 1, 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)); + } + } + public void Dispose() + { + for (int i = 0; i < Count; i++) + { + SRVs[i].Dispose(); + RTVs[i].Dispose(); + Textures[i].Dispose(); + } + SRVs = null; + RTVs = null; + Textures = null; + + if (DSV != null) + { + DSV.Dispose(); + DSV = null; + } + if (DepthSRV != null) + { + DepthSRV.Dispose(); + DepthSRV = null; + } + if (Depth != null) + { + Depth.Dispose(); + Depth = null; + } + } + public GpuMultiTexture(Device device, int w, int h, int count, Format f, bool depth, Format df) + { + Init(device, w, h, count, f, depth, df); + } + public GpuMultiTexture(Device device, int w, int h, int count, Format f) + { + Init(device, w, h, count, f, false, Format.Unknown); + } + + public void Clear(DeviceContext context, Color4 colour) + { + for (int i = 0; i < Count; i++) + { + context.ClearRenderTargetView(RTVs[i], colour); + } + if (UseDepth) + { + context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0); + } + } + + public void ClearDepth(DeviceContext context) + { + if (!UseDepth) return; + context.ClearDepthStencilView(DSV, DepthStencilClearFlags.Depth, 0.0f, 0); + } + + public void SetRenderTargets(DeviceContext context) + { + context.OutputMerger.SetRenderTargets(UseDepth ? DSV : null, RTVs); + } + + } + } diff --git a/Rendering/Utils/UnitCapsule.cs b/Rendering/Utils/UnitCapsule.cs index 6561281..585ce03 100644 --- a/Rendering/Utils/UnitCapsule.cs +++ b/Rendering/Utils/UnitCapsule.cs @@ -33,7 +33,7 @@ namespace CodeWalker.Rendering } } - public UnitCapsule(Device device, byte[] vsbytes, int detail) + public UnitCapsule(Device device, byte[] vsbytes, int detail, bool invert = false) { InputLayout = new InputLayout(device, vsbytes, new[] @@ -208,8 +208,8 @@ namespace CodeWalker.Rendering foreach (var tri in curtris) { idata.Add((uint)tri.v1); - idata.Add((uint)tri.v2); - idata.Add((uint)tri.v3); + idata.Add((uint)(invert ? tri.v3 : tri.v2)); + idata.Add((uint)(invert ? tri.v2 : tri.v3)); } diff --git a/Rendering/Utils/UnitCone.cs b/Rendering/Utils/UnitCone.cs new file mode 100644 index 0000000..5bec8a3 --- /dev/null +++ b/Rendering/Utils/UnitCone.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SharpDX; +using SharpDX.Direct3D; +using SharpDX.Direct3D11; +using Device = SharpDX.Direct3D11.Device; +using Buffer = SharpDX.Direct3D11.Buffer; +using SharpDX.DXGI; + +namespace CodeWalker.Rendering +{ + public class UnitCone + { + private Buffer VertexBuffer { get; set; } + private Buffer IndexBuffer { get; set; } + private InputLayout InputLayout { get; set; } + private VertexBufferBinding vbbinding; + private int indexcount; + + private struct SphTri + { + public int v1; + public int v2; + public int v3; + public SphTri(int i1, int i2, int i3) + { + v1 = i1; + v2 = i2; + v3 = i3; + } + } + + public UnitCone(Device device, byte[] vsbytes, int detail, bool invert = false) + { + + InputLayout = new InputLayout(device, vsbytes, new[] + { + new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), + new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0), + }); + + + + List verts = new List(); + Dictionary vdict = new Dictionary(); + List curtris = new List(); + + verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f));//top end (translated by VS!) + verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal + verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 1.0f));//bottom end + verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 1.0f));//bottom normal + + int nlons = detail * 4; + int lastlon = nlons - 1; + float latrng = 1.0f / (detail); + float lonrng = 1.0f / (nlons); + float twopi = (float)(2.0 * Math.PI); + + for (int lon = 0; lon < nlons; lon++) + { + float tlon = lon * lonrng; + float rlon = tlon * twopi; + float lonx = (float)Math.Sin(rlon); + float lonz = (float)Math.Cos(rlon); + + verts.Add(new Vector4(lonx, 0.0f, lonz, 1.0f));//2 + verts.Add(new Vector4(lonx, 0.0f, lonz, 0.0f));//side normal + verts.Add(new Vector4(lonx, 0.0f, lonz, 1.0f));//3 + verts.Add(new Vector4(0.0f, 1.0f, 0.0f, 0.0f));//bottom normal + } + + for (int lon = 0; lon < nlons; lon++) + { + int i0 = 2 + lon * 2; + int i1 = i0 + 2; + + if (lon == lastlon) + { + i1 = 2; + } + + curtris.Add(new SphTri(0, i0, i1)); //fill the cone + curtris.Add(new SphTri(1, i1+1, i0+1)); //bottom cap triangles + } + + + + List idata = new List(); + foreach (var tri in curtris) + { + idata.Add((uint)tri.v1); + idata.Add((uint)(invert ? tri.v2 : tri.v3)); + idata.Add((uint)(invert ? tri.v3 : tri.v2)); + } + + + VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray()); + vbbinding = new VertexBufferBinding(VertexBuffer, 32, 0); + + IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray()); + indexcount = idata.Count; + + } + + + public void Draw(DeviceContext context) + { + context.InputAssembler.InputLayout = InputLayout; + context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; + context.InputAssembler.SetVertexBuffers(0, vbbinding); + context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0); + + context.DrawIndexed(indexcount, 0, 0); + } + + public void DrawInstanced(DeviceContext context, int count) + { + context.InputAssembler.InputLayout = InputLayout; + context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; + context.InputAssembler.SetVertexBuffers(0, vbbinding); + context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0); + + context.DrawIndexedInstanced(indexcount, count, 0, 0, 0); + } + + + public void Dispose() + { + if (VertexBuffer != null) + { + VertexBuffer.Dispose(); + VertexBuffer = null; + } + if (IndexBuffer != null) + { + IndexBuffer.Dispose(); + IndexBuffer = null; + } + if (InputLayout != null) + { + InputLayout.Dispose(); + InputLayout = null; + } + } + + } + + +} diff --git a/Rendering/Utils/UnitSphere.cs b/Rendering/Utils/UnitSphere.cs index bbf36da..33f5992 100644 --- a/Rendering/Utils/UnitSphere.cs +++ b/Rendering/Utils/UnitSphere.cs @@ -33,7 +33,7 @@ namespace CodeWalker.Rendering } } - public UnitSphere(Device device, byte[] vsbytes, int detail) + public UnitSphere(Device device, byte[] vsbytes, int detail, bool invert = false) { InputLayout = new InputLayout(device, vsbytes, new[] @@ -121,8 +121,8 @@ namespace CodeWalker.Rendering foreach (var tri in curtris) { idata.Add((uint)tri.v1); - idata.Add((uint)tri.v2); - idata.Add((uint)tri.v3); + idata.Add((uint)(invert ? tri.v3 : tri.v2)); + idata.Add((uint)(invert ? tri.v2 : tri.v3)); } diff --git a/Shaders/BasicPS.cso b/Shaders/BasicPS.cso index 9a0122e4608fa0c3b274887eda7a0209910ff685..05695f26be462b52f69429b6a722103059643a4a 100644 GIT binary patch delta 114 zcmZ1xb|lQuCBn(sDKqi$OVzLbMs2c8U%Z}%GcqtRxM(vlumWilAQs?eV5s3?VAue} zCpH>3^Kc5tF)%m)Wm-1xF2=D@N$>gJ2 F$pCuI7%2b% delta 100 zcmX>Swj#{XCBn&hMyAF2>%Y_2=ReF6j#sjs$;iOKprOsczzU>IfLMT=fuV+nfnfs> uui0qW%)|LbmVv=yOSZ z)04zTF84L=XtYL5PiS&qh1xPuV@zObhHZp}yB_4I8|_B{e^p~kb8u7*e_i-;*bJM5}HU*U{vYFUL`(6xwN+wA1# zS`hIX7b>cLB^7#cE0gIU#rm~chD|nF)hpG@)m?(SKrcJ5BCLcOZfI<&?^k#)X?#U} zO!UtK9f^J`(8omI4|FX0-9Rsj{#&3|MQ8hx6E^IIRhF4rWi3t08^R{|y|db+6}J!oj-nUklfD@Cg0~;pE*d z|0m(ppd0_IaQ0(2{!ih$W*)%{I)GH6TYkUrD2E^9psF3w_<4;cZ}@THM*@zV;Zwq& z>47f^XRXLV%i`8Gr?oW38p#>_rGUSpaZdAYzi$d>ZM*Sb311GlhITx^7rxR1e^2=H zIo!_QpM|dq?~XIuFX6@syN7EekQeH@ebRYdGht)t`svKFONjYwvzT12q#9>7tIcNh zI|)#=*@C&IyQ^ADn%REbeMTqKt&K`qs);*aX{`I{RH{wtwwuYabdof!w5s)*TlY6! zS(jV2b`?{Poabg1+-yx=o8Pwc-nlE_Z>N=p1d>{_+InGrJ8d~bOO-UOU%9dyYb4ED zlDcb2i}>MHx6*3T@b~aSEq%c*Yah6GJ72xrs5k3ZTG5fEFGT0(%5xFNF=<58b=5&< zD>`}f_|Y$&Ja+8p7f&8Pb;8Y-&s|v8{mZwDvlEM^F z0dQj>558X;5*(Ta?t74jrZKV?@ryh(4O~aijn%Wx8dK%3dCd%tUl;vVH^)(v5M&nCsQ9$o0H!v`= z6SeoyqRKYzZ#3r)3#So7U!3iyNLynq@IQK4Gd1{ySU+m`!9ML-ZM%Cx_V!2?+u##f zu8hbcWA-lX$z*PSCga`Sm(7ux2zCa;cq_=3LLFx$^C0j_HolnY+j=jA+^7rrFy?bt zE&4~K3vTwHKRlepQrSg_d$ag_=g#)vF7Zw8*#kNk;|8hU$!9Ub8` zA3t??I_Q!&vT8%vgC>4tg5A5?Pb1i*v4=fRbiV%Zq8_!!UZ|0KQa~klSaE^MP!)4?&%^{U3dhuhrJ}5VqT~##r4s8$BjpYNYiWUJJPl_GR@O zyph!}d{f%>U_J7=Yrl_Jt)AZL=-9ehjV7WjR{WjL$yux>r~NX_UP7)A>!+)6XV@BZ zXAp~>D@NL>$PHUv+V+D_?2c=xWoHaOv`asT{FuA%&I+*Z3bAIYW2b-ozK(j-8g2F# zv2s>E2yqYY4YfWr=HD{pW-(cAw}wKF;ao+!rze8`EyYbf*e%4_2yG2tQ$g11a5{X4 zo{ijIYJ@)L2t8X{lT~#7tYNP-9^wdNF?X&_9)IryTikuLLFI;R?UPY*>lgjQ{tPR` znsn++y{gJKz8|7 zT>7zQYPM(m8fZ>_)YR6J^Fs{i5Cigz;M|Q9vIl10A~4nr%245y)>)Eywh5aXACPQv!=P9L|e+SLv?iH&s?*d;e$c(0(t`rBI~{|;l1aM#{bOz7BK>9*dr=zxho!k!?X4^;!OLhRi6_rDs`U1;W; z+)NJN=$UU(BW+&;Sse0A?`TA2R)y= z$#M5u?mC%e4%4+MEv)~ z&eg}if0{e2ooA^3pz=gse~$Qf3AFjOQILN#db{Dx2;CR!N8gUGX}QPEulP5F!pC1j zICW&tgXQk3y&nV}?orp7Q6FrN2VK5%G<$!**Sh#Sm_6{@z_&Zj_66%VuDpdm_H9CK zRI{O}D68XP*`tP8tUG7*1{!UM2loGd1BvOTbZOLp*bKv79^>yt_^gM?O$cNCxZCX8 vgFP_QeNLg4mnWC`oBu_1_8X1=waAyh&sh)uz0laJ!Rv0H6hJ4=$F=_gqiAs7 literal 0 HcmV?d00001 diff --git a/Shaders/CablePS.cso b/Shaders/CablePS.cso index 92f24f7a8082f91cf46a298203e693b2bf7326be..a3ff7056e0a51d84b2a0a8d067a5fd98fcbf259e 100644 GIT binary patch delta 125 zcmZ2ue!|?)CBn)1{9Da`|HX}u-#tAu-C#}07DfgJh7-~Z46H!f1c>*r0|`zb8;E^2 z8nSb83J5VUH~e3Wf1OXf^=>2DZtWQs)I%L39I21_o{* KHk<4zoeTiVzZjAL delta 99 zcmX?MzQ)|pCBn%$d8Lk(*0#X1fW`xNEK8*H7#SEC)<`ojumWilAl}0cBshU=AU4=& p$j-_6MUa8P0Vr6z*^yIQaB_##8NrnhH9(Sqfg6ZTC#Om$0|2Tt6j}fP diff --git a/Shaders/CablePS_Deferred.cso b/Shaders/CablePS_Deferred.cso new file mode 100644 index 0000000000000000000000000000000000000000..a8ec1fbdec58a08488bb570964c5d2e4feb73264 GIT binary patch literal 3088 zcmai0J#1T56h3z1B&0#L0!URU;vp80swi=*5D;pd_$P_v*pZ(Tr7YBrUm6R?&%C%w z1}IS_Bw&CARUH^ngcODj9T-@M7&-t8h=~CS)EQ-{vZdem?mg~{vEWG8=iKjn_ndRj zz4s;A_4&;FFMt2uxiI^~x3}N>?4>`mZ^uL=IVO^TzKZeB05m4|F}^$}QqJb`4}itt zdx$ZJaS1~PPfrDlKZ5ToOricIjLmU?!S&3+^`{W1(Dy9#eNOs_uK&J|kMY!B@%B2m z0?&0N<2U_V!FIJRE3UiYwY;@zumgL+^S49ukhxgL3C2E#3Ujcw69i5w2;F89YNO;H z6GOg%CdM_C?=1chx`R1!LW=*2$zC7)FW?{a!55l-t=cR!Zf8DI^-$D!mb#vE;C&byH+cfZrHi)nx%v*idA&8+621VHk_wO*57RzY%b_DHX9p_ zGsH7s$o&xg`^5I}9`x53xNh*=yCkVA-#G^3+@cwrA&Vb-Ug4f{gD6b*x{v zt?oU~P2j|O@%Mp`SRAT*{(Hc=Z|%O`3sbMX!M6HJqt%g>YJF;Q(x@p}Zfpepj=$M) zUMs)uEEe2?!##R|lkvCP4HWE5Ph6RJb9!=eVru%z%vIipC3m672aabP)|7-zp|abO z^RO>joIc{54iAgG+JmFLG5`W`b&*ee44WfPn?gJsmQR~P%^ol>`PvWSJWJx2H8^bI zL&Q-Jadi;~)WxHD*?;m=O2(Z0XDsfny}MF!mnuu8q7+Nz<+*}Xa_gB=shpKesZc6Q zWv;l8D^}3N5_+ibnQ^x;R2Y-Onu%*V;DFVtpVJ>))iOg^<)liJLsHshmTamH}4m2vyU9o=`j_a~M%dwN+02S%+Q zZ@aaMf#;`}hmYAoR!6_<^tn=BB)X>u_Yb2cxF$q36xssmUcr-D_Gv5jf$FR=c2TIA=S3fFX?9C-np z5;%7(hx?|m7p#{ugDo>g40b+la^%O8;rnN;8vpTm>jNjs1v;$pxi0isokg3~_m-_8 zny(wv@>96d(OMWQp2m;JY-C70jad)YTL!JRyI@pJ39pq~r^sy(@@icyVa>mny z&erDOP90;fyf}`KmG5RCe2)}QUyTg!H%$gMZVP5o&dqtd)Ba6k;mfBVOv)2&bt;|*U_vJDM dzlRk5pTK*|9)$UzSxZ0Zhx31G{>}eCc>>U#IE4TJ literal 0 HcmV?d00001 diff --git a/Shaders/LightPS.cso b/Shaders/LightPS.cso new file mode 100644 index 0000000000000000000000000000000000000000..685dc0f93d258d19fbe53d29343924495772fa8a GIT binary patch literal 10036 zcmd^_UyNK;9mmh?ZnxWo(z0N!Rbglpv}m)Grj}CZ?7wL@Zo8Y#cC$4^neN_ghs@4Q zW_M{(LWasCA-rgm@X!#VP1=}-_&^N7iX@`)K$Hg)c_79pkES7LFb2P$bI)(~bb7Y| zeDtJe&N;vTf6u)$+tJzKk)L&M`RCzB|9;@^eJ_0f(#502oO5pXUC#At-K+V|2Ipq` zox7-c{!Zs!);u~oR(xLYZsFe)gHY}Zny%-gkDSh@gnLLU_;?_j3H+osU0T;^_Go^j zp~d4jYHeiTjUW7D8F=JD1OBNDJbDfPOa>l14F6mP9$O86UK`HD3D{J$=ll{M83Qo$ z)eOAhSVxn_@~Opgqf|<_)5)1O%#BtS7FL!LU`OiB#d4KhsgcaBRLf2Frzrohr}QPfLYAVb3knd#i%@R+KpWxIyp>=vWX+;=L7tr))xa@;5Pghf}hWz|Bc`mGvI#^{89w} ztImw~wf;NlyI9g1?ag9})b`0LMPFbELdjnoDZQ zRDDUI>(&eoh{kX;mE^R$aN$C?@I4Vetuc^(H(F_mWofQFpG+<+EG4SL3l~hLW(X-Y6}Xo6B|>tIfONdUHN$ zPL=29E47n{D>WxM_#TQ!a;~N*pK-&L@{${_t~7^}<Y$k6M@8Y94RlaG|N>%k2TVYU4@L+ zPuEh|P;deZE4;p1D@4-PLq6H3j4hFuZ8`f_HT!MLHqZ@ zeoFiQg#E+Xt6f!%JZ<~jt%@N%IMu8_LWQX>lV+KY9jld3RFm|EUlQ#tSJm**q^2rA zT%S+e>ULbPGvQn+FE*-4bEK|zNWGtatdY3!B|S+f*+D+;aa(owGq90bnALNi@ujh9 zvY4n3WlCkaQdb*YlSj)@r)^44GUs`wD~ricZC*XPoD{3&lS^*8TstYTv*f-rw*hzD z70cCXePJQ1J_2g&Oru`IyzyEsX%5v+Rueb5vK+RP&5?3r>htM>Wai zbbyn~ZwELTX=wkrW?uWJ!=AkUK>Kr=1??||{iybr!~T%=zYqHf?b96Js$IW(SMbA? zxn_N-zObDC%F(ap4^5ON@}xFt=11y_jfygr-?Q`Ho%ih-9Nc-&o_qK1mhI!EgGZJn zfzFW#pCc{)CbMqZr22UXU>Lx;={D(spBON}$Zt-_(#&_JCQIYf(?dr_#>Pk8g-Pkg4|vecd!&uFZUKf3s1-QxfVrEzj_IMJ2gjxnJUTWteaKxX z9U7Z`|MO`K>4!%Sx!mzS*He5Z?`?iS{Ks|eab`%2`&OUCKD^oEXSeD~Y>+YMjvZ62 zhBN-gXKaqo*cG3-SK~9e;`{uGLI^`Ya$X4n0a&VDbu2DC?);@o{D zpVDdHmAkC>XRXwkYHHmse`7dT46^npq^|{7S3yJ_*?MWU?v0mVi}wbM_ghYXTuSr7{^)l(6gcX61W8F#Idt6l8@O$5!ys<3NhnLR?caVE=F+23!z z;S=^tc56s0y00hy)7pBwYQ4Xem-O`eto0UW>cFq+YietA-u0cuI}OuUJe&7tK8T6o z_XWCK!MWePy)g7S`YgZc85esw~zE^a_oftzeT)*KA)>Uxs z?D_BQwJEZz{IUGR{^UbVqt9Z*eTh%NZr5EF=MJ6p3bN<}t50M?&#>Nu4mtAmfb|YE z#N5jW&zo++?uqP>zSfh1L7Vb_I2zl5tO40UPj<>8HsH6ffyZXEC5s=s@{ujX1UvR= zVhelK@C|VsyqvQs-8SJZ7WBO6eGZXpJw)s{Z;$kt>{wsyGcmnUgO@KC7R6 zy`}kT9oQf7S&YngYR+KTW^pxMY?Dv@z=_q4R=$0A(Kp`Wyy2U(eK1nt$HW()z=PZF)8h zX*K(Jw%OeTkML=%wQ>eGtUa=^+iXGBS~&RZPGjHZYvnyZb!vSIUU6vmht<73ulOEl zu?_b7dns2)WBcV0BjgYpTcN!#^4n_1--+U7D8B8uW!WfS*YsWW<=BO-z%K@N*ourj`Scyo`Y71t-%p7d@1hK7JHKPZK0t#H z*q++u4%q7Qt9@?%L!aXHTY_wOA=ovuF}06=YzoHnqf;;6W2ha&n~ms>-;v?P_cmR4 zZ|1(}#PtUKh9fud`4~ieb`Jb&+DIK_*~q=PmW`GJThW0XFPUw9Y0dJTiBZ%Udpc>* z(SD!2F{SnXP&Q188r(ZTu0}m=~)SLO{`6Um3R-=CPmewLhHk_0`x|?3@q4h@okhpH0`qZP zJ!T($L>~uS`yR1e4M-fZ#13K>#}dnm&DD7C5)E}0(;R{(#5=F_oe&Li>5XjeDhQx~ z4fG+yV&AR3`Oa#2!{!j*)~`eZo!M-;vG}u6Ths&mih=(wZ#;vwAHM?cU0Z(iKukxB zvgn`Mef-srL-*pw-yYzu*uE+!t;cYdj17j{7GS9l?lSA2H;otKcP{K6lKt3C9$9mt z=3OA1ual}`icg71XJdDmB3AnaC<24_%^qO4c zttB_$yj=Dsm+$h#hp{90VKO>t=$&m5joAV(ckAYS_FV>@*$*x9<9mX;ioSs^)w${i zc_v2Sjs-f^qnE)7{nmh^&O32<2H$W7j%SeQ`>zBXzp26BRnXs&w8nErcX213e9Gi~ zvemjjp7`DjI(S~AgWp(LkzqLQ9@FpKIay)T|DNe%B$n0RXT$RX`2&*6AXW_GV!zFH z;)KqmSB>)9>@_%Ka%aXk%c1FuaR$Q%ev<`OV literal 0 HcmV?d00001 diff --git a/Shaders/LightVS.cso b/Shaders/LightVS.cso new file mode 100644 index 0000000000000000000000000000000000000000..3d1f79966453fa1753663ebc4c1af5eb3fe4cfdf GIT binary patch literal 3056 zcmai0O>7%g5FRIPnx@bM6ND7;vnoBnfyg0I2&FVmZ7;SIY%6P7E~=C+$tH2-*wK1R zgM@_XiBm5~h;xNN5UE1FaVQ`GQW4>XxWK7r4pk(|4fwv@H>+)M=}2$iyqRx)->lb# z=DGY&uNJRA*}QrCcI7+g)}QaTQX+EqxX1|h1*~9LWFM=P7FmZpz*;F3?K#MXsK?^| z6qcm_{zvElx(nEjV9^gnH7pW&t_>arkm{GKh2_@fR?w4%6EY3g@5$aC?dbCptczGm zj7Qs#@z7XEL*^(1<*=A%&YWx5DVs3z3r60?PJ5Ia;&+Yw1MGDp$0jPj26=OU{6ol@ z6aA1B-)MPPYJT?;O4%DmqtY=#B=2r}zFX_E&J=X1gf8qs{hb{TI+4erGl{`>xrc5^ z&0Wv(F(Y3Z73*NlcliLFDz?3CuM-GDw1QT*6USkvBFcB$-OIlGCq|*=duyRhy|wKv zb=IB04LrN;ZuX?^b~fR*$(j!5ZFJ|wcH8al#s)DQkYxTwRova_c9>qd)A9VJ&Su+_ z>gB+&RX^|U6n6tS_zLxXZ)*Gn`|ntfApJj#oOgQ9$T^pzsDBd60)NWzS@17{U%<+N zFB!f7zG?Up_%*{XgXcV_WD?IY*@gU#)|%h#bvFX*`IQ%}(z3H`Ia}_!=Ue&i_D-t} zW`25h`jz=?c6w%hc3}>=mz~!udM~5!#CJ?dZ()2~WXTALK`GG!Q>!}VdbwH=r?Fb@ z^a8iD=9LSwSA}1`i}XPo#vsu)_6wdfsYE&T2q&HjjSS^U>Vz;%9I{?)=Bw3}LKwT^ z)R!vxB4azHVsr8+`NE!vN8{b6GcjTvu`i)M z`e&ci7js*^@x>YL^Kag`H3&m2ZHT$^_QKhRVbV{3{58c(z!e8$#Y8{j@hSo#u z40?4EGTs;CvJb$-Jyri|t9}9emiXVse_VvW@UEzvGQPAHwbz)sC-cO8#&=CS5`8ll z=Eq)=RENF46iP&1Hg`Elud%pm4~QE}$=Y#d68)M^Zx#8Q#i9v zv}ewYYa>_g$(mKieiBa%^HZ$WOgq-BnBfElx`8p6D`q0>nc7oE->hF_Br)v0Vl);b(5n40Q$u2cXQY&AL3zYLllJiLkN>2rw{BUTbt-FafBa4=4!&KphP0CifaA F0{{no7~%i` delta 99 zcmeCl_>gYs65-@5Bo+8gLR3Ju;kmSVwT_+@BLf4&2V({XRv>Kx#0^{w3~#s@7!-II u7)mx8e&*)%QD>Ch~s6}q9zM?a&QSQdR3WP_t(G5W!?CjyJdj8~Pl z>b$T=7c-tVX1M;;LWVooSe`pIcXFGF4lctu>C+ zXKStv9v1F=SXZiN7w2n@p?bYBEBWtZK!d2o`FvA&aC!XCgr`UI_}>W6zVrAi!V`l$ z{;$G+q5ywQ_?-p#+jMXcg}k1f!Y2jzdxgI*;5D`CbWr#QVt%a|lbUyHMn5ABKo;-N z>HQ)6VY#<+S?*l!>s$_WE{{~z^qKOk^^a5+9cisK#;a#*#yq#M9Ke}cW4U%d)bWXP zXBX!dYD-J+VCuo-&{$-8&|ilukB-mkaN}+u$0-M$29rw9kF9!-1w07wEH`X$u9Cx3Pg^Ab-bnEC zYz_S3`0+SG4*qdt4!kM}*DWFNMnVVpEh;+ju^v)t{FYDnrP|>?{KzuEvsc51a`1TW z8uJHP2K?MHhDVkGp1TFU%FNd%Cn|@h4^ND{@rkJ;2glsd#Ms1?n;tnfG%+zXtYA+l z)^?7fqp#1$40ug2z8N0B48|wmvUu2}SDN~PgXMdx0AF=^FqDa~??4j#sca~s#h%X&2UHu_AqC(Fs_)CR`W6ZDSW zp2?I_2|9P6{WK4lPW+2?;$vPXJTvRFJ))C!Db?!+I?)m9^!;}{lQ%yRzO<>W6PZ$~ zS59XV;^cK+$l^pCO6iT`guU4Qdad(&f`>SHz1kD&QmR+ZzQqY0@9oNJgxFIPkjpa6Ypj!g&Fh3G*2%h*>Xp+urt@llGx4=ZJ!n7OU8%k& zo+%@;nS7vM@oyf~Oe{;OUaqM=;K|0rIYF-;L`&&bQ1sN&Xyc*!1b(wzl zQcCq|jjVPoXI2;ZVR5mX8I78uo-Jn<^EKJ>F%LD9mp2-wV|k0Y$y+?Fp3Ht+Gwjvu zn|wp|y^o=0V*4@8&LS^=lbXrPd;i66XN1Ye_QAFM7cVsY$9`NhE&s)XOk6Xw&t3V6 z)ydWIm+lw&R-F`_Ev+~Q+Q+ROT7S24^Stn)PISci6dV_rKjeoRuaAjqeVV z_h+wgj9A{z-uUjo?#=Fwe6F!?_e0CR&Sk};b#~jm^6$PkVtKwh@c*)6!5RNyzBlj< z|9iAoWRTC_9p-=0_r~e39s8T*@f~;J?^1Cqk5L@|-}9(%1U|3+-Y_2P zZTREfjC&gz-}3q125<7VHy>B=T5r>ve*ePpUD)zpYw)pr%l|;j_cr!g{s$h#pzBUO zN$6v-xS8j*(y+fxu@jGb+`8^f@{6JOhV20!-5z`m^RRv{G@9|_@8!VHUKl-}%;eJGV~ETr$Vmy zy9$|}ZQ1?BOkKx3)EGRM?g}-pT4TgK_~!Kln(0Zx*#!TlX5#$-CWr8k$QS&^zZZf} z{I=xB@s=I`yB<88O$_>#bt%=Wqjs7Hk|?HT6JE1P&HhNXd<=WD8X4W0oiT;+R_%IT z?TtK0zmGMsy!57&J7AI%NFbR^qT@RxJLpGpBTo+Ib**M86P;~!@tXt zWe{_G;5)(F(+sca0*5Zc`AS^E zJ`R9u{gxpbe0g0$xt=W{_95RU$KS^LgU(ov`tbV@zyJF=$i+O=yzyYy{59Rg1Kr4* z9DL}eX5sg-4Z82pw(L=6{%hx_Y;E|A{9rs3_PQ&qIisj6?~i7DEv0%n$D7BGQp(i) zdG-MN|A)~_Eg;L8L(TG#oBH0)0+aXHCt$N@{L}>Y81xOpXx2A_Nmk$N0iAv?iSENB(+@wRlNxUVh*eP%;^y;H$nDMhu7?Dt;NL)>~)zxV~NEIsrm=LIxys{uz3!uLg`t1^9X nnt!kRqaOYZhr!=eO+EbmLA>~8Mpw}wfBCUZh&%Jhg7v=uES)b^ literal 0 HcmV?d00001 diff --git a/Shaders/TreesLodPS.cso b/Shaders/TreesLodPS.cso index d8645ac0d83bf42f7d137289709bd3fb38b71dbd..83662a266c53a14aa25a41302e846c246363ecc5 100644 GIT binary patch delta 137 zcmeAWSR!EP65-@5CNaxuul<5H9skR38l~4wW@KPsP~l);U7BL)EmCZI$ZAB1KT5MW@Q Ye3Narpd3&Xs0$2$rZEUkUdo;f06FIw=l}o! delta 111 zcmZ1?&>>*x65-^0_tw{I)9lt>@VVGjZ+>y-LPiD#1`ZAe238<#0>nPd3=9u|ScHXv zp=YCE2Qwqnl-{|6to8C<_z>%7Fn;4}-wugY3xw D{OB6r diff --git a/Shaders/TreesLodPS_Deferred.cso b/Shaders/TreesLodPS_Deferred.cso new file mode 100644 index 0000000000000000000000000000000000000000..52d8a7f3f9e8c25d0e45f90360506ab2d0d01313 GIT binary patch literal 1352 zcmZ`&O>a^`6ukv(v1u)0OuEqcmUTl~Xh=1&rRAfL0FUr!gWXta(UQK?-Th1d=7||Q|ZhxIL3Vh{J;%B0{uS8b>LX@q=$_;#47;h zydEeieHbQhZyNJEE=J7ca<0^$bdKD*<4CgAY#q7#wYHR;^g*Z5dAeD152e@Zu?B0O z0wKWIEDON6M-6j&y@Z(@K{Nb4@IkCc`8DuU|KQUHwVh^ND})e{YdDu~g7{KxcY#Bc zLre;dhi>bz^{8Xbm2X?wypy+_z1nWwwUVv}BF~m{){C!o zZ))2EXzar8L7M?Oo~H)#+@F{bc{alH9{dP68R413I?m>UlI`RwIlCxDyIfe!OC?=R z+IBf5NjqN1aQ>ErUu6NMe$)?J` zP&9$P7r=eU$h@(chMEfr^c)-wKZ z3^hT&kDP_$hxLn_>?#eQWh|l2eM&!RsvS+93pkm zUE3o?Vn;WXDrFO8g~TuDqWuX~qi(yf#1G*6?%XpB0db_!xjxVDJnr>>_g~ywyZO!V z#y@+1KOFyc=kDgwkG*5L^>ZL1FIGfy;Gg3AYEtCsl*lo@rIWSMRO!*2$PP5$p1z#A z9t8Q*ab>&GI+Gd5M83|&JYSlTEPl5|if!mJ`k)@IXCS$T;IoiW8|>iovL}#D;Cxhw zBfzeB1+tv}FdyoxdU0ePFp|q~WbC1jH1B!&py?v^Vbc^T9GaYwAY(=nvKGv@?`?XX zBTv@OS41v&WO`#^&SBU+Z03o&jL-63O~s>(m6SbSOW`zpo6uVh^f|%#Az!NjICa#> zjplugjPbELu8Wjh2VwVnIqvwbuaTVnXdrjn%d8fg$|Z#7w9cR>ai*wiT4rN~jb|}h zpY_+~Ygf@I^^!r8`wW9iWA`{eq6I}C>UZ=;r@JgdJ%VTBcQ$h64n zpi}#fRZv1C?`R>z8kJ3Ec0E5v<~BTRH>+SA!vk6VP)|Db5+ks#zMe$k9^>$r<#QVE z%Y3Yram>!v#%hI1Zi`Hs9amyP2TQdzS2fjssTqX`4HY>Thuz@0ulvn#MBJPfai=XP zb6o-tcHGJeS8Ey(SdsaVGYdJlf@eM$pdvGoAUhbiQyfd=U>iUA#PppplD}uby9op5 zMsOqsC%Jp8DU&Bh2MgiAlBFLVliAKQw8?De6PZ41)YgYSaT%PmIluR`1|@sXXcOG~IW~?{ z;N(c$Mn>Z;sF#x2@doU%0!oOB?MSqc*$uEQb-L6IF#Nm$=F1^vwA$(5_En>(;!yec zL*4JxbZV&>^mH7BC0504hGjEav|d7(JgtVVr_Y+*5%XAWrr}Pz+Tg}q#2D=01GkN( zp5(B3PCHPtrSMIbupe= zNR|$3P&o6l{B%6RJbq{Or{yTf=pW17`6tcTXE!tBN+jo~j|%$d%1ZS$j(Nre@vrWC N4Z52_q@Q=YZvf9op%VZA delta 2125 zcmdT_y=xO;7=Ny5^VQTg2{klnl1th&kSZK|fNQV~%sh`1Cf=upAIf=~x(%pf>8 zy{?LjqTpcYB)Et;I`}7492|5gh=Y^A-+S+Sy;dhTAGmw&o{!)2`QAM}|K&pc^p)jP zPfou4wpD)o{NmM#N4MYK`{9VlwW>%D_%yCdy&_u)kyp6BcIw-S*mPE85t@fPZxVBk z6WQ78Yxb2kWk5oZUhWydU1X)pdoPPb%g~8h%@t>;nFV+Xl5RXZi@1!82#jhyVHcf* zEUa#3GwN+Fx@tXOBolBXcAMCstU-*oT#eX(%oT|+b{C%GL;`0-5~4=hs$R+rBI{7Y zpiGMN>paxbaBhh4R@!cu8OCwh7*ncKN^cO6`PKtj*ysz8TTFD(&w>c_3HsU$sbi*D zQvosjEbDV3G2IPFfA*Um!$ao?&e{ql5@lJn?q>3=g;QZq88-#UKwtC4dE39k{mBQi zt{D`scdh1ezjsCH_It;w$NWkHhY8&6LrXxv~$e=9uX#Wes(= zkeNvt3+76x?Kbk!-KGo_TQ+)~xB6brIBm6CNUPT)!%kU!94W3b2D@Z);WJUmu>)~N zV!y0i&CG<6Y;@MkI_T2?XLQKI%c?Vyi?JGNYN}Jr3{uZGTc@XSM$;v$u~TORMkU%A zk>0kN87smv?k~DS-FRe>FXSblU27ys~bl+HRwrN1vr3jTN#M>ir??z7M&(2~DVu|f#zJ%Tv3%1zqqhPHj4Gt*PdL`FqLvo0so>huY zNPVbO*EoI>8$$99i8L)2*ZlsVgRf3^->%i1b-lHsOk;y{tu}$ztv*%K+dR%FE=~yv zKP1gVxCei>w1a2Fx5Fo{pD1{)OAQD%R&$BMnEqP@dSWsC4+`{sIsI)63kaC!-2%PEk7_x+(Z1G9 zt5rAMs5P!Nx04-r?%MVayxd5(;cq1Ev}rZu}3z zKPbR2)EcWvZGLO>YP;n;o7rl*y}ce)JCBi9&90-`<0ka@s>rl9EjxJ^=7xY|V*07= z)nMY0i-{^GsR_NbliBPeGmY!@44Z1Uw>GxcwhkB`0KILGLVY@fdqVsaW34?QKC6d( zTnTa{`I|vLEBR)SW6AFXc~SB&g1jO*yGwM10r#Qs^Yvu4mR7GO>y7IzCB?aC59DMi zt*@ueg~od7_Qg42H^MmFf$2u0xgNav`?0F~(F%YrLR%B6YxTus{iVQ1-DbJgxW1S) zlkJv2qn=I`J2#zdr_E%s(dt~KV5oCj;lhhJnSAZlg@bkDH-)QBK8C+7oZNQX|4cY} zHvF!}&~L<#i-SXke=PiYjl1zb3MbRu_@9MG1^8cuf1v>XhwxJc_-DdjEWiiV=cxzQ zB|jGDbHaIVbmJ$5PZZ#zye|SS*71|oOz4#1h-rrl>W!I>PRWS63e{8HN!PB`lIC2! zoz`1h?Qgrs?w^^IlUl8@vEkG$eZ6Fyrut@D+1O~M?W`zfQ?9#*7aDJ-+iAV+GOV(b ztg*z>){Yvq{HE(BuO&5=vd4*etDd%6VWly*u(j4~v>F@j=+x2|quKfDe3We=nr_He zy*?U0Gj`_7<7dyFd1-uX;$=5iy>Rh_diJ35Lyi55M2Q4-y3R4ly#Rr9?YzEU`90Ew zb6$sJ0B$Pmd5)=A!I2?2XNiAsWC)yl4u0I61Y9NKj)irxfv^|U!LfnB*^}901A+5x z(J!HT`5TLs>fG{N<)XV-Sz4HycgyFmOjjyPGj6&vUs+O5sVGPGF2dhcJx2I~h!xzz z1xGfVyg=Z{hTD8N54d7lPMVu4lfAv_?99?<%3CaaQU+gBn#wBRF}C?J>*mM!$&bl%eoTHDuMW9G&7mQ`PvlX__(r}b8NX)39FsW* zlgTGCb2*b#@jr~Rm`x^+Cga~^{43|BaNYwCeb>`B;PK2?`Bo&0thOZ$3`>u%)4P$6 z6J1ZtuXB;~Cxd=OdWhK2Ge=Lq%^wMNgMq)`dJmZ_)5D_ye=wNsqr4mKPDueB(K8Xb z0kbKa?b{J*uNNCQ7jUiR=lU38EOsZ)YmJ9N|D(Xm-yL#34=dT4e-fXYneLswVd`*;}$@ID#{p`udC5|2WgMT&b z7u_qtW-MoKSWhei<D#vK5Q6w+c3{+?LoWP57Y8Cc|X+3sP>8<%co(?1M~LE zC;Rhphy8IjKJNdpcTM-X$#GwQ!AIv_;3wqW*S23bV4offXCBtn*&Hj%v*yJ4r^G1x zd-9QS&b@o?ou5WhXSF8QPc9(Km*u~xX71?T=4!^@edgMnKJ_*3Wm%j%M_#$x(CL6_ z0 z%labyyC?QN(b4;CJgCa zzN2pq?{mMV4^wA`an_wa8gj3FAFv_cox2fi4&1YVakugNKi{)ppYJ*LE@dm`&w2)Z z*7j>PNo-j@qA7Z!otMQ+E^H2Uiv5V{koy(s8v}dl=Tr51Vuwnxe8Tk@;pbeiwQoA} zm)D&(o3MuVcKBq#Mglh*n~x1KvL?QX2OVT{>>d-7oj-R(_<)^fDVDN}xC`Ua{x_ek zIU1=aNB>_>CKme^=lx9FVC;eTYz>cvHNeo>Tx8}3Y=BtUcPZA7e{aDvGC!6V=IFz; sr@B0~%>S>J9{-IiengMz*MA>k$NyK;NjyN*em5znE_~B;s}79+4N?M3^#A|> literal 0 HcmV?d00001 diff --git a/VehicleForm.cs b/VehicleForm.cs index e610a7c..48ba738 100644 --- a/VehicleForm.cs +++ b/VehicleForm.cs @@ -132,6 +132,8 @@ namespace CodeWalker.Vehicles camera.TargetRotation.X = 0.5f * (float)Math.PI; camera.CurrentRotation.X = 0.5f * (float)Math.PI; + Renderer.shaders.deferred = false; //no point using this here yet + LoadSettings(); diff --git a/WorldForm.Designer.cs b/WorldForm.Designer.cs index b8201d1..055fa64 100644 --- a/WorldForm.Designer.cs +++ b/WorldForm.Designer.cs @@ -295,6 +295,7 @@ namespace CodeWalker this.ToolbarPanel = new System.Windows.Forms.Panel(); this.SubtitleLabel = new System.Windows.Forms.Label(); this.SubtitleTimer = new System.Windows.Forms.Timer(this.components); + this.DeferredShadingCheckBox = new System.Windows.Forms.CheckBox(); this.StatusStrip.SuspendLayout(); this.ToolsPanel.SuspendLayout(); this.ToolsTabControl.SuspendLayout(); @@ -2200,6 +2201,7 @@ namespace CodeWalker // // tabPage10 // + this.tabPage10.Controls.Add(this.DeferredShadingCheckBox); this.tabPage10.Controls.Add(this.WeatherRegionComboBox); this.tabPage10.Controls.Add(this.label29); this.tabPage10.Controls.Add(this.CloudParamTrackBar); @@ -2361,7 +2363,7 @@ namespace CodeWalker this.ArtificialAmbientLightCheckBox.AutoSize = true; this.ArtificialAmbientLightCheckBox.Checked = true; this.ArtificialAmbientLightCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.ArtificialAmbientLightCheckBox.Location = new System.Drawing.Point(10, 129); + this.ArtificialAmbientLightCheckBox.Location = new System.Drawing.Point(10, 137); this.ArtificialAmbientLightCheckBox.Name = "ArtificialAmbientLightCheckBox"; this.ArtificialAmbientLightCheckBox.Size = new System.Drawing.Size(124, 17); this.ArtificialAmbientLightCheckBox.TabIndex = 36; @@ -2374,7 +2376,7 @@ namespace CodeWalker this.NaturalAmbientLightCheckBox.AutoSize = true; this.NaturalAmbientLightCheckBox.Checked = true; this.NaturalAmbientLightCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.NaturalAmbientLightCheckBox.Location = new System.Drawing.Point(10, 106); + this.NaturalAmbientLightCheckBox.Location = new System.Drawing.Point(10, 115); this.NaturalAmbientLightCheckBox.Name = "NaturalAmbientLightCheckBox"; this.NaturalAmbientLightCheckBox.Size = new System.Drawing.Size(122, 17); this.NaturalAmbientLightCheckBox.TabIndex = 35; @@ -2387,7 +2389,7 @@ namespace CodeWalker this.DistantLODLightsCheckBox.AutoSize = true; this.DistantLODLightsCheckBox.Checked = true; this.DistantLODLightsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.DistantLODLightsCheckBox.Location = new System.Drawing.Point(10, 83); + this.DistantLODLightsCheckBox.Location = new System.Drawing.Point(10, 93); this.DistantLODLightsCheckBox.Name = "DistantLODLightsCheckBox"; this.DistantLODLightsCheckBox.Size = new System.Drawing.Size(111, 17); this.DistantLODLightsCheckBox.TabIndex = 34; @@ -2400,7 +2402,7 @@ namespace CodeWalker this.HDRRenderingCheckBox.AutoSize = true; this.HDRRenderingCheckBox.Checked = true; this.HDRRenderingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.HDRRenderingCheckBox.Location = new System.Drawing.Point(10, 9); + this.HDRRenderingCheckBox.Location = new System.Drawing.Point(10, 27); this.HDRRenderingCheckBox.Name = "HDRRenderingCheckBox"; this.HDRRenderingCheckBox.Size = new System.Drawing.Size(97, 17); this.HDRRenderingCheckBox.TabIndex = 31; @@ -2413,7 +2415,7 @@ namespace CodeWalker this.ControlTimeOfDayCheckBox.AutoSize = true; this.ControlTimeOfDayCheckBox.Checked = true; this.ControlTimeOfDayCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.ControlTimeOfDayCheckBox.Location = new System.Drawing.Point(10, 180); + this.ControlTimeOfDayCheckBox.Location = new System.Drawing.Point(10, 181); this.ControlTimeOfDayCheckBox.Name = "ControlTimeOfDayCheckBox"; this.ControlTimeOfDayCheckBox.Size = new System.Drawing.Size(166, 17); this.ControlTimeOfDayCheckBox.TabIndex = 38; @@ -2479,7 +2481,7 @@ namespace CodeWalker // ControlLightDirectionCheckBox // this.ControlLightDirectionCheckBox.AutoSize = true; - this.ControlLightDirectionCheckBox.Location = new System.Drawing.Point(10, 157); + this.ControlLightDirectionCheckBox.Location = new System.Drawing.Point(10, 159); this.ControlLightDirectionCheckBox.Name = "ControlLightDirectionCheckBox"; this.ControlLightDirectionCheckBox.Size = new System.Drawing.Size(177, 17); this.ControlLightDirectionCheckBox.TabIndex = 37; @@ -2492,7 +2494,7 @@ namespace CodeWalker this.SkydomeCheckBox.AutoSize = true; this.SkydomeCheckBox.Checked = true; this.SkydomeCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.SkydomeCheckBox.Location = new System.Drawing.Point(10, 55); + this.SkydomeCheckBox.Location = new System.Drawing.Point(10, 71); this.SkydomeCheckBox.Name = "SkydomeCheckBox"; this.SkydomeCheckBox.Size = new System.Drawing.Size(70, 17); this.SkydomeCheckBox.TabIndex = 33; @@ -2503,7 +2505,7 @@ namespace CodeWalker // ShadowsCheckBox // this.ShadowsCheckBox.AutoSize = true; - this.ShadowsCheckBox.Location = new System.Drawing.Point(10, 32); + this.ShadowsCheckBox.Location = new System.Drawing.Point(10, 49); this.ShadowsCheckBox.Name = "ShadowsCheckBox"; this.ShadowsCheckBox.Size = new System.Drawing.Size(70, 17); this.ShadowsCheckBox.TabIndex = 32; @@ -3413,6 +3415,19 @@ namespace CodeWalker // this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick); // + // DeferredShadingCheckBox + // + this.DeferredShadingCheckBox.AutoSize = true; + this.DeferredShadingCheckBox.Checked = true; + this.DeferredShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.DeferredShadingCheckBox.Location = new System.Drawing.Point(10, 5); + this.DeferredShadingCheckBox.Name = "DeferredShadingCheckBox"; + this.DeferredShadingCheckBox.Size = new System.Drawing.Size(107, 17); + this.DeferredShadingCheckBox.TabIndex = 30; + this.DeferredShadingCheckBox.Text = "Deferred shading"; + this.DeferredShadingCheckBox.UseVisualStyleBackColor = true; + this.DeferredShadingCheckBox.CheckedChanged += new System.EventHandler(this.DeferredShadingCheckBox_CheckedChanged); + // // WorldForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -3767,5 +3782,6 @@ namespace CodeWalker private System.Windows.Forms.ToolStripMenuItem ToolsMenuCutsceneViewer; private System.Windows.Forms.Label SubtitleLabel; private System.Windows.Forms.Timer SubtitleTimer; + private System.Windows.Forms.CheckBox DeferredShadingCheckBox; } } \ No newline at end of file diff --git a/WorldForm.cs b/WorldForm.cs index acb01fd..37442da 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -4659,6 +4659,7 @@ namespace CodeWalker WindowState = s.WindowMaximized ? FormWindowState.Maximized : WindowState; FullScreenCheckBox.Checked = s.FullScreen; WireframeCheckBox.Checked = s.Wireframe; + DeferredShadingCheckBox.Checked = s.Deferred; HDRRenderingCheckBox.Checked = s.HDR; ShadowsCheckBox.Checked = s.Shadows; SkydomeCheckBox.Checked = s.Skydome; @@ -4693,6 +4694,7 @@ namespace CodeWalker s.WindowMaximized = (WindowState == FormWindowState.Maximized); s.FullScreen = FullScreenCheckBox.Checked; s.Wireframe = WireframeCheckBox.Checked; + s.Deferred = DeferredShadingCheckBox.Checked; s.HDR = HDRRenderingCheckBox.Checked; s.Shadows = ShadowsCheckBox.Checked; s.Skydome = SkydomeCheckBox.Checked; @@ -7258,6 +7260,14 @@ namespace CodeWalker Renderer.renderchildents = ShowYmapChildrenCheckBox.Checked; } + private void DeferredShadingCheckBox_CheckedChanged(object sender, EventArgs e) + { + lock (Renderer.RenderSyncRoot) + { + Renderer.shaders.deferred = DeferredShadingCheckBox.Checked; + } + } + private void HDRRenderingCheckBox_CheckedChanged(object sender, EventArgs e) { lock (Renderer.RenderSyncRoot) diff --git a/WorldForm.resx b/WorldForm.resx index 1ea334c..70dd9c9 100644 --- a/WorldForm.resx +++ b/WorldForm.resx @@ -240,14 +240,6 @@ ufo YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB4SURBVDhP3ZC7DcAgDEQZKTMwHOvSIFriS7BlEB+HMic9 QJbvFThLUkpXzjkSpaeuzMPlEELx3jdsBauyCHBY6UWYPQI93KEljQD3jL6EGzN6x0bASyNYwkKU8Udm gd6TMnIikDJyIqjVNz8T7FgKrAwFX6lVinM3aJ05lWDPRRcAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2 - CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f - wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg== @@ -269,13 +261,12 @@ ufo WBXYx9R1nV75RuyHKrrnzCcGjE1u9ZyD4BugoZigQ9xrngAAAABJRU5ErkJggg== - + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPrZBBEsIgEAR5Gy/wFV55T/wHr+KgHuCKNsVY - ZI2JiU7VVIVlp7OL+1mllIr7cb8Ie++PQwQYITnnM24NWxoBgsQYm/l+gk699bMsRA4h1JTSPsg0Xert - em/mGwh3vW1Z7MvIABSWqXG3+iZHAEw1m4wD49oVANgVOL/VeSgeDAiX1mpWeKy9BIQiI+OxWQF77tG5 - 2Fc729BmeElf/3lNhORe+oecewDObEqX49RqCgAAAABJRU5ErkJggg== + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2 + CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f + wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg== @@ -304,6 +295,15 @@ ufo EcMw2DzPDMEke9AsYBrHs10vN4I1QqImwwDcFyMjQGaBHr5Bo8nEoYCnCQTGzVeI4oj6fIi+KHgoPBhC 4knCjTww9vxfbIUQNDEyiGIZ8t6tW/k0vC/AOpuiueNOLwVkUeylvju9FJCg8E1vM/2PlTv5UoervVTJ uQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPrZBBEsIgEAR5Gy/wFV55T/wHr+KgHuCKNsVY + ZI2JiU7VVIVlp7OL+1mllIr7cb8Ie++PQwQYITnnM24NWxoBgsQYm/l+gk699bMsRA4h1JTSPsg0Xert + em/mGwh3vW1Z7MvIABSWqXG3+iZHAEw1m4wD49oVANgVOL/VeSgeDAiX1mpWeKy9BIQiI+OxWQF77tG5 + 2Fc729BmeElf/3lNhORe+oecewDObEqX49RqCgAAAABJRU5ErkJggg== @@ -389,17 +389,6 @@ ufo 4BJN+IjGo5O8ZJndGVhKxpjWWts551aih0fre+0BLaVchRAezPB2NXSSV/gVwXGYPJiVUt6ns1ghCDjn UQG86w3FToVgDcWCWS9Fvi/Ao0RVAcwUjwpyhzmf4n8BFApS5HZRwRuONGMbrIJ1JIN8O2QAAAAASUVO RK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG - WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM - TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G - UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC - ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 - 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII= @@ -435,6 +424,17 @@ ufo rp3fhGJScIRLzKMLFTC9cMIu3nCDVUyjB6WkYA93mEWbAyH9cMImPuA+rWMA31YwBU82kF6BS32Er/aO M8zAh+OEghpcwQ2bg3uwBW8ewFd7xQkm0IA4oaAS7bh2KHjBIZbhV/D6GJkFphrdcIP8lFrAGPwPOjCO QdQiTqrAWNICd7gPnUj+xBKaU9dxfhTkjwV/FxU+AbsiGnc46OYIAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG + WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM + TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G + UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC + ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 + 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII=