Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KHR_materials_sheen support #780

Merged
merged 7 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Editor/Scripts/ShaderGraph/InternalShaderGraph/PBRGraphGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,10 +489,14 @@ private void DrawProperties(Material targetMaterial, MaterialProperty[] properti
propertyList.RemoveAll(x => x.name.EndsWith("_ST", StringComparison.Ordinal));
}
#endif
if (!targetMaterial.IsKeywordEnabled("_VOLUME_TRANSMISSION_ON"))
if (!targetMaterial.IsKeywordEnabled("_VOLUME_TRANSMISSION_ON") && !targetMaterial.IsKeywordEnabled("_VOLUME_TRANSMISSION_ANDDISPERSION"))
{
propertyList.RemoveAll(x => x.name.StartsWith("transmission", StringComparison.Ordinal));
}
if (!targetMaterial.IsKeywordEnabled("_VOLUME_TRANSMISSION_ANDDISPERSION"))
{
propertyList.RemoveAll(x => x.name.StartsWith("dispersion", StringComparison.Ordinal));
}
if (!targetMaterial.HasProperty("_VOLUME_ON") || !(targetMaterial.GetFloat("_VOLUME_ON") > 0.5f))
{
propertyList.RemoveAll(x => x.name.StartsWith("thickness", StringComparison.Ordinal) || x.name.StartsWith("attenuation", StringComparison.Ordinal));
Expand All @@ -509,6 +513,11 @@ private void DrawProperties(Material targetMaterial, MaterialProperty[] properti
{
propertyList.RemoveAll(x => x.name.StartsWith("clearcoat", StringComparison.Ordinal));
}
if (!targetMaterial.IsKeywordEnabled("_SHEEN_ON"))
{
propertyList.RemoveAll(x => x.name.StartsWith("sheen", StringComparison.Ordinal));
}

if (HasPropertyButNoTex(targetMaterial, "occlusionTexture"))
{
propertyList.RemoveAll(x => x.name == "occlusionStrength" || (x.name.StartsWith("occlusionTexture", StringComparison.Ordinal) && x.name != "occlusionTexture"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using GLTF.Extensions;
using Newtonsoft.Json.Linq;
using Color = GLTF.Math.Color;

namespace GLTF.Schema
{
// https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_sheen/README.md
[Serializable]
public class KHR_materials_sheen : IExtension
{
public Color sheenColorFactor = COLOR_DEFAULT;
public float sheenRoughnessFactor = 0f;
public TextureInfo sheenColorTexture;
public TextureInfo sheenRoughnessTexture;

public static readonly Color COLOR_DEFAULT = Color.Black;

public JProperty Serialize()
{
var jo = new JObject();
JProperty jProperty = new JProperty(KHR_materials_sheen_Factory.EXTENSION_NAME, jo);

if (sheenRoughnessFactor != 0) jo.Add(new JProperty(nameof(sheenRoughnessFactor), sheenRoughnessFactor));
if (sheenColorFactor != COLOR_DEFAULT) jo.Add(new JProperty(nameof(sheenColorFactor), new JArray(sheenColorFactor.R, sheenColorFactor.G, sheenColorFactor.B)));
if (sheenColorTexture != null)
jo.WriteTexture(nameof(sheenColorTexture), sheenColorTexture);

if (sheenRoughnessTexture != null)
jo.WriteTexture(nameof(sheenRoughnessTexture), sheenRoughnessTexture);

return jProperty;
}

public IExtension Clone(GLTFRoot root)
{
return new KHR_materials_sheen()
{
sheenRoughnessFactor = sheenRoughnessFactor, sheenColorTexture = sheenColorTexture,
sheenColorFactor = sheenColorFactor, sheenRoughnessTexture = sheenRoughnessTexture,
};
}
}

public class KHR_materials_sheen_Factory : ExtensionFactory
{
public const string EXTENSION_NAME = "KHR_materials_sheen";

public KHR_materials_sheen_Factory()
{
ExtensionName = EXTENSION_NAME;
}

public override IExtension Deserialize(GLTFRoot root, JProperty extensionToken)
{
if (extensionToken != null)
{
var extension = new KHR_materials_sheen();
extension.sheenRoughnessFactor = extensionToken.Value[nameof(KHR_materials_sheen.sheenRoughnessFactor)]?.Value<float>() ?? 1;
extension.sheenColorFactor = extensionToken.Value[nameof(KHR_materials_sheen.sheenColorFactor)]?.DeserializeAsColor() ?? Color.White;
extension.sheenColorTexture = extensionToken.Value[nameof(KHR_materials_sheen.sheenColorTexture)]?.DeserializeAsTexture(root);
extension.sheenRoughnessTexture = extensionToken.Value[nameof(KHR_materials_sheen.sheenRoughnessTexture)]?.DeserializeAsTexture(root);
return extension;
}

return null;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Runtime/Plugins/GLTFSerialization/Schema/GLTFProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static IReadOnlyList<string> RegisteredExtensions
{ EXT_mesh_gpu_instancing_Factory.EXTENSION_NAME, new EXT_mesh_gpu_instancing_Factory() },
{ KHR_animation_pointerExtensionFactory.EXTENSION_NAME, new KHR_animation_pointerExtensionFactory() },
{ KHR_materials_dispersion_Factory.EXTENSION_NAME, new KHR_materials_dispersion_Factory() },
{ KHR_materials_sheen_Factory.EXTENSION_NAME, new KHR_materials_sheen_Factory()},
};

private static DefaultExtensionFactory _defaultExtensionFactory = new DefaultExtensionFactory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,25 @@ public DefaultMaterialPropertiesRemapper()
};
AddMap(clearcoatRoughnessFactor);

var sheenRoughnessFactor =
new MaterialPointerPropertyMap(MaterialPointerPropertyMap.PropertyTypeOption.Float)
{
PropertyNames = new[] { "sheenRoughness", "_sheenRoughness", "sheenRoughnessFactor", "_sheenRoughnessFactor" },
GltfPropertyName =
$"extensions/{KHR_materials_sheen_Factory.EXTENSION_NAME}/{nameof(KHR_materials_sheen.sheenRoughnessFactor)}",
ExtensionName = KHR_materials_sheen_Factory.EXTENSION_NAME,
};
AddMap(sheenRoughnessFactor);
var sheenColorFactor =
new MaterialPointerPropertyMap(MaterialPointerPropertyMap.PropertyTypeOption.Float)
{
PropertyNames = new[] { "sheenColor", "_sheenColor", "sheenColorFactor", "_sheenColorFactor" },
GltfPropertyName =
$"extensions/{KHR_materials_sheen_Factory.EXTENSION_NAME}/{nameof(KHR_materials_sheen.sheenColorFactor)}",
ExtensionName = KHR_materials_sheen_Factory.EXTENSION_NAME,
};
AddMap(sheenColorFactor);

AddTextureExtTransforms("pbrMetallicRoughness/baseColorTexture", new[] { "_MainTex", "_BaseMap", "_BaseColorTexture", "baseColorTexture" });
AddTextureExtTransforms("emissiveTexture", new[] { "_EmissionMap", "_EmissiveTexture", "emissiveTexture" } );
AddTextureExtTransforms("normalTexture", new[] { "_BumpMap", "_NormalTexture", "normalTexture" });
Expand All @@ -518,6 +537,8 @@ public DefaultMaterialPropertiesRemapper()
AddTextureExtTransforms("extensions/"+nameof(KHR_materials_specular)+"/"+nameof(KHR_materials_specular.specularTexture), new[] { "specularTexture", "_specularTexture"}, nameof(KHR_materials_specular));
AddTextureExtTransforms("extensions/"+nameof(KHR_materials_specular)+"/"+nameof(KHR_materials_specular.specularColorTexture), new[] { "specularColorTexture", "_specularColorTexture"}, nameof(KHR_materials_specular));

AddTextureExtTransforms("extensions/"+nameof(KHR_materials_sheen)+"/"+nameof(KHR_materials_sheen.sheenColorTexture), new[] {"sheenColorTexture", "_sheenColorTexture"}, nameof(KHR_materials_sheen));
AddTextureExtTransforms("extensions/"+nameof(KHR_materials_sheen)+"/"+nameof(KHR_materials_sheen.sheenRoughnessTexture), new[] {"sheenRoughnessTexture", "_sheenRoughnessTexture"}, nameof(KHR_materials_sheen));

// TODO KHR_materials_sheen
// case "_SheenColorFactor":
Expand Down
34 changes: 33 additions & 1 deletion Runtime/Scripts/Plugins/MaterialExtensionsExport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public class MaterialExtensionsExport: GLTFExportPlugin
public bool KHR_materials_specular = true;
public bool KHR_materials_clearcoat = true;
public bool KHR_materials_emissive_strength = true;

public bool KHR_materials_sheen = true;

public override GLTFExportPluginContext CreateInstance(ExportContext context)
{
return new MaterialExtensionsExportContext(this);
Expand All @@ -30,6 +31,7 @@ public override GLTFExportPluginContext CreateInstance(ExportContext context)
- KHR_materials_specular
- KHR_materials_clearcoat
- KHR_materials_emissive_strength
- KHR_materials_sheen
";
}

Expand Down Expand Up @@ -69,6 +71,10 @@ public MaterialExtensionsExportContext(MaterialExtensionsExport settings)
private static readonly int clearcoatRoughnessTexture = Shader.PropertyToID("clearcoatRoughnessTexture");
private static readonly int clearcoatNormalTexture = Shader.PropertyToID("clearcoatNormalTexture");

private static readonly int sheenColorFactor = Shader.PropertyToID("sheenColorFactor");
private static readonly int sheenRoughnessFactor = Shader.PropertyToID("sheenRoughnessFactor");
private static readonly int sheenColorTexture = Shader.PropertyToID("sheenColorTexture");
private static readonly int sheenRoughnessTexture = Shader.PropertyToID("sheenRoughnessTexture");

public override void AfterMaterialExport(GLTFSceneExporter exporter, GLTFRoot gltfroot, Material material, GLTFMaterial materialnode)
{
Expand All @@ -81,6 +87,7 @@ public override void AfterMaterialExport(GLTFSceneExporter exporter, GLTFRoot gl
var usesIridescence = material.IsKeywordEnabled("_IRIDESCENCE_ON");
var usesSpecular = material.IsKeywordEnabled("_SPECULAR_ON");
var usesClearcoat = material.IsKeywordEnabled("_CLEARCOAT_ON");
var usesSheen = material.IsKeywordEnabled("_SHEEN_ON");

if (hasNonDefaultIor && settings.KHR_materials_ior)
{
Expand Down Expand Up @@ -240,6 +247,31 @@ public override void AfterMaterialExport(GLTFSceneExporter exporter, GLTFRoot gl
if (material.HasProperty(clearcoatNormalTexture))
cc.clearcoatNormalTexture = exporter.ExportTextureInfoWithTextureTransform(material, material.GetTexture(clearcoatNormalTexture), nameof(clearcoatNormalTexture));
}

if (usesSheen && settings.KHR_materials_sheen)
{
exporter.DeclareExtensionUsage(KHR_materials_sheen_Factory.EXTENSION_NAME, false);

if (materialnode.Extensions == null)
materialnode.Extensions = new Dictionary<string, IExtension>();

var cc = new KHR_materials_sheen();

if (materialnode.Extensions.TryGetValue(KHR_materials_sheen_Factory.EXTENSION_NAME, out var vv0))
cc = (KHR_materials_sheen) vv0;
else
materialnode.Extensions.Add(KHR_materials_sheen_Factory.EXTENSION_NAME, cc);

if (material.HasProperty(sheenColorFactor))
cc.sheenColorFactor = material.GetColor(sheenColorFactor).ToNumericsColorRaw();
if (material.HasProperty(sheenColorTexture))
cc.sheenColorTexture = exporter.ExportTextureInfoWithTextureTransform(material, material.GetTexture(sheenColorTexture), nameof(sheenColorTexture));

if (material.HasProperty(sheenRoughnessFactor))
cc.sheenRoughnessFactor = material.GetFloat(sheenRoughnessFactor);
if (material.HasProperty(sheenRoughnessTexture))
cc.sheenRoughnessTexture = exporter.ExportTextureInfoWithTextureTransform(material, material.GetTexture(sheenRoughnessTexture), nameof(sheenRoughnessTexture));
}
}
}
}
1 change: 1 addition & 0 deletions Runtime/Scripts/Plugins/MaterialExtensionsImport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class MaterialExtensionsImport: GLTFImportPlugin
public bool KHR_materials_iridescence = true;
public bool KHR_materials_specular = true;
public bool KHR_materials_clearcoat = true;
public bool KHR_materials_sheen = true;
[HideInInspector] // legacy
public bool KHR_materials_pbrSpecularGlossiness = true;
public bool KHR_materials_emissive_strength = true;
Expand Down
83 changes: 83 additions & 0 deletions Runtime/Scripts/SceneImporter/ImporterMaterials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ void SetTransformKeyword()
var KHR_materials_clearcoat = settings && settings.KHR_materials_clearcoat;
var KHR_materials_pbrSpecularGlossiness = settings && settings.KHR_materials_pbrSpecularGlossiness;
var KHR_materials_emissive_strength = settings && settings.KHR_materials_emissive_strength;
var KHR_materials_sheen = settings && settings.KHR_materials_sheen;
// ReSharper restore InconsistentNaming

var sgMapper = mapper as ISpecGlossUniformMap;
Expand Down Expand Up @@ -298,6 +299,64 @@ void SetTransformKeyword()
}
}

var sheenMapper = mapper as ISheenMap;
if (sheenMapper != null && KHR_materials_sheen)
{
var sheen = GetSheen(def);
if (sheen != null)
{
sheenMapper.SheenColorFactor = sheen.sheenColorFactor.ToUnityColorRaw();
sheenMapper.SheenRoughnessFactor = sheen.sheenRoughnessFactor;
MatHelper.SetKeyword(mapper.Material, "_SHEEN", true);

if (sheen.sheenColorTexture != null)
{
var td = await FromTextureInfo(sheen.sheenColorTexture, false);
sheenMapper.SheenColorTexture = td.Texture;
sheenMapper.SheenColorTextureTexCoord = td.TexCoord;
var ext = GetTextureTransform(sheen.sheenColorTexture);
if (ext != null)
{
CalculateYOffsetAndScale(sheen.sheenColorTexture.Index, ext, out var scale, out var offset);
sheenMapper.SheenColorTextureOffset = offset;
sheenMapper.SheenColorTextureScale = scale;
sheenMapper.SheenColorTextureRotation = td.Rotation;
if (td.TexCoordExtra != null) sheenMapper.SheenColorTextureTexCoord = td.TexCoordExtra.Value;
SetTransformKeyword();
}
else if (IsTextureFlipped(sheen.sheenColorTexture.Index.Value))
{
sheenMapper.SheenColorTextureScale = new Vector2(1f,-1f);
sheenMapper.SheenColorTextureOffset = new Vector2(0f, 1f);
SetTransformKeyword();
}
}

if (sheen.sheenRoughnessTexture != null)
{
var td = await FromTextureInfo(sheen.sheenRoughnessTexture, false);
sheenMapper.SheenRoughnessTexture = td.Texture;
sheenMapper.SheenColorTextureTexCoord = td.TexCoord;
var ext = GetTextureTransform(sheen.sheenRoughnessTexture);
if (ext != null)
{
CalculateYOffsetAndScale(sheen.sheenRoughnessTexture.Index, ext, out var scale, out var offset);
sheenMapper.SheenRoughnessTextureOffset = offset;
sheenMapper.SheenRoughnessTextureScale = scale;
sheenMapper.SheenRoughnessTextureRotation = td.Rotation;
if (td.TexCoordExtra != null) sheenMapper.SheenRoughnessTextureTexCoord = td.TexCoordExtra.Value;
SetTransformKeyword();
}
else if (IsTextureFlipped(sheen.sheenRoughnessTexture.Index.Value))
{
sheenMapper.SheenRoughnessTextureScale = new Vector2(1f,-1f);
sheenMapper.SheenRoughnessTextureOffset = new Vector2(0f, 1f);
SetTransformKeyword();
}
}
}
}

var transmissionMapper = mapper as ITransmissionMap;
if (transmissionMapper != null && KHR_materials_transmission)
{
Expand Down Expand Up @@ -851,6 +910,20 @@ protected virtual Task ConstructMaterialImageBuffers(GLTFMaterial def)
}
}

if (def.Extensions != null && def.Extensions.ContainsKey(KHR_materials_sheen_Factory.EXTENSION_NAME))
{
var sheenDef = (KHR_materials_sheen)def.Extensions[KHR_materials_sheen_Factory.EXTENSION_NAME];
if (sheenDef.sheenColorTexture != null)
{
var textureId = sheenDef.sheenColorTexture.Index;
tasks.Add(ConstructImageBuffer(textureId.Value, textureId.Id));
}
if (sheenDef.sheenRoughnessTexture != null)
{
var textureId = sheenDef.sheenRoughnessTexture.Index;
tasks.Add(ConstructImageBuffer(textureId.Value, textureId.Id));
}
}

if (def.Extensions != null && def.Extensions.ContainsKey(KHR_materials_clearcoat_Factory.EXTENSION_NAME))
{
Expand Down Expand Up @@ -908,6 +981,16 @@ protected virtual KHR_materials_transmission GetTransmission(GLTFMaterial def)
return null;
}

protected virtual KHR_materials_sheen GetSheen(GLTFMaterial def)
{
if (_gltfRoot.ExtensionsUsed != null && _gltfRoot.ExtensionsUsed.Contains(KHR_materials_sheen_Factory.EXTENSION_NAME) &&
def.Extensions != null && def.Extensions.TryGetValue(KHR_materials_sheen_Factory.EXTENSION_NAME, out var extension))
{
return (KHR_materials_sheen) extension;
}
return null;
}

protected virtual KHR_materials_dispersion GetDispersion(GLTFMaterial def)
{
if (_gltfRoot.ExtensionsUsed != null && _gltfRoot.ExtensionsUsed.Contains(KHR_materials_dispersion_Factory.EXTENSION_NAME) &&
Expand Down
Loading