Skip to content

Commit

Permalink
Material Parameter Rework Init
Browse files Browse the repository at this point in the history
  • Loading branch information
PassiveModding committed Apr 6, 2024
1 parent 88d942e commit 53928e3
Show file tree
Hide file tree
Showing 13 changed files with 479 additions and 122 deletions.
1 change: 0 additions & 1 deletion Meddle/Meddle.Plugin/Models/CharacterTree.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Runtime.InteropServices;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Shader;
Expand Down
139 changes: 100 additions & 39 deletions Meddle/Meddle.Plugin/Models/ColorTable.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,56 @@
using System.Collections;
using System.Numerics;
using System.Runtime.InteropServices;
using Lumina.Data.Files;
using Meddle.Plugin.Utility;
using CSTexture = FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Texture;

namespace Meddle.Plugin.Models;

// https://github.com/Ottermandias/Penumbra.GameData/blob/45679aa32cc37b59f5eeb7cf6bf5a3ea36c626e0/Files/MtrlFile.ColorTable.cs
public unsafe struct ColorTable : IEnumerable<ColorTable.Row>
{
public ColorTable(Half[] data)
public ColorTable(CSTexture* colorTable)
{
fixed (byte* ptr = rowData)
{
for (var i = 0; i < NumRows; ++i)
{
var row = new Row();
var span = row.AsHalves();
for (var j = 0; j < 16; ++j)
span[j] = data[i * 16 + j];
((Row*)ptr)[i] = row;
}
}
var data = DXHelper.ExportTextureResource(colorTable);
if ((TexFile.TextureFormat)colorTable->TextureFormat != TexFile.TextureFormat.R16G16B16A16F)
throw new ArgumentException($"Color table is not R16G16B16A16F ({(TexFile.TextureFormat)colorTable->TextureFormat})");
if (colorTable->Width != 4 || colorTable->Height != 16)
throw new ArgumentException($"Color table is not 4x16 ({colorTable->Width}x{colorTable->Height})");

var stridedData = TextureHelper.AdjustStride(data.Stride, (int)colorTable->Width * 8, (int)colorTable->Height, data.Data);

var table = MemoryMarshal.Cast<byte, ushort>(stridedData.AsSpan()).ToArray();
this = FromData(table);
}

public ColorTable(ushort[] data)
{
this = FromData(data);
}

public ColorTable()
{
for (var i = 0; i < NumRows; ++i)
this[i] = Row.Default;
}

private static ColorTable FromData(ushort[] data)
{
if (data.Length != NumRows * 16)
throw new ArgumentException($"Color table is not 16 rows of 16 shorts ({data.Length})");

var table = new ColorTable();
for (var i = 0; i < NumRows; ++i)
{
var row = new ushort[16];
for (var j = 0; j < 16; ++j)
row[j] = data[i * 16 + j];
table[i] = new Row(row);
}

return table;
}

public const int NumRows = 16;
private fixed byte rowData[NumRows * Row.Size];
Expand All @@ -51,20 +76,56 @@ IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public (Row prev, Row next, TableRow row) Lookup(float index)
{
var row = TableRow.GetTableRowIndices(index);
return (this[row.Previous], this[row.Next], row);
}

public struct TableRow
{
public int Stepped;
public int Previous;
public int Next;
public float Weight;

public static TableRow GetTableRowIndices(float index)
{
var vBase = index * 15f;
var vOffFilter = (index * 7.5f) % 1.0f;
var smoothed = float.Lerp(vBase, float.Floor(vBase + 0.5f), vOffFilter * 2);
var stepped = float.Floor(smoothed + 0.5f);

public unsafe struct Row
return new TableRow
{
Stepped = (int)stepped,
Previous = (int)MathF.Floor(smoothed),
Next = (int)MathF.Ceiling(smoothed),
Weight = smoothed % 1,
};
}
}

public struct Row
{
public const int Size = 32;
private fixed ushort data[16];

public Row(ushort[] data)
{
for (var i = 0; i < 16; ++i)
this.data[i] = data[i];
}

public static readonly Row Default = new()
{
Diffuse = Vector3.One,
Specular = Vector3.One,
SpecularStrength = 1.0f,
FresnelValue0 = Vector3.One,
SpecularMask = 1.0f,
Emissive = Vector3.Zero,
GlossStrength = 20.0f,
TileSet = 0,
Shininess = 20.0f,
TileW = 0,
MaterialRepeat = new Vector2(16.0f),
MaterialSkew = Vector2.Zero,
};
Expand All @@ -79,8 +140,14 @@ public Vector3 Diffuse
data[2] = FromFloat(value.Z);
}
}

public Vector3 Specular

public float SpecularMask
{
readonly get => ToFloat(3);
set => data[3] = FromFloat(value);
}

public Vector3 FresnelValue0
{
readonly get => new(ToFloat(4), ToFloat(5), ToFloat(6));
set
Expand All @@ -90,6 +157,12 @@ public Vector3 Specular
data[6] = FromFloat(value.Z);
}
}

public float Shininess
{
readonly get => ToFloat(7);
set => data[7] = FromFloat(value);
}

public Vector3 Emissive
{
Expand All @@ -101,7 +174,13 @@ public Vector3 Emissive
data[10] = FromFloat(value.Z);
}
}


public ushort TileW
{
readonly get => (ushort)(ToFloat(11) * 64f);
set => data[11] = FromFloat((value + 0.5f) / 64f);
}

public Vector2 MaterialRepeat
{
readonly get => new(ToFloat(12), ToFloat(15));
Expand All @@ -111,7 +190,7 @@ public Vector2 MaterialRepeat
data[15] = FromFloat(value.Y);
}
}

public Vector2 MaterialSkew
{
readonly get => new(ToFloat(13), ToFloat(14));
Expand All @@ -122,24 +201,6 @@ public Vector2 MaterialSkew
}
}

public float SpecularStrength
{
readonly get => ToFloat(3);
set => data[3] = FromFloat(value);
}

public float GlossStrength
{
readonly get => ToFloat(7);
set => data[7] = FromFloat(value);
}

public ushort TileSet
{
readonly get => (ushort)(ToFloat(11) * 64f);
set => data[11] = FromFloat((value + 0.5f) / 64f);
}

public readonly Span<Half> AsHalves()
{
fixed (ushort* ptr = data)
Expand Down
26 changes: 23 additions & 3 deletions Meddle/Meddle.Plugin/Models/CustomizeParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public class SkinShaderParameters

return new SkinShaderParameters()
{
ApplyLipColor = parameters.ApplyLipColor,
IsHrothgar = parameters.IsHrothgar,
SkinColor = parameters.SkinColor,
MainColor = parameters.MainColor,
Expand Down Expand Up @@ -58,6 +57,7 @@ public class CustomizeParameters
/// W : Muscle tone.
/// </summary>
public Vector4 SkinColor;

/// <summary>
/// XYZ : Skin specular color
/// </summary>
Expand All @@ -68,16 +68,17 @@ public class CustomizeParameters
/// W : Lip opacity.
/// </summary>
public Vector4 LipColor;
public bool ApplyLipColor;

/// <summary>
/// XYZ : Hair primary color
/// </summary>
public Vector3 MainColor;

/// <summary>
/// XYZ : Hair specular color
/// </summary>
public Vector3 HairFresnelValue0;

/// <summary>
/// XYZ : Hair highlight color
/// </summary>
Expand All @@ -88,6 +89,7 @@ public class CustomizeParameters
/// W : Face paint (UV2) U multiplier.
/// </summary>
public Vector4 LeftColor;

/// <summary>
/// XYZ : Right eye color
/// W : Face paint (UV2) U offset.
Expand All @@ -111,7 +113,25 @@ public CustomizeParameters(CustomizeParameter customizeParameter, bool isHrothga
RightColor = FromSquaredRgb(customizeParameter.RightColor);
OptionColor = FromSquaredRgb(customizeParameter.OptionColor);
IsHrothgar = isHrothgar;
ApplyLipColor = customizeParameter.LipColor.W > 0;
}

public CustomizeParameters(){}

public CustomizeParameters Default()
{
return new CustomizeParameters()
{
SkinColor = new Vector4(1, 0.8745098f, 0.8627451f, 1),
SkinFresnelValue0 = new Vector4(0.25f, 0.25f, 0.25f, 32),
LipColor = new Vector4(0.47058824f, 0.27058825f, 0.40784314f, 0.6f),
MainColor = new Vector3(0.89411765f, 0.89411765f, 0.89411765f),
HairFresnelValue0 = new Vector3(0.8627451f, 0.8627451f, 0.8627451f),
MeshColor = new Vector3(0.8666667f, 0.6745098f, 0.64705884f),
LeftColor = new Vector4(0.80784315f, 0.49803922f, 0.5176471f, -1),
RightColor = new Vector4(0.80784315f, 0.49803922f, 0.5176471f, 1),
OptionColor = new Vector3(0.7764706f, 0.7764706f, 0.7764706f),
IsHrothgar = false
};
}

private static Vector4 FromSquaredRgb(Vector4 input)
Expand Down
Loading

0 comments on commit 53928e3

Please sign in to comment.