implement MeshExportInfo.DetectVertexColor

sharedMaterials に 頂点カラーを使う Unlit と 頂点カラーを使わない Unlit が混在することを検知
This commit is contained in:
ousttrue 2020-10-05 15:15:40 +09:00
parent 94694b4186
commit 705f3480f5
2 changed files with 66 additions and 35 deletions

View File

@ -22,17 +22,72 @@ namespace UniGLTF
public bool IsRendererActive;
public bool Skinned;
/// <summary>
/// Mesh に頂点カラーが含まれているか。
/// 含まれている場合にマテリアルは Unlit.VColorMultiply になっているか?
/// </summary>
public enum VertexColorState
{
// 存在しない
// VColorが存在しない
None,
// 存在して使用している
// VColorが存在して使用している(UnlitはすべてVColorMultiply)
ExistsAndIsUsed,
// 存在するが使用していない
// VColorが存在するが使用していない(UnlitはすべてVColorNone。もしくはUnlitが存在しない)
ExistsButNotUsed,
// VColorが存在して、Unlit.Multiply と Unlit.NotMultiply が混在している。 Unlit.NotMultiply を MToon か Standardに変更した方がよい
ExistsAndMixed,
}
public VertexColorState VertexColor;
static bool MaterialUseVertexColor(Material m)
{
if (m.shader.name != UniGLTF.UniUnlit.Utils.ShaderName)
{
return false;
}
if (UniGLTF.UniUnlit.Utils.GetVColBlendMode(m) != UniGLTF.UniUnlit.UniUnlitVertexColorBlendOp.Multiply)
{
return false;
}
return true;
}
public static VertexColorState DetectVertexColor(Mesh mesh, Material[] materials)
{
if (mesh != null && mesh.colors != null && mesh.colors.Length == mesh.vertexCount)
{
// mesh が 頂点カラーを保持している
VertexColorState? state = default;
if (materials != null)
{
foreach (var m in materials)
{
var currentState = MaterialUseVertexColor(m)
? UniGLTF.MeshExportInfo.VertexColorState.ExistsAndIsUsed
: UniGLTF.MeshExportInfo.VertexColorState.ExistsButNotUsed
;
if (state.HasValue)
{
if (state.Value != currentState)
{
state = UniGLTF.MeshExportInfo.VertexColorState.ExistsAndMixed;
break;
}
}
else
{
state = currentState;
}
}
}
return state.GetValueOrDefault(VertexColorState.None);
}
else
{
return VertexColorState.None;
}
}
public int VertexCount;
/// <summary>
@ -92,15 +147,14 @@ namespace UniGLTF
var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
var colorAccessorIndex = -1;
if (mesh.colors != null && mesh.colors.Length == mesh.vertexCount)
var vColorState = MeshExportInfo.DetectVertexColor(mesh, materials);
if (vColorState == MeshExportInfo.VertexColorState.ExistsAndIsUsed // VColor使っている
|| vColorState == MeshExportInfo.VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
)
{
// この Mesh が 頂点カラーを保持していて
if (materials.Any(x => x.shader.name == UniGLTF.UniUnlit.Utils.ShaderName
&& UniGLTF.UniUnlit.Utils.GetVColBlendMode(x) == UniUnlit.UniUnlitVertexColorBlendOp.Multiply))
{
// UniUnlit で Multiply 設定になっている
colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER);
}
// UniUnlit で Multiply 設定になっている
colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER);
}
var boneweights = mesh.boneWeights;

View File

@ -62,19 +62,6 @@ namespace VRM
List<Validation> m_validations = new List<Validation>();
public IEnumerable<Validation> Validations => m_validations;
static bool MaterialUseVertexColor(Material m)
{
if (m.shader.name != UniGLTF.UniUnlit.Utils.ShaderName)
{
return false;
}
if (UniGLTF.UniUnlit.Utils.GetVColBlendMode(m) != UniGLTF.UniUnlit.UniUnlitVertexColorBlendOp.Multiply)
{
return false;
}
return true;
}
public static void CalcMeshSize(ref UniGLTF.MeshExportInfo info,
string relativePath, VRMExportSettings settings, IReadOnlyList<BlendShapeClip> clips)
{
@ -193,17 +180,7 @@ namespace VRM
return false;
}
if (info.Mesh.colors != null && info.Mesh.colors.Length == info.Mesh.vertexCount)
{
if (renderer.sharedMaterials.Any(x => MaterialUseVertexColor(x)))
{
info.VertexColor = UniGLTF.MeshExportInfo.VertexColorState.ExistsAndIsUsed;
}
else
{
info.VertexColor = UniGLTF.MeshExportInfo.VertexColorState.ExistsButNotUsed;
}
}
info.VertexColor = UniGLTF.MeshExportInfo.DetectVertexColor(info.Mesh, info.Renderer.sharedMaterials);
var relativePath = UniGLTF.UnityExtensions.RelativePathFrom(renderer.transform, root.transform);
CalcMeshSize(ref info, relativePath, settings, clips);