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

色プロパティのシリアライズ・デシリアライズ時に色空間をコードで明示 #933

Merged
merged 8 commits into from
May 7, 2021
73 changes: 73 additions & 0 deletions Assets/UniGLTF/Runtime/Extensions/ColorConversionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using UnityEngine;

namespace UniGLTF
{
public enum ColorSpace
{
sRGB,
Linear,
}

public static class ColorConversionExtensions
{
public static float[] ToFloat4(this Color src, ColorSpace srcColorSpace, ColorSpace dstColorSpace)
{
var dst = src.ConvertColorSpace(srcColorSpace, dstColorSpace);
return new float[] {dst.r, dst.g, dst.b, dst.a};
}

public static float[] ToFloat3(this Color src, ColorSpace srcColorSpace, ColorSpace dstColorSpace)
{
var dst = src.ConvertColorSpace(srcColorSpace, dstColorSpace);
return new float[] {dst.r, dst.g, dst.b};
}

public static Color ToColor4(this float[] src, ColorSpace srcColorSpace, ColorSpace dstColorSpace)
{
if (src == null || src.Length < 4)
{
Debug.LogWarning("Invalid argument.");
return Color.magenta;
}

return new Color(src[0], src[1], src[2], src[3]).ConvertColorSpace(srcColorSpace, dstColorSpace);
}

public static Color ToColor3(this float[] src, ColorSpace srcColorSpace, ColorSpace dstColorSpace)
{
if (src == null || src.Length < 3)
{
Debug.LogWarning("Invalid argument.");
return Color.magenta;
}

return new Color(src[0], src[1], src[2], 1f).ConvertColorSpace(srcColorSpace, dstColorSpace);
}

private static Color ConvertColorSpace(this Color srcColor, ColorSpace srcColorSpace, ColorSpace dstColorSpace)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

2 x 2 = 4 pattern

// Need pattern matching :(
if (srcColorSpace == ColorSpace.sRGB && dstColorSpace == ColorSpace.sRGB)
{
return srcColor;
}
else if (srcColorSpace == ColorSpace.sRGB && dstColorSpace == ColorSpace.Linear)
{
return srcColor.linear;
}
else if (srcColorSpace == ColorSpace.Linear && dstColorSpace == ColorSpace.sRGB)
{
return srcColor.gamma;
}
else if (srcColorSpace == ColorSpace.Linear && dstColorSpace == ColorSpace.Linear)
{
return srcColor;
}
else
{
throw new ArgumentException();
}
}
}
}

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

5 changes: 0 additions & 5 deletions Assets/UniGLTF/Runtime/Extensions/UnityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,6 @@ public static float[] ToArray(this Vector4 v)
return new float[] { v.x, v.y, v.z, v.w };
}

public static float[] ToArray(this Color c)
{
return new float[] { c.r, c.g, c.b, c.a };
}

public static void ReverseRecursive(this Transform root, IAxisInverter axisInverter)
{
var globalMap = root.Traverse().ToDictionary(x => x, x => PosRot.FromGlobalTransform(x));
Expand Down
13 changes: 7 additions & 6 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialIO/GltfPBRMaterial.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
using VRMShaders;


namespace UniGLTF
{
/// <summary>
Expand Down Expand Up @@ -103,8 +101,9 @@ public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportPa

if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
var color = src.pbrMetallicRoughness.baseColorFactor;
param.Colors.Add("_Color", (new Color(color[0], color[1], color[2], color[3])).gamma);
param.Colors.Add("_Color",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

glTF の定義として baseColorFactor は Linear 空間の色である。
また、Unity の Standard Shader の _Color プロパティは sRGB 空間の色である。
その変換を明示。

Copy link
Contributor Author

Choose a reason for hiding this comment

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

glTF Import

Copy link
Contributor

Choose a reason for hiding this comment

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

);
}

if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
Expand Down Expand Up @@ -153,7 +152,9 @@ public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportPa

if (src.emissiveFactor != null && src.emissiveFactor.Length == 3)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

param.Colors.Add("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2]));
param.Colors.Add("_EmissionColor",
src.emissiveFactor.ToColor3(ColorSpace.Linear, ColorSpace.Linear)
);
}

if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportPa
// color
if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
{
var color = src.pbrMetallicRoughness.baseColorFactor;
param.Colors.Add("_Color", (new Color(color[0], color[1], color[2], color[3])).gamma);
param.Colors.Add("_Color",
src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB)
);
}

//renderMode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static void Export_Color(Material m, TextureExporter textureManager, glTFMateria
{
if (m.HasProperty("_Color"))
{
material.pbrMetallicRoughness.baseColorFactor = m.color.linear.ToArray();
material.pbrMetallicRoughness.baseColorFactor = m.GetColor("_Color").ToFloat4(ColorSpace.sRGB, ColorSpace.Linear);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

glTF Export

}

if (m.HasProperty("_MainTex"))
Expand Down Expand Up @@ -161,7 +161,7 @@ static void Export_Emission(Material m, TextureExporter textureManager, glTFMate
{
color /= color.maxColorComponent;
}
material.emissiveFactor = new float[] { color.r, color.g, color.b };
material.emissiveFactor = color.ToFloat3(ColorSpace.Linear, ColorSpace.Linear);
}

if (m.HasProperty("_EmissionMap"))
Expand Down
52 changes: 0 additions & 52 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ColorSpace.cs

This file was deleted.

11 changes: 0 additions & 11 deletions Assets/UniGLTF/Runtime/UniGLTF/IO/TextureIO/ColorSpace.cs.meta

This file was deleted.

4 changes: 3 additions & 1 deletion Assets/VRM/Runtime/IO/VRMMaterialExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using UniGLTF.ShaderPropExporter;
using UnityEngine;
using VRMShaders;
using ColorSpace = UniGLTF.ColorSpace;

namespace VRM
{
Expand Down Expand Up @@ -160,7 +161,8 @@ public static glTF_VRM_Material CreateFromMaterial(Material m, TextureExporter t
{
case ShaderPropertyType.Color:
{
var value = m.GetColor(kv.Key).ToArray();
// No color conversion. Because color property is serialized to raw float array.
var value = m.GetColor(kv.Key).ToFloat4(ColorSpace.Linear, ColorSpace.Linear);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

VRM0.x Export

material.vectorProperties.Add(kv.Key, value);
}
break;
Expand Down
5 changes: 3 additions & 2 deletions Assets/VRM10/Runtime/IO/Vrm10MaterialExporter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using UniGLTF;
using UnityEngine;
using VRMShaders;
using ColorSpace = UniGLTF.ColorSpace;

namespace UniVRM10
{
Expand All @@ -23,14 +24,14 @@ public override glTFMaterial ExportMaterial(Material m, TextureExporter textureE

pbrMetallicRoughness = new glTFPbrMetallicRoughness
{
baseColorFactor = def.Color.LitColor.ToArray(),
baseColorFactor = def.Color.LitColor.ToFloat4(ColorSpace.sRGB, ColorSpace.Linear),
Copy link
Contributor Author

@Santarh Santarh May 7, 2021

Choose a reason for hiding this comment

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

VRM10 Export

baseColorTexture = new glTFMaterialBaseColorTextureInfo
{
index = textureExporter.ExportSRGB(def.Color.LitMultiplyTexture),
},
},

emissiveFactor = def.Emission.EmissionColor.ToArray(),
emissiveFactor = def.Emission.EmissionColor.ToFloat3(ColorSpace.Linear, ColorSpace.Linear),
};

// VRMC_materials_mtoon
Expand Down
65 changes: 25 additions & 40 deletions Assets/VRM10/Runtime/IO/Vrm10MaterialImporter.cs
Original file line number Diff line number Diff line change
@@ -1,45 +1,11 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniGLTF;
using UniGLTF;
using UnityEngine;
using VRMShaders;


namespace UniVRM10
{
public static class Vrm10MaterialImporter
{
public static Color ToColor4(this float[] src, Color defaultValue = default)
{
if (src == null || src.Length != 4)
{
throw new NotImplementedException();
}

var v = new Vector4(
src[0],
src[1],
src[2],
src[3]
);
return v;
}
public static Color ToColor3(this float[] src, Color defaultValue = default)
{
if (src == null || src.Length < 3)
{
throw new NotImplementedException();
}

var v = new Vector4(
src[0],
src[1],
src[2]
);
return v;
}

/// <summary>
/// VMRC_materials_mtoon の場合にマテリアル生成情報を作成する
/// </summary>
Expand Down Expand Up @@ -75,8 +41,15 @@ public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportPa
}
{
// var color = mtoon.Color;
material.SetColor(MToon.Utils.PropColor, m.pbrMetallicRoughness.baseColorFactor.ToColor4());
if (mtoon.ShadeColorFactor != null) material.SetColor(MToon.Utils.PropShadeColor, mtoon.ShadeColorFactor.ToColor3());
material.SetColor(MToon.Utils.PropColor, m.pbrMetallicRoughness.baseColorFactor
.ToColor4(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

VRM10 Import

);
if (mtoon.ShadeColorFactor != null)
{
material.SetColor(MToon.Utils.PropShadeColor, mtoon.ShadeColorFactor
.ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
);
}
material.SetFloat(MToon.Utils.PropCutoff, m.alphaCutoff);
}
{
Expand All @@ -91,17 +64,29 @@ public static bool TryCreateParam(GltfParser parser, int i, out MaterialImportPa
}
}
{
material.SetColor(MToon.Utils.PropEmissionColor, m.emissiveFactor.ToColor3());
material.SetColor(MToon.Utils.PropEmissionColor,
m.emissiveFactor.ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.Linear)
);
}
{
if (mtoon.ParametricRimColorFactor != null) material.SetColor(MToon.Utils.PropRimColor, mtoon.ParametricRimColorFactor.ToColor3());
if (mtoon.ParametricRimColorFactor != null)
{
material.SetColor(MToon.Utils.PropRimColor, mtoon.ParametricRimColorFactor
.ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
);
}
if (mtoon.RimLightingMixFactor.HasValue) material.SetFloat(MToon.Utils.PropRimLightingMix, mtoon.RimLightingMixFactor.Value);
if (mtoon.ParametricRimFresnelPowerFactor.HasValue) material.SetFloat(MToon.Utils.PropRimFresnelPower, mtoon.ParametricRimFresnelPowerFactor.Value);
if (mtoon.ParametricRimLiftFactor.HasValue) material.SetFloat(MToon.Utils.PropRimLift, mtoon.ParametricRimLiftFactor.Value);
}
{
if (mtoon.OutlineWidthFactor.HasValue) material.SetFloat(MToon.Utils.PropOutlineWidth, mtoon.OutlineWidthFactor.Value);
if (mtoon.OutlineColorFactor != null) material.SetColor(MToon.Utils.PropOutlineColor, mtoon.OutlineColorFactor.ToColor3());
if (mtoon.OutlineColorFactor != null)
{
material.SetColor(MToon.Utils.PropOutlineColor, mtoon.OutlineColorFactor
.ToColor3(UniGLTF.ColorSpace.Linear, UniGLTF.ColorSpace.sRGB)
);
}
if (mtoon.OutlineLightingMixFactor.HasValue) material.SetFloat(MToon.Utils.PropOutlineLightingMix, mtoon.OutlineLightingMixFactor.Value);

// private
Expand Down
Loading