improved shader

This commit is contained in:
Asval 2024-05-18 05:48:57 +02:00
parent c1c8adf122
commit 0bef5967c4
9 changed files with 78 additions and 58 deletions

@ -1 +1 @@
Subproject commit ec0a82887540dc982c5c755020323b5a341dbde1
Subproject commit 3fe4665cb0d824fd54d92c980bb03488ccb234b1

View File

@ -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))

View File

@ -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++)

View File

@ -77,6 +77,7 @@ void main()
finalTangent += inverseBoneMatrix * bindTangent * weight;
}
}
finalPos = normalize(finalPos);
}
else
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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<string, int> _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);
}
}

View File

@ -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;

View File

@ -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;
}
}