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

Bake smoothness and roughnessFactor into textures. #222

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 18 additions & 8 deletions Assets/VRM/UniGLTF/Scripts/IO/MaterialExporter.cs
Expand Up @@ -61,32 +61,42 @@ static void Export_Metallic(Material m, TextureExportManager textureManager, glT
int index = -1;
if (m.HasProperty("_MetallicGlossMap"))
{
index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), new MetallicRoughnessConverter());
float smoothness = 0.0f;
if (m.HasProperty("_GlossMapScale"))
{
smoothness = m.GetFloat("_GlossMapScale");
}

// Bake smoothness values into a texture.
var converter = new MetallicRoughnessConverter(smoothness);
index = textureManager.ConvertAndGetIndex(m.GetTexture("_MetallicGlossMap"), converter);
if (index != -1)
{
material.pbrMetallicRoughness.metallicRoughnessTexture = new glTFMaterialMetallicRoughnessTextureInfo()
{
index = index,
};
material.pbrMetallicRoughness.metallicRoughnessTexture =
new glTFMaterialMetallicRoughnessTextureInfo()
{
index = index,
};
}
}

if (index != -1 && m.HasProperty("_GlossMapScale"))
if (index != -1)
{
material.pbrMetallicRoughness.metallicFactor = 1.0f;
material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_GlossMapScale");
// Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
material.pbrMetallicRoughness.roughnessFactor = 1.0f;
}
else
{
if (m.HasProperty("_Metallic"))
{
material.pbrMetallicRoughness.metallicFactor = m.GetFloat("_Metallic");
}

if (m.HasProperty("_Glossiness"))
{
material.pbrMetallicRoughness.roughnessFactor = 1.0f - m.GetFloat("_Glossiness");
}

}
}

Expand Down
7 changes: 5 additions & 2 deletions Assets/VRM/UniGLTF/Scripts/IO/MaterialImporter.cs
Expand Up @@ -164,11 +164,14 @@ public virtual Material CreateMaterial(int i, glTFMaterial x)
if (texture != null)
{
var prop = "_MetallicGlossMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
var smoothness = 1.0f - x.pbrMetallicRoughness.roughnessFactor;
// Bake smoothness values into a texture.
material.SetTexture(prop, texture.ConvertTexture(prop, smoothness));
}

material.SetFloat("_Metallic", 1.0f);
material.SetFloat("_GlossMapScale", 1.0f - x.pbrMetallicRoughness.roughnessFactor);
// Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
material.SetFloat("_GlossMapScale", 1.0f);
}
else
{
Expand Down
20 changes: 18 additions & 2 deletions Assets/VRM/UniGLTF/Scripts/IO/TextureConverter.cs
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
Expand Down Expand Up @@ -50,6 +51,13 @@ class MetallicRoughnessConverter : ITextureConverter
{
private const string m_extension = ".metallicRoughness";

private float _smoothness;

public MetallicRoughnessConverter(float smoothness)
{
_smoothness = smoothness;
}

public Texture2D GetImportTexture(Texture2D texture)
{
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null);
Expand All @@ -66,21 +74,29 @@ public Texture2D GetExportTexture(Texture2D texture)

public Color32 Import(Color32 src)
{
// Roughness(glTF): dst.g -> Smoothness(Unity): src.a (with conversion)
// Metallic(glTF) : dst.b -> Metallic(Unity) : src.r
return new Color32
{
r = src.b,
g = 0,
b = 0,
a = (byte)(255 - src.g),
// Bake roughness values into a texture.
// See: https://github.com/dwango/UniVRM/issues/212.
a = (byte)(255 - Math.Min(src.g * (1.0f - _smoothness), 255)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちら、 roughness = 1.0 - smoothness でなく、
roughness = (1.0 - smoothness)^2 とのことですので、修正をお願いします。

以下のような要因で即時の変更が難しい場合、次のPRにまわしていただいても構わないです。

  • UniGLTF全編に対する変更が必要なこと
  • エクスポート結果が変化すること(正しくはなります)

こちらの記事を参考にどうぞ。
Roughnessは学術的に確立されたパラメータではあるものの、視覚的変化が線形でないため、
SmoothnessというRoughnessを一段覆うパラメータが生まれたようです。
https://blogs.unity3d.com/jp/2016/01/25/ggx-in-unity-5-3/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おお、ありがとうございます!変更いたします。記事も参考になります 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c8489af で対応しました。Import/Exportの段階ですべて変換してしまう方針です。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

計算間違えているので修正します...

};
}

public Color32 Export(Color32 src)
{
// Smoothness(Unity): src.a -> Roughness(glTF): dst.g (with conversion)
// Metallic(Unity) : src.r -> Metallic(glTF) : dst.b
return new Color32
{
r = 0,
g = (byte)(255 - src.a),
// Bake smoothness values into a texture.
// See: https://github.com/dwango/UniVRM/issues/212.
g = (byte)(255 - Math.Min(src.a * _smoothness, 255)),
b = src.r,
a = 255,
};
Expand Down
10 changes: 8 additions & 2 deletions Assets/VRM/UniGLTF/Scripts/IO/TextureItem.cs
Expand Up @@ -30,7 +30,13 @@ public Texture2D Texture
get { return m_converts; }
}

public Texture2D ConvertTexture(string prop)
/// <summary>
///
/// </summary>
/// <param name="prop"></param>
/// <param name="smoothness">used only when converting MetallicRoughness maps</param>
/// <returns></returns>
public Texture2D ConvertTexture(string prop, float smoothness = 1.0f)
{
var convertedTexture = Converts.FirstOrDefault(x => x.Key == prop);
if (convertedTexture.Value != null)
Expand Down Expand Up @@ -63,7 +69,7 @@ public Texture2D ConvertTexture(string prop)

if (prop == "_MetallicGlossMap")
{
var converted = new MetallicRoughnessConverter().GetImportTexture(Texture);
var converted = new MetallicRoughnessConverter(smoothness).GetImportTexture(Texture);
m_converts.Add(prop, converted);
return converted;
}
Expand Down