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 3 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
6 changes: 4 additions & 2 deletions Assets/VRM/UniGLTF/Scripts/IO/MaterialImporter.cs
Expand Up @@ -164,11 +164,13 @@ public virtual Material CreateMaterial(int i, glTFMaterial x)
if (texture != null)
{
var prop = "_MetallicGlossMap";
material.SetTexture(prop, texture.ConvertTexture(prop));
// Bake roughnessFactor values into a texture.
material.SetTexture(prop, texture.ConvertTexture(prop, x.pbrMetallicRoughness.roughnessFactor));
}

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
29 changes: 27 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 _smoothnessOrRoughness;

public MetallicRoughnessConverter(float smoothnessOrRoughness)
{
_smoothnessOrRoughness = smoothnessOrRoughness;
}

public Texture2D GetImportTexture(Texture2D texture)
{
var converted = TextureConverter.Convert(texture, glTFTextureTypes.Metallic, Import, null);
Expand All @@ -66,21 +74,38 @@ 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

var pixelRoughnessFactor = src.g * _smoothnessOrRoughness; // roughness
var pixelSmoothness = 1.0f - Mathf.Sqrt(pixelRoughnessFactor);

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)Mathf.Clamp(pixelSmoothness * 255, 0, 255),
};
}

public Color32 Export(Color32 src)
{
// Smoothness(Unity): src.a -> Roughness(glTF): dst.g (with conversion)
// Metallic(Unity) : src.r -> Metallic(glTF) : dst.b

var pixelSmoothness = src.a * _smoothnessOrRoughness; // smoothness
// https://blogs.unity3d.com/jp/2016/01/25/ggx-in-unity-5-3/
var pixelRoughnessFactor = (1.0f - pixelSmoothness) * (1.0f - pixelSmoothness);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
var pixelRoughnessFactor = (1.0f - pixelSmoothness) * (1.0f - pixelSmoothness);
var pixelRoughnessFactorSqrt = (1.0f - pixelSmoothness);
var pixelRoughnessFactor = pixelRoughnessFactorSqrt * pixelRoughnessFactorSqrt;

めちゃ細かいですが……w

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

@0b5vr 0b5vr Mar 15, 2019

Choose a reason for hiding this comment

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

対応ありがとうございます 🙏


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)Mathf.Clamp(pixelRoughnessFactor * 255, 0, 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 smoothnessOrRoughness = 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(smoothnessOrRoughness).GetImportTexture(Texture);
m_converts.Add(prop, converted);
return converted;
}
Expand Down