From 0bef5967c47a32d7fb84a9147ccaed47ae59d3ab Mon Sep 17 00:00:00 2001 From: Asval Date: Sat, 18 May 2024 05:48:57 +0200 Subject: [PATCH] improved shader --- CUE4Parse | 2 +- FModel/App.xaml.cs | 9 +++++- FModel/Resources/default.frag | 31 ++++++++++++------- FModel/Resources/default.vert | 1 + FModel/Resources/outline.vert | 7 +++-- FModel/Views/Snooper/Shading/Material.cs | 31 +++++++------------ FModel/Views/Snooper/Shading/Shader.cs | 27 +++++++++++----- FModel/Views/Snooper/Shading/Texture.cs | 10 +++--- FModel/Views/Snooper/Shading/TextureHelper.cs | 18 +++++------ 9 files changed, 78 insertions(+), 58 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index ec0a8288..3fe4665c 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit ec0a82887540dc982c5c755020323b5a341dbde1 +Subproject commit 3fe4665cb0d824fd54d92c980bb03488ccb234b1 diff --git a/FModel/App.xaml.cs b/FModel/App.xaml.cs index f5de48d8..e5161508 100644 --- a/FModel/App.xaml.cs +++ b/FModel/App.xaml.cs @@ -50,7 +50,14 @@ public partial class App var createMe = false; if (!Directory.Exists(UserSettings.Default.OutputDirectory)) { - UserSettings.Default.OutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Output"); + var currentDir = Directory.GetCurrentDirectory(); + var dirInfo = new DirectoryInfo(currentDir); + if (dirInfo.Attributes.HasFlag(FileAttributes.Archive)) + throw new Exception("FModel cannot be run from an archive file. Please extract it and try again."); + if (dirInfo.Attributes.HasFlag(FileAttributes.ReadOnly)) + throw new Exception("FModel cannot be run from a read-only directory. Please move it to a writable location."); + + UserSettings.Default.OutputDirectory = Path.Combine(currentDir, "Output"); } if (!Directory.Exists(UserSettings.Default.RawDataDirectory)) diff --git a/FModel/Resources/default.frag b/FModel/Resources/default.frag index 71f42fc2..3225bdf8 100644 --- a/FModel/Resources/default.frag +++ b/FModel/Resources/default.frag @@ -149,6 +149,11 @@ vec3 CalcLight(int layer, vec3 normals, vec3 position, vec3 color, float attenua { vec3 fLambert = SamplerToVector(uParameters.Diffuse[layer].Sampler).rgb * uParameters.Diffuse[layer].Color.rgb; vec3 specular_masks = SamplerToVector(uParameters.SpecularMasks[layer].Sampler).rgb; + float cavity = specular_masks.g; + if (uParameters.HasAo) + { + cavity = SamplerToVector(uParameters.Ao.Sampler).g; + } float roughness = mix(uParameters.RoughnessMin, uParameters.RoughnessMax, specular_masks.b); vec3 l = normalize(uViewPos - fPos); @@ -159,14 +164,14 @@ vec3 CalcLight(int layer, vec3 normals, vec3 position, vec3 color, float attenua float nDotH = max(dot(n, h), 0.0); float hDotv = max(dot(h, v), 0.0); - float nDotL = max(dot(n, l), 0.0); + float nDotL = max(dot(n, l), 0.4); float nDotV = max(dot(n, v), 0.0); vec3 f = schlickFresnel(fLambert, specular_masks.g, hDotv); vec3 kS = f; vec3 kD = 1.0 - kS; - kD *= 1.0 - specular_masks.g; + kD *= 1.0 - cavity; vec3 specBrdfNom = ggxDistribution(roughness, nDotH) * geomSmith(roughness, nDotL) * geomSmith(roughness, nDotV) * f; float specBrdfDenom = 4.0 * nDotV * nDotL + 0.0001; @@ -213,30 +218,32 @@ vec3 CalcSpotLight(int layer, vec3 normals, Light light) void main() { + int layer = LayerToIndex(); + vec3 normals = ComputeNormals(layer); + vec3 lightDir = normalize(uViewPos - fPos); + float diffuseFactor = max(dot(normals, lightDir), 0.4); + if (bVertexColors[1]) { - FragColor = vec4(uSectionColor, uOpacity); + FragColor = vec4(diffuseFactor * uSectionColor, uOpacity); } else if (bVertexColors[2] && uHasVertexColors) { - FragColor = fColor; + FragColor = vec4(diffuseFactor * fColor.rgb, fColor.a); } else if (bVertexColors[3]) { - int layer = LayerToIndex(); - vec3 normals = ComputeNormals(layer); FragColor = vec4(normals, uOpacity); } else if (bVertexColors[4]) { - FragColor = SamplerToVector(uParameters.Diffuse[0].Sampler); + vec4 diffuse = SamplerToVector(uParameters.Diffuse[0].Sampler); + FragColor = vec4(diffuseFactor * diffuse.rgb, diffuse.a); } else { - int layer = LayerToIndex(); - vec3 normals = ComputeNormals(layer); vec4 diffuse = SamplerToVector(uParameters.Diffuse[layer].Sampler); - vec3 result = uParameters.Diffuse[layer].Color.rgb * diffuse.rgb; + vec3 result = diffuseFactor * diffuse.rgb * uParameters.Diffuse[layer].Color.rgb; if (uParameters.HasAo) { @@ -246,7 +253,7 @@ void main() vec3 color = uParameters.Ao.ColorBoost.Color * uParameters.Ao.ColorBoost.Exponent; result = mix(result, result * color, m.b); } - result = vec3(uParameters.Ao.AmbientOcclusion) * result * m.r; + result *= m.r; } vec2 coords = fTexCoords; @@ -264,7 +271,7 @@ void main() } { - result += CalcLight(layer, normals, uViewPos, vec3(0.75), 1.0, false); + result += CalcLight(layer, normals, uViewPos, vec3(1.0), 1.0, false); vec3 lights = vec3(uNumLights > 0 ? 0 : 1); for (int i = 0; i < uNumLights; i++) diff --git a/FModel/Resources/default.vert b/FModel/Resources/default.vert index 97e564c7..b73bc5ef 100644 --- a/FModel/Resources/default.vert +++ b/FModel/Resources/default.vert @@ -77,6 +77,7 @@ void main() finalTangent += inverseBoneMatrix * bindTangent * weight; } } + finalPos = normalize(finalPos); } else { diff --git a/FModel/Resources/outline.vert b/FModel/Resources/outline.vert index a7049e5e..11cc1037 100644 --- a/FModel/Resources/outline.vert +++ b/FModel/Resources/outline.vert @@ -53,6 +53,7 @@ void main() finalNormal += transpose(inverse(boneMatrix)) * bindNormal * weight; } } + finalPos = normalize(finalPos); } else { @@ -60,10 +61,10 @@ void main() finalNormal = bindNormal; } - finalPos = vInstanceMatrix * finalPos; - float scaleFactor = distance(vec3(finalPos), uViewPos) * 0.0035; + vec4 worldPos = vInstanceMatrix * finalPos; + float scaleFactor = distance(worldPos.xyz, uViewPos) * 0.0035; vec4 nor = transpose(inverse(vInstanceMatrix)) * normalize(finalNormal) * scaleFactor; finalPos.xyz += nor.xyz; - gl_Position = uProjection * uView * finalPos; + gl_Position = uProjection * uView * vInstanceMatrix * finalPos; } diff --git a/FModel/Views/Snooper/Shading/Material.cs b/FModel/Views/Snooper/Shading/Material.cs index 2aabe66f..a63a0e58 100644 --- a/FModel/Views/Snooper/Shading/Material.cs +++ b/FModel/Views/Snooper/Shading/Material.cs @@ -76,12 +76,12 @@ public class Material : IDisposable if (uvCount < 1 || Parameters.IsNull) { - Diffuse = new[] { options.Icons["checker"] }; - Normals = new[] { new Texture(new FLinearColor(0.498f, 0.498f, 0.996f, 1f)) }; - SpecularMasks = new [] { new Texture(new FLinearColor(1f, 0.5f, 0.5f, 1f)) }; + Diffuse = [new Texture(new FLinearColor(1f, 1f, 1f, 1f))]; + Normals = [new Texture(new FLinearColor(0.498f, 0.498f, 0.996f, 1f))]; + SpecularMasks = [new Texture(new FLinearColor(1f, 0.5f, 0.5f, 1f))]; Emissive = new Texture[1]; - DiffuseColor = new[] { Vector4.One }; - EmissiveColor = new[] { Vector4.One }; + DiffuseColor = [Vector4.One]; + EmissiveColor = [Vector4.One]; } else { @@ -102,7 +102,7 @@ public class Material : IDisposable !original.Name.Equals("T_BlackMask") && options.TryGetTexture(original, false, out var transformed)) { HasAo = true; - Ao = new AoParams { Texture = transformed, AmbientOcclusion = 0.7f }; + Ao = new AoParams { Texture = transformed }; if (Parameters.TryGetLinearColor(out var l, "Skin Boost Color And Exponent")) { Ao.HasColorBoost = true; @@ -242,7 +242,6 @@ public class Material : IDisposable shader.SetUniform("uParameters.Ao.HasColorBoost", Ao.HasColorBoost); shader.SetUniform("uParameters.Ao.ColorBoost.Color", Ao.ColorBoost.Color); shader.SetUniform("uParameters.Ao.ColorBoost.Exponent", Ao.ColorBoost.Exponent); - shader.SetUniform("uParameters.Ao.AmbientOcclusion", Ao.AmbientOcclusion); shader.SetUniform("uParameters.HasAo", HasAo); shader.SetUniform("uParameters.EmissiveRegion", EmissiveRegion); @@ -269,18 +268,13 @@ public class Material : IDisposable ImGui.DragFloat("", ref EmissiveMult, _step, _zero, _infinite, _mult, _clamp); ImGui.PopID(); - if (HasAo) + if (HasAo && Ao.HasColorBoost) { - SnimGui.Layout("Ambient Occlusion");ImGui.PushID(id++); - ImGui.DragFloat("", ref Ao.AmbientOcclusion, _step, _zero, 1.0f, _mult, _clamp);ImGui.PopID(); - if (Ao.HasColorBoost) - { - SnimGui.Layout("Color Boost");ImGui.PushID(id++); - ImGui.ColorEdit3("", ref Ao.ColorBoost.Color);ImGui.PopID(); - SnimGui.Layout("Color Boost Exponent");ImGui.PushID(id++); - ImGui.DragFloat("", ref Ao.ColorBoost.Exponent, _step, _zero, _infinite, _mult, _clamp); - ImGui.PopID(); - } + SnimGui.Layout("Color Boost");ImGui.PushID(id++); + ImGui.ColorEdit3("", ref Ao.ColorBoost.Color);ImGui.PopID(); + SnimGui.Layout("Color Boost Exponent");ImGui.PushID(id++); + ImGui.DragFloat("", ref Ao.ColorBoost.Exponent, _step, _zero, _infinite, _mult, _clamp); + ImGui.PopID(); } ImGui.EndTable(); } @@ -401,7 +395,6 @@ public class Material : IDisposable public struct AoParams { public Texture Texture; - public float AmbientOcclusion; public Boost ColorBoost; public bool HasColorBoost; diff --git a/FModel/Views/Snooper/Shading/Shader.cs b/FModel/Views/Snooper/Shading/Shader.cs index 538f05af..537800df 100644 --- a/FModel/Views/Snooper/Shading/Shader.cs +++ b/FModel/Views/Snooper/Shading/Shader.cs @@ -10,6 +10,8 @@ namespace FModel.Views.Snooper.Shading; public class Shader : IDisposable { private readonly int _handle; + private readonly int _vHandle; + private readonly int _fHandle; private readonly Dictionary _uniformsLocation = new (); public Shader() : this("default") {} @@ -17,21 +19,29 @@ public class Shader : IDisposable public Shader(string name1, string name2 = null) { _handle = GL.CreateProgram(); + _vHandle = LoadShader(ShaderType.VertexShader, $"{name1}.vert"); + _fHandle = LoadShader(ShaderType.FragmentShader, $"{name2 ?? name1}.frag"); + Attach(); + } - var v = LoadShader(ShaderType.VertexShader, $"{name1}.vert"); - var f = LoadShader(ShaderType.FragmentShader, $"{name2 ?? name1}.frag"); - GL.AttachShader(_handle, v); - GL.AttachShader(_handle, f); + private void Attach() + { + GL.AttachShader(_handle, _vHandle); + GL.AttachShader(_handle, _fHandle); GL.LinkProgram(_handle); GL.GetProgram(_handle, GetProgramParameterName.LinkStatus, out var status); if (status == 0) { throw new Exception($"Program failed to link with error: {GL.GetProgramInfoLog(_handle)}"); } - GL.DetachShader(_handle, v); - GL.DetachShader(_handle, f); - GL.DeleteShader(v); - GL.DeleteShader(f); + } + + private void Detach() + { + GL.DetachShader(_handle, _vHandle); + GL.DetachShader(_handle, _fHandle); + GL.DeleteShader(_vHandle); + GL.DeleteShader(_fHandle); } private int LoadShader(ShaderType type, string file) @@ -130,6 +140,7 @@ public class Shader : IDisposable public void Dispose() { + Detach(); GL.DeleteProgram(_handle); } } diff --git a/FModel/Views/Snooper/Shading/Texture.cs b/FModel/Views/Snooper/Shading/Texture.cs index 692ed13a..1ec41a28 100644 --- a/FModel/Views/Snooper/Shading/Texture.cs +++ b/FModel/Views/Snooper/Shading/Texture.cs @@ -29,17 +29,17 @@ public class Texture : IDisposable public int Height; private const int DisabledChannel = (int)BlendingFactor.Zero; - private readonly bool[] _values = { true, true, true, true }; - private readonly string[] _labels = { "R", "G", "B", "A" }; + private readonly bool[] _values = [true, true, true, true]; + private readonly string[] _labels = ["R", "G", "B", "A"]; public int[] SwizzleMask = - { + [ (int) PixelFormat.Red, (int) PixelFormat.Green, (int) PixelFormat.Blue, (int) PixelFormat.Alpha - }; + ]; - public Texture(TextureType type) + private Texture(TextureType type) { _handle = GL.GenTexture(); _type = type; diff --git a/FModel/Views/Snooper/Shading/TextureHelper.cs b/FModel/Views/Snooper/Shading/TextureHelper.cs index 60922845..1cedefb1 100644 --- a/FModel/Views/Snooper/Shading/TextureHelper.cs +++ b/FModel/Views/Snooper/Shading/TextureHelper.cs @@ -21,13 +21,13 @@ public static class TextureHelper case "PHOENIX": case "ATOMICHEART": { - texture.SwizzleMask = new [] - { + texture.SwizzleMask = + [ (int) PixelFormat.Red, (int) PixelFormat.Blue, (int) PixelFormat.Green, (int) PixelFormat.Alpha - }; + ]; break; } // R: Metallic @@ -37,13 +37,13 @@ public static class TextureHelper case "DIVINEKNOCKOUT": case "MOONMAN": { - texture.SwizzleMask = new [] - { + texture.SwizzleMask = + [ (int) PixelFormat.Blue, (int) PixelFormat.Red, (int) PixelFormat.Green, (int) PixelFormat.Alpha - }; + ]; break; } // R: Roughness @@ -52,13 +52,13 @@ public static class TextureHelper case "CCFF7R": case "PJ033": { - texture.SwizzleMask = new [] - { + texture.SwizzleMask = + [ (int) PixelFormat.Blue, (int) PixelFormat.Green, (int) PixelFormat.Red, (int) PixelFormat.Alpha - }; + ]; break; } }