Skip to content

Commit

Permalink
Shader updates
Browse files Browse the repository at this point in the history
  • Loading branch information
PassiveModding committed Jul 14, 2024
1 parent 608d6c5 commit 61ff3c3
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 98 deletions.
105 changes: 56 additions & 49 deletions Meddle/Meddle.Utils/Materials/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,54 +69,56 @@ public static MaterialBuilder BuildCharacter(Material material, string name)
var outDiffuse = new SKTexture(normal.Width, normal.Height);
var outSpecular = new SKTexture(normal.Width, normal.Height);
var outOcclusion = new SKTexture(normal.Width, normal.Height);
for (var x = 0; x < normal.Width; x++)
for (var y = 0; y < normal.Height; y++)
//for (var x = 0; x < normal.Width; x++)
Parallel.For(0, normal.Width, x =>
{
var normalPixel = normal[x, y].ToVector4();
var maskPixel = maskTexture[x, y].ToVector4();
var indexPixel = indexTexture[x, y];

var blended = material.ColorTable.GetBlendedPair(indexPixel.Red, indexPixel.Green);
if (texMode == TextureMode.Compatibility)
{
var diffusePixel = diffuseTexture![x, y].ToVector4();
diffusePixel *= new Vector4(blended.Diffuse, normalPixel.Z);
outDiffuse[x, y] = (diffusePixel with {W = normalPixel.Z}).ToSkColor();
}
else if (texMode == TextureMode.Default)
{
var diffusePixel = new Vector4(blended.Diffuse, normalPixel.Z);
outDiffuse[x, y] = diffusePixel.ToSkColor();
}
else
for (var y = 0; y < normal.Height; y++)
{
throw new NotImplementedException();
}
var normalPixel = normal[x, y].ToVector4();
var maskPixel = maskTexture[x, y].ToVector4();
var indexPixel = indexTexture[x, y];

var specular = new Vector4(1.0f);
var roughness = 0.0f;
var occlusion = 1.0f;

if (specMode == SpecularMode.Mask)
{
var diffuseMask = maskPixel.X;
specular *= maskPixel.Y;
roughness = maskPixel.Z;
outOcclusion[x, y] = new Vector4(diffuseMask).ToSkColor();
outSpecular[x, y] = specular.ToSkColor();
}
else if (specMode == SpecularMode.Default)
{
var specPixel = specTexture![x, y].ToVector4();
outSpecular[x, y] = specPixel.ToSkColor();
}
else
{
outSpecular[x, y] = new Vector4(0.1f, 0.1f, 0.1f, 1.0f).ToSkColor();
var blended = material.ColorTable.GetBlendedPair(indexPixel.Red, indexPixel.Green);
if (texMode == TextureMode.Compatibility)
{
var diffusePixel = diffuseTexture![x, y].ToVector4();
diffusePixel *= new Vector4(blended.Diffuse, normalPixel.Z);
outDiffuse[x, y] = (diffusePixel with {W = normalPixel.Z}).ToSkColor();
}
else if (texMode == TextureMode.Default)
{
var diffusePixel = new Vector4(blended.Diffuse, normalPixel.Z);
outDiffuse[x, y] = diffusePixel.ToSkColor();
}
else
{
throw new NotImplementedException();
}

var spec = blended.Specular;
var specStrength = blended.SpecularStrength;

if (specMode == SpecularMode.Mask)
{
var diffuseMask = maskPixel.X;
var maspSpec = maskPixel.Y;
var maskRoughness = maskPixel.Z;
outOcclusion[x, y] = new Vector4(diffuseMask).ToSkColor();
outSpecular[x, y] = new Vector4(spec, specStrength).ToSkColor();
}
else if (specMode == SpecularMode.Default)
{
var specPixel = specTexture![x, y].ToVector4();
outSpecular[x, y] = specPixel.ToSkColor();
}
else
{
outSpecular[x, y] = new Vector4(spec, specStrength).ToSkColor();
}

outNormal[x, y] = (normalPixel with {W = 1.0f}).ToSkColor();
}

outNormal[x, y] = (normalPixel with {W = 1.0f}).ToSkColor();
}
});

var output = new MaterialBuilder(name);
output.WithBaseColor(BuildImage(outDiffuse, name, "diffuse"));
Expand All @@ -125,12 +127,14 @@ public static MaterialBuilder BuildCharacter(Material material, string name)
if (specMode == SpecularMode.Mask)
{
output.WithMetallicRoughnessShader();
output.WithMetallicRoughness(BuildImage(outSpecular, name, "specular"), 1);
output.WithMetallicRoughness(BuildImage(outSpecular, name, "specular"));
output.WithOcclusion(BuildImage(outOcclusion, name, "occlusion"));
}
else
{
output.WithSpecularFactor(BuildImage(outSpecular, name, "specular"), 1);
var spec = BuildImage(outSpecular, name, "specular");
output.WithSpecularFactor(spec, 1);
output.WithSpecularColor(spec);
}

var alphaThreshold = material.GetConstantOrDefault(MaterialConstant.g_AlphaThreshold, 0.0f);
Expand Down Expand Up @@ -224,6 +228,7 @@ public static MaterialBuilder BuildCharacterTattoo(

public static MaterialBuilder BuildCharacterLegacy(Material material, string name)
{
return BuildCharacter(material, name);
TextureMode texMode;

Check warning on line 232 in Meddle/Meddle.Utils/Materials/Character.cs

View workflow job for this annotation

GitHub Actions / Build (7.0.x, latest)

Unreachable code detected

Check warning on line 232 in Meddle/Meddle.Utils/Materials/Character.cs

View workflow job for this annotation

GitHub Actions / Build (7.0.x, latest)

Unreachable code detected

Check warning on line 232 in Meddle/Meddle.Utils/Materials/Character.cs

View workflow job for this annotation

GitHub Actions / Build (7.0.x, latest)

Unreachable code detected
if (material.ShaderKeys.Any(x => x.Category == (uint)ShaderCategory.CategoryTextureType))
{
Expand Down Expand Up @@ -294,11 +299,11 @@ public static MaterialBuilder BuildCharacterLegacy(Material material, string nam
}
else if (specMode == SpecularMode.Mask)
{
outSpecular[x, y] = new Vector4(0.1f, 0.1f, 0.1f, 1.0f).ToSkColor();
outSpecular[x, y] = new Vector4(0.1f, 0.1f, 0.1f, 0.1f).ToSkColor();
}
else
{
outSpecular[x, y] = new Vector4(0.1f, 0.1f, 0.1f, 1.0f).ToSkColor();
outSpecular[x, y] = new Vector4(0.1f, 0.1f, 0.1f, 0.1f).ToSkColor();
}

outNormal[x, y] = (normalPixel with {W = 1.0f}).ToSkColor();
Expand All @@ -307,7 +312,9 @@ public static MaterialBuilder BuildCharacterLegacy(Material material, string nam
var output = new MaterialBuilder(name);
output.WithBaseColor(BuildImage(outDiffuse, name, "diffuse"));
output.WithNormal(BuildImage(outNormal, name, "normal"));
output.WithSpecularFactor(BuildImage(outSpecular, name, "specular"), 1);
var spec = BuildImage(outSpecular, name, "specular");
output.WithSpecularFactor(spec, 1);
output.WithSpecularColor(spec);

var alphaThreshold = material.GetConstantOrDefault(MaterialConstant.g_AlphaThreshold, 0.0f);
if (alphaThreshold > 0)
Expand Down
38 changes: 21 additions & 17 deletions Meddle/Meddle.Utils/Materials/Hair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,22 @@ public static MaterialBuilder BuildHair(Material material, string name, Customiz
}

SKTexture normal = material.GetTexture(TextureUsage.g_SamplerNormal).ToTexture();
SKTexture mask = material.GetTexture(TextureUsage.g_SamplerMask).ToTexture();
SKTexture mask = material.GetTexture(TextureUsage.g_SamplerMask).ToTexture((normal.Width, normal.Height)); // spec, roughness, sss thickness, ao

var outDiffuse = new SKTexture(normal.Width, normal.Height);
var outSpecRough = new SKTexture(normal.Width, normal.Height);
var roughMet = new SKTexture(normal.Width, normal.Height); // R = SSS, G = roughness, B = metallic, A = specular strength
var outNormal = new SKTexture(normal.Width, normal.Height);
var occ = new SKTexture(normal.Width, normal.Height);

var refMask = mask.Resize(normal.Width, normal.Height);
var refNormal = normal.Resize(normal.Width, normal.Height);
for (var x = 0; x < outDiffuse.Width; x++)
for (var y = 0; y < outDiffuse.Height; y++)
{
var maskPixel = refMask[x, y].ToVector4();
var normalPixel = refNormal[x, y].ToVector4();
var normalPixel = normal[x, y].ToVector4();
var maskPixel = mask[x, y].ToVector4();

roughMet[x, y] = new Vector4(maskPixel.Z, maskPixel.Y, 0, maskPixel.X).ToSkColor();
occ[x, y] = new Vector4(0, 0, 0, maskPixel.W).ToSkColor();


// Base color
var hairColor = parameters.MainColor;
Expand Down Expand Up @@ -58,23 +61,24 @@ public static MaterialBuilder BuildHair(Material material, string name, Customiz
}

outDiffuse[x, y] = new Vector4(hairColor, normalPixel.W).ToSkColor();

// Specular
outSpecRough[x, y] = new Vector4(maskPixel.X, maskPixel.Y, maskPixel.Z, maskPixel.W).ToSkColor();

// Normal
outNormal[x, y] = normalPixel.ToSkColor();
outNormal[x, y] = (normalPixel with {Z = 1.0f, W = 1.0f}).ToSkColor();
}

var output = new MaterialBuilder(name);
var doubleSided = (material.ShaderFlags & 0x1) == 0;
output.WithDoubleSide(doubleSided);
//var doubleSided = (material.ShaderFlags & 0x1) == 0;
//output.WithDoubleSide(doubleSided);


var normalScale = material.GetConstantOrDefault(MaterialConstant.g_NormalScale, 1.0f);
// using this kinda just makes everything look jank
//var normalScale = material.GetConstantOrDefault(MaterialConstant.g_NormalScale, 1.0f);

output.WithBaseColor(BuildImage(outDiffuse, name, "diffuse"))
.WithNormal(BuildImage(outNormal, name, "normal"), normalScale);
output.WithBaseColor(BuildImage(outDiffuse, name, "diffuse"));
output.WithNormal(BuildImage(outNormal, name, "normal"));
var roughMetImg = BuildImage(roughMet, name, "roughness_metallic_specular");
output.WithSpecularFactor(roughMetImg, 1.0f);
output.WithMetallicRoughness(roughMetImg, 0.0f, 1.0f);
output.WithMetallicRoughnessShader();
output.WithOcclusion(BuildImage(occ, name, "occlusion"));

var alphaThreshold = material.GetConstantOrDefault(MaterialConstant.g_AlphaThreshold, 0.0f);
if (alphaThreshold > 0)
Expand Down
19 changes: 17 additions & 2 deletions Meddle/Meddle.Utils/Materials/MaterialUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,23 @@ public static MaterialBuilder BuildSharedBase(Material material, string name)
}

public static Vector4 ToVector4(this SKColor color) => new Vector4(color.Red / 255f, color.Green / 255f, color.Blue / 255f, color.Alpha / 255f);
public static SKColor ToSkColor(this Vector4 color) =>
new((byte)(color.X * 255), (byte)(color.Y * 255), (byte)(color.Z * 255), (byte)(color.W * 255));
//public static SKColor ToSkColor(this Vector4 color) =>
// new((byte)(color.X * 255), (byte)(color.Y * 255), (byte)(color.Z * 255), (byte)(color.W * 255));
public static SKColor ToSkColor(this Vector4 color)
{
var c = color.Clamp(0, 1);
return new SKColor((byte)(c.X * 255), (byte)(c.Y * 255), (byte)(c.Z * 255), (byte)(c.W * 255));
}
public static Vector4 Clamp(this Vector4 v, float min, float max)
{
return new Vector4(
Math.Clamp(v.X, min, max),
Math.Clamp(v.Y, min, max),
Math.Clamp(v.Z, min, max),
Math.Clamp(v.W, min, max)
);
}

public static SKColor ToSkColor(this Vector3 color) =>
new((byte)(color.X * 255), (byte)(color.Y * 255), (byte)(color.Z * 255), byte.MaxValue);

Expand Down
63 changes: 33 additions & 30 deletions Meddle/Meddle.Utils/Materials/Skin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,53 +36,56 @@ public static MaterialBuilder BuildSkin(Material material, string name, Customiz
var diffuseTexture = new SKTexture(diffuse.Width, diffuse.Height);
var normalTexture = new SKTexture(normal.Width, normal.Height);
var metallicRoughness = new SKTexture(normal.Width, normal.Height);
for (int x = 0; x < normal.Width; x++)
for (int y = 0; y < normal.Height; y++)
//for (int x = 0; x < normal.Width; x++)
Parallel.For(0, normal.Width, x =>
{
var normalPixel = normal[x, y].ToVector4();
var maskPixel = mask[x, y].ToVector4();
var diffusePixel = diffuse[x, y].ToVector4();
for (int y = 0; y < normal.Height; y++)
{
var normalPixel = normal[x, y].ToVector4();
var maskPixel = mask[x, y].ToVector4();
var diffusePixel = diffuse[x, y].ToVector4();

var skinInfluence = normalPixel.Z;
var newDiffusePixel = Vector4.Lerp(diffusePixel, skinColor, skinInfluence);

var specular = maskPixel.X;
var roughness = maskPixel.Y;
var subsurface = maskPixel.Z;
var metallic = 0.0f;
var roughnessPixel = new Vector4(subsurface, roughness, metallic, specular);
var skinInfluence = normalPixel.Z;
var diffuseAlpha = diffusePixel.W;
diffusePixel = Vector4.Lerp(diffusePixel, skinColor, skinInfluence);

var secondaryInfluence = normalPixel.W;
if (skinType == SkinType.Default || skinType == SkinType.Face)
{
if (data.LipStick)
var specular = maskPixel.X;
var roughness = maskPixel.Y;
var subsurface = maskPixel.Z;
var metallic = 0.0f;
var roughnessPixel = new Vector4(subsurface, roughness, metallic, specular);

if (skinType == SkinType.Face)
{
newDiffusePixel = Vector4.Lerp(newDiffusePixel, lipColor, secondaryInfluence * lipColor.W);
if (data.LipStick)
{
diffusePixel = Vector4.Lerp(diffusePixel, lipColor, normalPixel.W * lipColor.W);
}
}
}
else if (skinType == SkinType.Hrothgar)
{
if (skinInfluence != 0f)
// only apply hair for hrothgar if skin is not applied
else if (skinType == SkinType.Hrothgar && skinInfluence == 0f)
{
var hair = hairColor;
if (data.Highlights)
{
hair = Vector3.Lerp(hairColor, highlightColor, maskPixel.W);
}

var hCol = new Vector4(hair, 1.0f);
newDiffusePixel = Vector4.Lerp(newDiffusePixel, hCol, secondaryInfluence);
diffusePixel = Vector4.Lerp(diffusePixel, new Vector4(hair, 1.0f), normalPixel.W);
}

diffuseTexture[x, y] = (diffusePixel with {W = diffuseAlpha}).ToSkColor();
normalTexture[x, y] = (normalPixel with {W = 1.0f}).ToSkColor();
metallicRoughness[x, y] = roughnessPixel.ToSkColor();
}

diffuseTexture[x, y] = (newDiffusePixel with { W = diffusePixel.W }).ToSkColor();
normalTexture[x, y] = (normalPixel with { W = 1.0f }).ToSkColor();
metallicRoughness[x, y] = roughnessPixel.ToSkColor();
}
});

var output = new MaterialBuilder(name);
output.WithBaseColor(BuildImage(diffuseTexture, name, "diffuse"));
output.WithNormal(BuildImage(normalTexture, name, "normal"));

// just seems right at 0.75f, at least for au-ra scales?
output.WithNormal(BuildImage(normalTexture, name, "normal"), 0.75f);

var mr = BuildImage(metallicRoughness, name, "sss_roughness_metallic_specular");
output.WithMetallicRoughness(mr);
output.WithSpecularFactor(mr, 1.0f);
Expand Down

0 comments on commit 61ff3c3

Please sign in to comment.