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

UniUniltでMultiply設定の時以外に自動で頂点カラーを落とす変更 #569

Merged
merged 21 commits into from
Oct 6, 2020
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
2 changes: 1 addition & 1 deletion Assets/VRM.Samples/Editor/Tests/VRMImportExportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void ImportExportTest()
*/
importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride"));

var vrm = VRMExporter.Export(context.Root);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root);

// TODO: Check contents in JSON
/*var exportJson = */
Expand Down
2 changes: 1 addition & 1 deletion Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void OnExportClicked()
return;
}

var vrm = VRMExporter.Export(m_model);
var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, m_model);
var bytes = vrm.ToGlbBytes();
File.WriteAllBytes(path, bytes);
Debug.LogFormat("export to {0}", path);
Expand Down
6 changes: 3 additions & 3 deletions Assets/VRM/UniGLTF/Editor/Tests/UniGLTFTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public void UniGLTFSimpleSceneTest()
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export();
exporter.Export(MeshExportSettings.Default);

// remove empty buffer
gltf.buffers.Clear();
Expand Down Expand Up @@ -307,7 +307,7 @@ public void GlTFToJsonTest()
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(CreateSimpleScene());
exporter.Export();
exporter.Export(MeshExportSettings.Default);
}

var expected = gltf.ToJson().ParseAsJson();
Expand Down Expand Up @@ -629,7 +629,7 @@ public void SameMeshButDifferentMaterialExport()
using (var exporter = new gltfExporter(gltf))
{
exporter.Prepare(go);
exporter.Export();
exporter.Export(UniGLTF.MeshExportSettings.Default);

json = gltf.ToJson();
}
Expand Down
141 changes: 132 additions & 9 deletions Assets/VRM/UniGLTF/Scripts/IO/MeshExporter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace UniGLTF
Expand All @@ -13,13 +14,130 @@ public struct MeshWithRenderer
public Renderer Renderer;
}

[Serializable]
public struct MeshExportInfo
{
public Renderer Renderer;
public Mesh Mesh;
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 == null)
{
return false;
}
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>
/// Position, UV, Normal
/// [Color]
/// [SkinningWeight]
/// </summary>
public int ExportVertexSize;

public int IndexCount;

// int 決め打ち
public int IndicesSize => IndexCount * 4;

public int ExportBlendShapeVertexSize;

public int TotalBlendShapeCount;

public int ExportBlendShapeCount;

public int ExportByteSize => ExportVertexSize * VertexCount + IndicesSize + ExportBlendShapeCount * ExportBlendShapeVertexSize * VertexCount;

public string Summary;
}

public struct MeshExportSettings
{
// MorphTarget に Sparse Accessor を使う
public bool UseSparseAccessorForMorphTarget;

// MorphTarget を Position だけにする(normal とか捨てる)
public bool ExportOnlyBlendShapePosition;

public static MeshExportSettings Default => new MeshExportSettings
{
UseSparseAccessorForMorphTarget = false,
ExportOnlyBlendShapePosition = false,
};
}

public static class MeshExporter
{
static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex,
string rendererName,
Mesh mesh, Material[] materials,
List<Material> unityMaterials,
bool removeVertexColor)
List<Material> unityMaterials)
{
var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray();
var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER);
Expand All @@ -33,8 +151,15 @@ static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex,
var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);

var colorAccessorIndex = -1;
if (!removeVertexColor)

var vColorState = MeshExportInfo.DetectVertexColor(mesh, materials);
if (vColorState == MeshExportInfo.VertexColorState.ExistsAndIsUsed // VColor使っている
|| vColorState == MeshExportInfo.VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
)
{
// UniUnlit で Multiply 設定になっている
colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.ARRAY_BUFFER);
}

var boneweights = mesh.boneWeights;
var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER);
Expand Down Expand Up @@ -234,9 +359,7 @@ static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex,

public static IEnumerable<(Mesh, glTFMesh, Dictionary<int, int>)> ExportMeshes(glTF gltf, int bufferIndex,
List<MeshWithRenderer> unityMeshes, List<Material> unityMaterials,
bool useSparseAccessorForMorphTarget,
bool exportOnlyBlendShapePosition,
bool removeVertexColor)
MeshExportSettings settings)
{
for (int i = 0; i < unityMeshes.Count; ++i)
{
Expand All @@ -246,16 +369,16 @@ static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex,

var gltfMesh = ExportPrimitives(gltf, bufferIndex,
x.Renderer.name,
mesh, materials, unityMaterials, removeVertexColor);
mesh, materials, unityMaterials);

var blendShapeIndexMap = new Dictionary<int, int>();
int exportBlendShapes = 0;
for (int j = 0; j < mesh.blendShapeCount; ++j)
{
var morphTarget = ExportMorphTarget(gltf, bufferIndex,
mesh, j,
useSparseAccessorForMorphTarget,
exportOnlyBlendShapePosition);
settings.UseSparseAccessorForMorphTarget,
settings.ExportOnlyBlendShapePosition);
if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0)
{
continue;
Expand Down
Loading