improved generic roughness

This commit is contained in:
4sval 2022-12-31 04:52:58 +01:00
parent 9cf6c32817
commit 9a0e6aa6c6
7 changed files with 58 additions and 90 deletions

@ -1 +1 @@
Subproject commit 80140f6d70b42d904687c2afca1abb8ea1ddb1f2
Subproject commit 59b004c355647a22c0ad7945443d0de509ecdaf1

View File

@ -43,10 +43,9 @@ struct Parameters
bool HasAo;
vec4 EmissiveRegion;
float Specular;
float Roughness;
float RoughnessMin;
float RoughnessMax;
float EmissiveMult;
float UVScale;
};
struct BaseLight
@ -101,11 +100,6 @@ int LayerToIndex()
return clamp(int(fTexLayer), 0, uUvCount - 1);
}
vec2 ScaledTexCoords()
{
return fTexCoords * uParameters.UVScale;
}
vec4 SamplerToVector(sampler2D s, vec2 coords)
{
return texture(s, coords);
@ -113,7 +107,7 @@ vec4 SamplerToVector(sampler2D s, vec2 coords)
vec4 SamplerToVector(sampler2D s)
{
return SamplerToVector(s, ScaledTexCoords());
return SamplerToVector(s, fTexCoords);
}
vec3 ComputeNormals(int layer)
@ -153,7 +147,7 @@ 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 roughness = max(0.0f, specular_masks.b * uParameters.Roughness);
float roughness = mix(uParameters.RoughnessMin, uParameters.RoughnessMax, specular_masks.b);
vec3 l = normalize(uViewPos - fPos);
@ -174,11 +168,11 @@ vec3 CalcLight(int layer, vec3 normals, vec3 position, vec3 color, float attenua
vec3 specBrdfNom = ggxDistribution(roughness, nDotH) * geomSmith(roughness, nDotL) * geomSmith(roughness, nDotV) * f;
float specBrdfDenom = 4.0 * nDotV * nDotL + 0.0001;
vec3 specBrdf = uParameters.Specular * specular_masks.r * specBrdfNom / specBrdfDenom;
vec3 specBrdf = specBrdfNom / specBrdfDenom;
vec3 diffuseBrdf = fLambert;
if (!global) diffuseBrdf = kD * fLambert / PI;
return (diffuseBrdf + specBrdf) * color * nDotL * attenuation;
return (diffuseBrdf + specBrdf) * color * attenuation * nDotL;
}
vec3 CalcBaseLight(int layer, vec3 normals, BaseLight base, float attenuation, bool global)
@ -223,13 +217,11 @@ void main()
}
else if (bVertexColors[3])
{
FragColor = vec4(fNormal, 1);
int layer = LayerToIndex();
vec3 normals = ComputeNormals(layer);
FragColor = vec4(normals, 1);
}
else if (bVertexColors[4])
{
FragColor = vec4(fTangent, 1);
}
else if (bVertexColors[5])
{
FragColor = vec4(fTexCoords, 0, 1);
}
@ -248,10 +240,11 @@ void main()
vec3 color = uParameters.Ao.ColorBoost.Color * uParameters.Ao.ColorBoost.Exponent;
result = mix(result, result * color, m.b);
}
result = mix(result * m.r * uParameters.Ao.AmbientOcclusion, result, m.g);
result = vec3(uParameters.Ao.AmbientOcclusion) * result * m.r;
result += CalcLight(layer, normals, vec3(0.0), vec3(0.25), m.g, false);
}
vec2 coords = ScaledTexCoords();
vec2 coords = fTexCoords;
if (coords.x > uParameters.EmissiveRegion.x &&
coords.y > uParameters.EmissiveRegion.y &&
coords.x < uParameters.EmissiveRegion.z &&

View File

@ -106,7 +106,7 @@ public class Renderer : IDisposable
if (ShowGrid) _grid.Render(viewMatrix, projMatrix, cam.Near, cam.Far);
_shader.Render(viewMatrix, cam.Position, projMatrix);
for (int i = 0; i < 6; i++)
for (int i = 0; i < 5; i++)
_shader.SetUniform($"bVertexColors[{i}]", i == VertexColor);
// render model pass

View File

@ -34,10 +34,9 @@ public class Material : IDisposable
public AoParams Ao;
public bool HasAo;
public float Specular = 1f;
public float Roughness = 0.5f;
public float RoughnessMin = 0f;
public float RoughnessMax = 1f;
public float EmissiveMult = 1f;
public float UVScale = 1f;
public Material()
{
@ -106,24 +105,22 @@ public class Material : IDisposable
}
}
// scalars
if (Parameters.TryGetScalar(out var specular, "Specular", "Specular Intensity", "Spec"))
Specular = specular;
if (Parameters.TryGetScalar(out var roughnessMin, "RoughnessMin", "SpecRoughnessMin") &&
Parameters.TryGetScalar(out var roughnessMax, "RoughnessMax", "SpecRoughnessMax"))
Roughness = (roughnessMin + roughnessMax) / 2f;
if (Parameters.TryGetScalar(out var roughnessMin, "RoughnessMin", "SpecRoughnessMin"))
RoughnessMin = roughnessMin;
if (Parameters.TryGetScalar(out var roughnessMax, "RoughnessMax", "SpecRoughnessMax"))
RoughnessMax = roughnessMax;
if (Parameters.TryGetScalar(out var roughness, "Rough", "Roughness", "Ro Multiplier", "RO_mul", "Roughness_Mult"))
Roughness = roughness;
{
var d = roughness / 2;
RoughnessMin = roughness - d;
RoughnessMax = roughness + d;
}
if (Parameters.TryGetScalar(out var emissiveMultScalar, "emissive mult", "Emissive_Mult", "EmissiveIntensity", "EmissionIntensity"))
EmissiveMult = emissiveMultScalar;
else if (Parameters.TryGetLinearColor(out var emissiveMultColor, "Emissive Multiplier", "EmissiveMultiplier"))
EmissiveMult = emissiveMultColor.R;
if (Parameters.TryGetScalar(out var uvScale, "UV Scale"))
UVScale = uvScale;
if (Parameters.TryGetLinearColor(out var EmissiveUVs,
"EmissiveUVs_RG_UpperLeftCorner_BA_LowerRightCorner",
"Emissive Texture UVs RG_TopLeft BA_BottomRight",
@ -228,10 +225,9 @@ public class Material : IDisposable
shader.SetUniform("uParameters.HasAo", HasAo);
shader.SetUniform("uParameters.EmissiveRegion", EmissiveRegion);
shader.SetUniform("uParameters.Specular", Specular);
shader.SetUniform("uParameters.Roughness", Roughness);
shader.SetUniform("uParameters.RoughnessMin", RoughnessMin);
shader.SetUniform("uParameters.RoughnessMax", RoughnessMax);
shader.SetUniform("uParameters.EmissiveMult", EmissiveMult);
shader.SetUniform("uParameters.UVScale", UVScale);
}
private const string _mult = "x %.2f";
@ -244,14 +240,12 @@ public class Material : IDisposable
if (ImGui.BeginTable("parameters", 2))
{
var id = 1;
SnimGui.Layout("Specular");ImGui.PushID(id++);
ImGui.DragFloat("", ref Specular, _step, _zero, 1.0f, _mult, _clamp);
ImGui.PopID();SnimGui.Layout("Roughness");ImGui.PushID(id++);
ImGui.DragFloat("", ref Roughness, _step, _zero, 1.0f, _mult, _clamp);
SnimGui.Layout("Roughness Min");ImGui.PushID(id++);
ImGui.DragFloat("", ref RoughnessMin, _step, _zero, 1.0f, _mult, _clamp);
ImGui.PopID();SnimGui.Layout("Roughness Max");ImGui.PushID(id++);
ImGui.DragFloat("", ref RoughnessMax, _step, _zero, 1.0f, _mult, _clamp);
ImGui.PopID();SnimGui.Layout("Emissive Multiplier");ImGui.PushID(id++);
ImGui.DragFloat("", ref EmissiveMult, _step, _zero, _infinite, _mult, _clamp);
ImGui.PopID();SnimGui.Layout("UV Scale");ImGui.PushID(id++);
ImGui.DragFloat("", ref UVScale, _step, _zero, _infinite, _mult, _clamp);
ImGui.PopID();
if (HasAo)

View File

@ -119,11 +119,13 @@ public class Texture : IDisposable
ProcessPixels(textures[t], TextureTarget.TextureCubeMapPositiveX + t);
}
GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
GL.TexParameter(_target, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(_target, TextureParameterName.TextureMagFilter, (int) TextureMinFilter.Linear);
GL.TexParameter(_target, TextureParameterName.TextureWrapR, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(_target, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(_target, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap);
}
public Texture(string texture) : this(TextureType.Normal)

View File

@ -7,9 +7,9 @@ public static class TextureHelper
private static readonly string _game = Services.ApplicationService.ApplicationView.CUE4Parse.Provider.GameName;
/// <summary>
/// Red : Specular (if possible)
/// Blue : Roughness
/// Red : Specular (not used anymore)
/// Green : Metallic
/// Blue : Roughness
/// </summary>
public static void FixChannels(UTexture2D o, FTexture2DMipMap mip, ref byte[] data)
{
@ -17,8 +17,6 @@ public static class TextureHelper
switch (_game)
{
case "hk_project":
case "gameface":
case "divineknockout":
{
unsafe
{
@ -34,6 +32,27 @@ public static class TextureHelper
}
break;
}
// R: Metallic
// G: Roughness
// B: Whatever (AO / S / E / ...)
case "shootergame":
case "divineknockout":
{
unsafe
{
var offset = 0;
fixed (byte* d = data)
{
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
(d[offset], d[offset + 1]) = (d[offset + 1], d[offset]); // GRB
(d[offset], d[offset + 2]) = (d[offset + 2], d[offset]); // RBG
offset += 4;
}
}
}
break;
}
// R: Roughness
// G: Metallic
// B: Whatever (AO / S / E / ...)
@ -54,46 +73,6 @@ public static class TextureHelper
}
break;
}
case "shootergame":
{
var packedPBRType = o.Name[(o.Name.LastIndexOf('_') + 1)..];
switch (packedPBRType)
{
case "MRAE": // R: Metallic, G: Roughness, B: AO (0-127) & Emissive (128-255) (Character PBR)
unsafe
{
var offset = 0;
fixed (byte* d = data)
{
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
(d[offset], d[offset + 1]) = (d[offset + 1], d[offset]); // RMAE
// (d[offset], d[offset + 2]) = (d[offset + 2], d[offset]); // AEMR
offset += 4;
}
}
}
break;
case "MRAS": // R: Metallic, G: Roughness, B: AO, A: Specular (Legacy PBR)
case "MRA": // R: Metallic, G: Roughness, B: AO (Environment PBR)
case "MRS": // R: Metallic, G: Roughness, B: Specular (Weapon PBR)
unsafe
{
var offset = 0;
fixed (byte* d = data)
{
for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
{
(d[offset], d[offset + 2]) = (d[offset + 2], d[offset]); // SRM
(d[offset + 1], d[offset + 2]) = (d[offset + 2], d[offset + 1]); // SMR
offset += 4;
}
}
}
break;
}
break;
}
}
}
}

View File

@ -139,7 +139,7 @@ public class SnimGui
ImGui.Checkbox("", ref s.Renderer.ShowLights);
ImGui.PopID();Layout("Vertex Colors");ImGui.PushID(4);
ImGui.Combo("vertex_colors", ref s.Renderer.VertexColor,
"Default\0Diffuse Only\0Colors\0Normals\0Tangent\0Texture Coordinates\0");
"Default\0Diffuse Only\0Colors\0Normals\0Texture Coordinates\0");
ImGui.PopID();
ImGui.EndTable();