mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-07 11:28:35 -05:00
Merge pull request #1415 from ousttrue/feature/keep_vertex_color
Feature/keep vertex color
This commit is contained in:
@@ -40,5 +40,10 @@ namespace UniGLTF
|
||||
/// VRMC_materials_hdr_emissiveMultiplier
|
||||
/// </summary>
|
||||
public bool UseEmissiveMultiplier;
|
||||
|
||||
/// <summary>
|
||||
/// Keep VertexColor
|
||||
/// </summary>
|
||||
public bool KeepVertexColor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace UniGLTF
|
||||
readonly List<Vector3> m_positions;
|
||||
readonly List<Vector3> m_normals;
|
||||
readonly List<Vector2> m_uv;
|
||||
readonly List<Vector4> m_color;
|
||||
|
||||
readonly Func<int, int> m_getJointIndex;
|
||||
readonly List<UShort4> m_joints;
|
||||
@@ -78,6 +79,7 @@ namespace UniGLTF
|
||||
m_positions = new List<Vector3>(vertexCount);
|
||||
m_normals = new List<Vector3>(vertexCount);
|
||||
m_uv = new List<Vector2>();
|
||||
m_color = new List<Vector4>();
|
||||
|
||||
m_getJointIndex = getJointIndex;
|
||||
if (m_getJointIndex != null)
|
||||
@@ -87,7 +89,7 @@ namespace UniGLTF
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(int index, Vector3 position, Vector3 normal, Vector2 uv)
|
||||
public void PushVertex(int index, Vector3 position, Vector3 normal, Vector2 uv)
|
||||
{
|
||||
var newIndex = m_positions.Count;
|
||||
m_vertexIndexMap.Add(index, newIndex);
|
||||
@@ -97,7 +99,12 @@ namespace UniGLTF
|
||||
m_uv.Add(uv);
|
||||
}
|
||||
|
||||
public void Push(BoneWeight boneWeight)
|
||||
public void PushColor(Vector4 color)
|
||||
{
|
||||
m_color.Add(color);
|
||||
}
|
||||
|
||||
public void PushBoneWeight(BoneWeight boneWeight)
|
||||
{
|
||||
m_joints.Add(new UShort4((ushort)boneWeight.boneIndex0, (ushort)boneWeight.boneIndex1, (ushort)boneWeight.boneIndex2, (ushort)boneWeight.boneIndex3));
|
||||
m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3));
|
||||
@@ -123,6 +130,12 @@ namespace UniGLTF
|
||||
weightAccessorIndex = data.ExtendBufferAndGetAccessorIndex(m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
int? vertexColorIndex = default;
|
||||
if (m_color.Count == m_positions.Count)
|
||||
{
|
||||
vertexColorIndex = data.ExtendBufferAndGetAccessorIndex(m_color.ToArray(), glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
var primitive = new glTFPrimitives
|
||||
{
|
||||
indices = indicesAccessorIndex,
|
||||
@@ -133,6 +146,7 @@ namespace UniGLTF
|
||||
TEXCOORD_0 = uvAccessorIndex0,
|
||||
JOINTS_0 = jointsAccessorIndex.GetValueOrDefault(-1),
|
||||
WEIGHTS_0 = weightAccessorIndex.GetValueOrDefault(-1),
|
||||
COLOR_0 = vertexColorIndex.GetValueOrDefault(-1),
|
||||
},
|
||||
material = materialIndex,
|
||||
mode = 4,
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace UniGLTF
|
||||
var normals = mesh.normals;
|
||||
var uv = mesh.uv;
|
||||
var boneWeights = mesh.boneWeights;
|
||||
var colors = mesh.colors;
|
||||
|
||||
Func<int, int> getJointIndex = null;
|
||||
if (boneWeights != null && boneWeights.Length == positions.Length)
|
||||
@@ -44,25 +45,40 @@ namespace UniGLTF
|
||||
Vector3[] blendShapePositions = new Vector3[mesh.vertexCount];
|
||||
Vector3[] blendShapeNormals = new Vector3[mesh.vertexCount];
|
||||
|
||||
var vColorState = VertexColorUtility.DetectVertexColor(mesh, unityMaterials);
|
||||
var exportVertexColor = (
|
||||
(settings.KeepVertexColor && mesh.colors != null && mesh.colors.Length == mesh.vertexCount) // vertex color を残す設定
|
||||
|| vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
|
||||
|| vColorState == VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
|
||||
);
|
||||
|
||||
var usedIndices = new List<int>();
|
||||
for (int i = 0; i < mesh.subMeshCount; ++i)
|
||||
{
|
||||
var indices = mesh.GetIndices(i);
|
||||
var hash = new HashSet<int>(indices);
|
||||
|
||||
// aggrigate vertex attributes
|
||||
// aggregate vertex attributes
|
||||
var buffer = new MeshExportUtil.VertexBuffer(indices.Length, getJointIndex);
|
||||
usedIndices.Clear();
|
||||
for (int k = 0; k < positions.Length; ++k)
|
||||
{
|
||||
if (hash.Contains(k))
|
||||
{
|
||||
// aggrigate indices
|
||||
// aggregate indices
|
||||
usedIndices.Add(k);
|
||||
buffer.Push(k, axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV());
|
||||
buffer.PushVertex(k,
|
||||
axisInverter.InvertVector3(positions[k]), // POSITION
|
||||
axisInverter.InvertVector3(normals[k]), // NORMAL
|
||||
uv[k].ReverseUV() // UV
|
||||
);
|
||||
if (getJointIndex != null)
|
||||
{
|
||||
buffer.Push(boneWeights[k]);
|
||||
buffer.PushBoneWeight(boneWeights[k]);
|
||||
}
|
||||
if (exportVertexColor)
|
||||
{
|
||||
buffer.PushColor(colors[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace UniGLTF
|
||||
var colorAccessorIndex = -1;
|
||||
|
||||
var vColorState = VertexColorUtility.DetectVertexColor(mesh, materials);
|
||||
if (vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
|
||||
if ((settings.KeepVertexColor && mesh.colors != null && mesh.colors.Length == mesh.vertexCount) // vertex color を残す設定
|
||||
|| vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
|
||||
|| vColorState == VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
|
||||
)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UniGLTF
|
||||
@@ -37,7 +38,7 @@ namespace UniGLTF
|
||||
return true;
|
||||
}
|
||||
|
||||
public static VertexColorState DetectVertexColor(Mesh mesh, Material[] materials)
|
||||
public static VertexColorState DetectVertexColor(Mesh mesh, IEnumerable<Material> materials)
|
||||
{
|
||||
if (mesh != null && mesh.colors != null && mesh.colors.Length == mesh.vertexCount)
|
||||
{
|
||||
|
||||
51
Assets/VRM/Editor/Format/VRMExportOptions.cs
Normal file
51
Assets/VRM/Editor/Format/VRMExportOptions.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using UniGLTF.M17N;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
public enum VRMExportOptions
|
||||
{
|
||||
[LangMsg(Languages.ja, "エクスポート時に強制的にT-Pose化する。これを使わずに手動でT-Poseを作っても問題ありません")]
|
||||
[LangMsg(Languages.en, "Force T-Pose before export. Manually making T-Pose for model without enabling this is ok")]
|
||||
FORCE_T_POSE,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポート時に正規化(ヒエラルキーから回転と拡大縮小を取り除くためにベイク)する")]
|
||||
[LangMsg(Languages.en, "Model's normalization (bake to remove roation and scaling from the hierarchy)")]
|
||||
NORMALIZE,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポート時に新しいJsonSerializerを使う")]
|
||||
[LangMsg(Languages.en, "The new version of JsonSerializer for model export")]
|
||||
USE_GENERATED_SERIALIZER,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeの容量を GLTF の Sparse Accessor 機能で削減する。修正中: UniGLTF以外でロードできません")]
|
||||
[LangMsg(Languages.en, "BlendShape size can be reduced by using Sparse Accessor")]
|
||||
BLENDSHAPE_USE_SPARSE,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClipのエクスポートに法線とTangentを含めない。UniVRM-0.53 以前ではロードがエラーになるのに注意してください")]
|
||||
[LangMsg(Languages.en, "BlendShape's Normal and Tangent will not be exported. Be aware that errors may occur during import if the model is made by UniVRM-0.53 or earlier versions")]
|
||||
BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClipから参照されないBlendShapeをエクスポートに含めない")]
|
||||
[LangMsg(Languages.en, "BlendShapes that are not referenced by BlendShapeClips will not be exported")]
|
||||
BLENDSHAPE_ONLY_CLIP_USE,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClip.Preset == Unknown のBlendShapeClipをエクスポートに含めない")]
|
||||
[LangMsg(Languages.en, "BlendShapeClip will not be exported if BlendShapeClip.Preset == Unknown")]
|
||||
BLENDSHAPE_EXCLUDE_UNKNOWN,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポートに頂点カラーを含めない")]
|
||||
[LangMsg(Languages.en, "Vertex color will not be exported")]
|
||||
REMOVE_VERTEX_COLOR,
|
||||
|
||||
[LangMsg(Languages.ja, "T-Pose にする")]
|
||||
[LangMsg(Languages.en, "Make T-Pose")]
|
||||
DO_TPOSE,
|
||||
|
||||
[LangMsg(Languages.ja, "頂点バッファをsubmeshで分割する。GLTF互換性のため。UniVRM-0.72 からロードできる。")]
|
||||
[LangMsg(Languages.en, "Divide vertex buffer by submesh。For more gltf compatibility。UniVRM-0.72 or later can load.")]
|
||||
DIVIDE_VERTEX_BUFFER,
|
||||
|
||||
[LangMsg(Languages.ja, "頂点カラーの自動削除をしない。")]
|
||||
[LangMsg(Languages.en, "Do not automatically delete vertex colors.")]
|
||||
KEEP_VERTEX_COLOR,
|
||||
}
|
||||
}
|
||||
11
Assets/VRM/Editor/Format/VRMExportOptions.cs.meta
Normal file
11
Assets/VRM/Editor/Format/VRMExportOptions.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c00e4ca5b52c8c54bb0565edadf6c7f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -7,7 +7,6 @@ namespace VRM
|
||||
[Serializable]
|
||||
public class VRMExportSettings : ScriptableObject
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// エクスポート時に強制的にT-Pose化する
|
||||
/// </summary>
|
||||
@@ -50,11 +49,18 @@ namespace VRM
|
||||
[Tooltip("Divide vertex buffer. For more gltf compatibility")]
|
||||
public bool DivideVertexBuffer = false;
|
||||
|
||||
/// <summary>
|
||||
/// Export時にVertexColorを落とさない。特別な用途で使えるように敢えて残す設定
|
||||
/// </summary>
|
||||
[Tooltip("Keep vertex color attribute")]
|
||||
public bool KeepVertexColor = false;
|
||||
|
||||
public GltfExportSettings MeshExportSettings => new GltfExportSettings
|
||||
{
|
||||
UseSparseAccessorForMorphTarget = UseSparseAccessor,
|
||||
ExportOnlyBlendShapePosition = OnlyBlendshapePosition,
|
||||
DivideVertexBuffer = DivideVertexBuffer,
|
||||
KeepVertexColor = KeepVertexColor,
|
||||
};
|
||||
|
||||
public GameObject Root { get; set; }
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UniGLTF.M17N;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace VRM
|
||||
{
|
||||
@@ -20,7 +21,7 @@ namespace VRM
|
||||
Description = desc;
|
||||
}
|
||||
|
||||
public CheckBoxProp(SerializedProperty property, Options desc) : this(property, () => Msg(desc))
|
||||
public CheckBoxProp(SerializedProperty property, VRMExportOptions desc) : this(property, () => Msg(desc))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,69 +37,23 @@ namespace VRM
|
||||
}
|
||||
}
|
||||
|
||||
CheckBoxProp m_poseFreeze;
|
||||
CheckBoxProp m_useSparseAccessor;
|
||||
CheckBoxProp m_onlyBlendShapePosition;
|
||||
CheckBoxProp m_reduceBlendShape;
|
||||
CheckBoxProp m_reduceBlendShapeClip;
|
||||
CheckBoxProp m_divideVertexBuffer;
|
||||
List<CheckBoxProp> m_checkbox_list = new List<CheckBoxProp>();
|
||||
|
||||
static string Msg(Options key)
|
||||
static string Msg(VRMExportOptions key)
|
||||
{
|
||||
return LanguageGetter.Msg(key);
|
||||
}
|
||||
|
||||
public enum Options
|
||||
{
|
||||
[LangMsg(Languages.ja, "エクスポート時に強制的にT-Pose化する。これを使わずに手動でT-Poseを作っても問題ありません")]
|
||||
[LangMsg(Languages.en, "Force T-Pose before export. Manually making T-Pose for model without enabling this is ok")]
|
||||
FORCE_T_POSE,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポート時に正規化(ヒエラルキーから回転と拡大縮小を取り除くためにベイク)する")]
|
||||
[LangMsg(Languages.en, "Model's normalization (bake to remove roation and scaling from the hierarchy)")]
|
||||
NORMALIZE,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポート時に新しいJsonSerializerを使う")]
|
||||
[LangMsg(Languages.en, "The new version of JsonSerializer for model export")]
|
||||
USE_GENERATED_SERIALIZER,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeの容量を GLTF の Sparse Accessor 機能で削減する。修正中: UniGLTF以外でロードできません")]
|
||||
[LangMsg(Languages.en, "BlendShape size can be reduced by using Sparse Accessor")]
|
||||
BLENDSHAPE_USE_SPARSE,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClipのエクスポートに法線とTangentを含めない。UniVRM-0.53 以前ではロードがエラーになるのに注意してください")]
|
||||
[LangMsg(Languages.en, "BlendShape's Normal and Tangent will not be exported. Be aware that errors may occur during import if the model is made by UniVRM-0.53 or earlier versions")]
|
||||
BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClipから参照されないBlendShapeをエクスポートに含めない")]
|
||||
[LangMsg(Languages.en, "BlendShapes that are not referenced by BlendShapeClips will not be exported")]
|
||||
BLENDSHAPE_ONLY_CLIP_USE,
|
||||
|
||||
[LangMsg(Languages.ja, "BlendShapeClip.Preset == Unknown のBlendShapeClipをエクスポートに含めない")]
|
||||
[LangMsg(Languages.en, "BlendShapeClip will not be exported if BlendShapeClip.Preset == Unknown")]
|
||||
BLENDSHAPE_EXCLUDE_UNKNOWN,
|
||||
|
||||
[LangMsg(Languages.ja, "エクスポートに頂点カラーを含めない")]
|
||||
[LangMsg(Languages.en, "Vertex color will not be exported")]
|
||||
REMOVE_VERTEX_COLOR,
|
||||
|
||||
[LangMsg(Languages.ja, "T-Pose にする")]
|
||||
[LangMsg(Languages.en, "Make T-Pose")]
|
||||
DO_TPOSE,
|
||||
|
||||
[LangMsg(Languages.ja, "頂点バッファをsubmeshで分割する。GLTF互換性のため。UniVRM-0.72 からロードできる。")]
|
||||
[LangMsg(Languages.en, "Divide vertex buffer by submesh。For more gltf compatibility。UniVRM-0.72 or later can load.")]
|
||||
DIVIDE_VERTEX_BUFFER,
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
m_poseFreeze = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), Options.NORMALIZE);
|
||||
m_useSparseAccessor = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), Options.BLENDSHAPE_USE_SPARSE);
|
||||
m_onlyBlendShapePosition = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), Options.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT);
|
||||
m_reduceBlendShape = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), Options.BLENDSHAPE_ONLY_CLIP_USE);
|
||||
m_reduceBlendShapeClip = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshapeClip)), Options.BLENDSHAPE_EXCLUDE_UNKNOWN);
|
||||
m_divideVertexBuffer = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), Options.DIVIDE_VERTEX_BUFFER);
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), VRMExportOptions.NORMALIZE));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), VRMExportOptions.BLENDSHAPE_USE_SPARSE));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), VRMExportOptions.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), VRMExportOptions.BLENDSHAPE_ONLY_CLIP_USE));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshapeClip)), VRMExportOptions.BLENDSHAPE_EXCLUDE_UNKNOWN));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), VRMExportOptions.DIVIDE_VERTEX_BUFFER));
|
||||
m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.KeepVertexColor)), VRMExportOptions.KEEP_VERTEX_COLOR));
|
||||
}
|
||||
|
||||
|
||||
@@ -112,13 +67,10 @@ namespace VRM
|
||||
|
||||
EditorGUIUtility.labelWidth = 160;
|
||||
serializedObject.Update();
|
||||
m_poseFreeze.Draw();
|
||||
m_useSparseAccessor.Draw();
|
||||
m_onlyBlendShapePosition.Draw();
|
||||
m_reduceBlendShape.Draw();
|
||||
m_reduceBlendShapeClip.Draw();
|
||||
m_divideVertexBuffer.Draw();
|
||||
|
||||
foreach (var checkbox in m_checkbox_list)
|
||||
{
|
||||
checkbox.Draw();
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ namespace VRM
|
||||
//
|
||||
// T-Pose
|
||||
//
|
||||
if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg()))
|
||||
if (GUILayout.Button(VRMExportOptions.DO_TPOSE.Msg()))
|
||||
{
|
||||
if (State.ExportRoot != null)
|
||||
{
|
||||
@@ -247,7 +247,7 @@ namespace VRM
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg() + "(unity internal)"))
|
||||
if (GUILayout.Button(VRMExportOptions.DO_TPOSE.Msg() + "(unity internal)"))
|
||||
{
|
||||
if (State.ExportRoot != null)
|
||||
{
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace UniVRM10
|
||||
{
|
||||
// indices から参照される頂点だけを蓄える
|
||||
usedIndices.Add(k);
|
||||
buffer.Push(k, positions[k], normals[k], uv[k]);
|
||||
buffer.PushVertex(k, positions[k], normals[k], uv[k]);
|
||||
if (getJointIndex != null)
|
||||
{
|
||||
var j = joints[k];
|
||||
@@ -116,7 +116,7 @@ namespace UniVRM10
|
||||
weight2 = w.z,
|
||||
weight3 = w.w,
|
||||
};
|
||||
buffer.Push(boneWeight);
|
||||
buffer.PushBoneWeight(boneWeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user