diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport.meta b/Assets/ExternalPlugins/CorrectNormalMapImport.meta new file mode 100644 index 00000000..db0e73fd --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e2b5a1138df59ab47bb13cfd11aecb99 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs b/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs new file mode 100644 index 00000000..6ca580d9 --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs @@ -0,0 +1,272 @@ +using System.Collections.Generic; + +namespace Yashinut.VRoid +{ + /// + /// TextureTypeを変換するときに使用する + /// + public static class ChangeTextureType + { + //DefaultからNormalMapへ変換する際に利用 + //数式が導き出せなかったので、0~255の範囲で対応する値を取得するDictionaryを定義 + public static readonly Dictionary DefaultToNormalMap = new Dictionary() + { + {0, 0}, + {1, 13}, + {2, 22}, + {3, 28}, + {4, 34}, + {5, 38}, + {6, 42}, + {7, 46}, + {8, 50}, + {9, 53}, + {10, 56}, + {11, 59}, + {12, 61}, + {13, 64}, + {14, 66}, + {15, 69}, + {16, 71}, + {17, 73}, + {18, 75}, + {19, 77}, + {20, 79}, + {21, 81}, + {22, 83}, + {23, 85}, + {24, 86}, + {25, 88}, + {26, 90}, + {27, 91}, + {28, 93}, + {29, 95}, + {30, 96}, + {31, 98}, + {32, 99}, + {33, 101}, + {34, 102}, + {35, 104}, + {36, 105}, + {37, 106}, + {38, 108}, + {39, 109}, + {40, 110}, + {41, 112}, + {42, 113}, + {43, 114}, + {44, 115}, + {45, 117}, + {46, 118}, + {47, 119}, + {48, 120}, + {49, 121}, + {50, 122}, + {51, 124}, + {52, 125}, + {53, 126}, + {54, 127}, + {55, 128}, + {56, 129}, + {57, 130}, + {58, 131}, + {59, 132}, + {60, 133}, + {61, 134}, + {62, 135}, + {63, 136}, + {64, 137}, + {65, 138}, + {66, 139}, + {67, 140}, + {68, 141}, + {69, 142}, + {70, 143}, + {71, 144}, + {72, 145}, + {73, 146}, + {74, 147}, + {75, 148}, + {76, 148}, + {77, 149}, + {78, 150}, + {79, 151}, + {80, 152}, + {81, 153}, + {82, 154}, + {83, 155}, + {84, 155}, + {85, 156}, + {86, 157}, + {87, 158}, + {88, 159}, + {89, 160}, + {90, 160}, + {91, 161}, + {92, 162}, + {93, 163}, + {94, 163}, + {95, 164}, + {96, 165}, + {97, 166}, + {98, 167}, + {99, 167}, + {100, 168}, + {101, 169}, + {102, 170}, + {103, 170}, + {104, 171}, + {105, 172}, + {106, 173}, + {107, 173}, + {108, 174}, + {109, 175}, + {110, 175}, + {111, 176}, + {112, 177}, + {113, 178}, + {114, 178}, + {115, 179}, + {116, 180}, + {117, 180}, + {118, 181}, + {119, 182}, + {120, 182}, + {121, 183}, + {122, 184}, + {123, 184}, + {124, 185}, + {125, 186}, + {126, 186}, + {127, 187}, + {128, 188}, + {129, 189}, + {130, 189}, + {131, 190}, + {132, 190}, + {133, 191}, + {134, 192}, + {135, 192}, + {136, 193}, + {137, 194}, + {138, 194}, + {139, 195}, + {140, 196}, + {141, 196}, + {142, 197}, + {143, 197}, + {144, 198}, + {145, 199}, + {146, 199}, + {147, 200}, + {148, 200}, + {149, 201}, + {150, 202}, + {151, 202}, + {152, 203}, + {153, 203}, + {154, 204}, + {155, 205}, + {156, 205}, + {157, 206}, + {158, 206}, + {159, 207}, + {160, 208}, + {161, 208}, + {162, 209}, + {163, 209}, + {164, 210}, + {165, 210}, + {166, 211}, + {167, 211}, + {168, 212}, + {169, 213}, + {170, 213}, + {171, 214}, + {172, 214}, + {173, 215}, + {174, 215}, + {175, 216}, + {176, 217}, + {177, 217}, + {178, 218}, + {179, 218}, + {180, 219}, + {181, 219}, + {182, 220}, + {183, 220}, + {184, 221}, + {185, 221}, + {186, 222}, + {187, 222}, + {188, 223}, + {189, 223}, + {190, 224}, + {191, 224}, + {192, 225}, + {193, 226}, + {194, 226}, + {195, 227}, + {196, 227}, + {197, 228}, + {198, 228}, + {199, 229}, + {200, 229}, + {201, 230}, + {202, 230}, + {203, 231}, + {204, 231}, + {205, 232}, + {206, 232}, + {207, 233}, + {208, 233}, + {209, 234}, + {210, 234}, + {211, 235}, + {212, 235}, + {213, 236}, + {214, 236}, + {215, 236}, + {216, 237}, + {217, 237}, + {218, 238}, + {219, 238}, + {220, 239}, + {221, 239}, + {222, 240}, + {223, 240}, + {224, 241}, + {225, 241}, + {226, 242}, + {227, 242}, + {228, 243}, + {229, 243}, + {230, 244}, + {231, 244}, + {232, 245}, + {233, 245}, + {234, 245}, + {235, 246}, + {236, 246}, + {237, 247}, + {238, 247}, + {239, 248}, + {240, 248}, + {241, 249}, + {242, 249}, + {243, 250}, + {244, 250}, + {245, 251}, + {246, 251}, + {247, 252}, + {248, 252}, + {249, 252}, + {250, 253}, + {251, 253}, + {252, 254}, + {253, 254}, + {254, 255}, + {255, 255}, + }; + } +} diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs.meta b/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs.meta new file mode 100644 index 00000000..f1721e41 --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/ChangeTextureType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7032b227b0e33c84baef6c989fc0d08a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs b/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs new file mode 100644 index 00000000..9f1df5dd --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace Yashinut.VRoid +{ + /// + /// VRoid出力のVRMをランタイムで読み込んだときに、NormalMapを修正するクラス + /// + public class CorrectNormalMapImport + { + + /// + /// VRoid用VRMのNormalMapを修正する + /// + /// + public static void CorrectNormalMap(GameObject vrmForVRoid) + { + var skinnedMeshRenderers = vrmForVRoid.GetComponentsInChildren(); + var materials = new List(); + + //vrmデータ内で使用されているマテリアルを全て取得する + foreach (var skinnedMesh in skinnedMeshRenderers) + { + materials.AddRange(skinnedMesh.materials); + } + + var normalTextures = new List(); + + //全てのマテリアルからNormalMapに設定されているTextureを取得する。 + foreach (var material in materials) + { + // VRM/MToonシェーダーのNormalMapを取得。 + var tex = material.GetTexture("_BumpMap"); + if (tex == null) continue; + var defaultNormalMapTexture = ToTexture2D(tex); + + Object.Destroy(tex); + //修正したNormalMapを取得 + var correctedNormalMapTexture = CorrectNormalMap(defaultNormalMapTexture); + Object.Destroy(defaultNormalMapTexture); + // 修正したNormalMapを設定 + material.SetTexture("_BumpMap", correctedNormalMapTexture); + } + } + + /// + /// TextureをTexture2Dへ変換 + /// + /// + /// + private static Texture2D ToTexture2D(Texture texture) + { + var resultTexture = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false); + var currentRenderTexture = RenderTexture.active; + var renderTexture = new RenderTexture(texture.width, texture.height, 32); + Graphics.Blit(texture, renderTexture); + RenderTexture.active = renderTexture; + resultTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); + resultTexture.Apply(); + RenderTexture.active = currentRenderTexture; + + return resultTexture; + } + + /// + /// TextureTypeがNormalMapのときと同等になるように修正 + /// + /// + /// + private static Texture2D CorrectNormalMap(Texture2D defaultNormalTexture) + { + var pixels = defaultNormalTexture.GetPixels(); + + for (var i = 0; i < pixels.Length; i++) + { + //各ピクセルごとにNormalMap用の修正を行う。 + var x = 1f; + var y = ChangeTextureType.DefaultToNormalMap[(int)(pixels[i].g * 255f)] / 255f; + var z = ChangeTextureType.DefaultToNormalMap[(int)(pixels[i].g * 255f)] / 255f; + var w = pixels[i].a; + + pixels[i] = new Color(x, y, z, w); + } + + var resultTexture = new Texture2D(defaultNormalTexture.width, defaultNormalTexture.height, TextureFormat.RGBA32, false); + resultTexture.SetPixels(pixels); + resultTexture.Apply(); + return resultTexture; + } + } +} diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs.meta b/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs.meta new file mode 100644 index 00000000..336c187a --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/CorrectNormalMapImport.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4ea80cc182740e7499236304d2b7181e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE b/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE new file mode 100644 index 00000000..12105f58 --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 yashinut + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE.meta b/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE.meta new file mode 100644 index 00000000..0665f8df --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0f136651103514545b43d58a8f5ee25c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/README.md b/Assets/ExternalPlugins/CorrectNormalMapImport/README.md new file mode 100644 index 00000000..a2f69412 --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/README.md @@ -0,0 +1,22 @@ +# CorrectNormalMapImport + +2018/09/17時点にて確認。 +VRoidから出力したVRMにおいて、UniVRMを使ってランタイムでロードすると、 +ノーマルマップのTextureTypeがdefaultのままでロードされてしまい見た目が不自然になるのを解消するスクリプト。 + +下記issueにも上がっているのでUniVRMの修正で直に治ると思いますが、とりあえずの対処として。 +https://github.com/Santarh/MToon/issues/9 + + +## 使い方 +ChangeTextureType.cs +CorrectNormalMapImport.cs +の2つのファイルをプロジェクトの任意の場所に配置します。 + +VRMファイルをロードして生成したゲームオブジェクトを +CorrectNormalMapImport.CorrectNormalMap(); +の引数に入れれば、NormalMapの生成及び再設定処理が走ります。 + +## 注意点 +全てのマテリアルのノーマルマップをピクセル毎に変換して生成しているので結構処理が重たいです。 +生成したノーマルマップは圧縮などしていないため、使いすぎるとメモリ容量を圧迫します。 diff --git a/Assets/ExternalPlugins/CorrectNormalMapImport/README.md.meta b/Assets/ExternalPlugins/CorrectNormalMapImport/README.md.meta new file mode 100644 index 00000000..b0789980 --- /dev/null +++ b/Assets/ExternalPlugins/CorrectNormalMapImport/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 394aa99c63ffcfe4c8a0264e9ed1fb74 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Calibrator.cs b/Assets/Scripts/Calibrator.cs index 11db7ac7..0a3eaa77 100644 --- a/Assets/Scripts/Calibrator.cs +++ b/Assets/Scripts/Calibrator.cs @@ -279,6 +279,17 @@ public static IEnumerator CalibrateScaled(Transform handTrackerRoot, Transform h var hscale = realHandHeight / modelHandHeight; ik.references.root.localScale = new Vector3(hscale, hscale, hscale); + //VRMモデルのコライダーがスケールについてこないため、すべて再設定 + var springBoneColiderGroups = ik.references.root.GetComponentsInChildren(); + foreach(var springBoneColiderGroup in springBoneColiderGroups) + { + foreach(var colider in springBoneColiderGroup.Colliders) + { + colider.Offset *= hscale; + colider.Radius *= hscale; + } + } + // 手のトラッカー全体のスケールを手の位置に合わせる var modelHandDistance = Vector3.Distance(ik.references.leftHand.position, ik.references.rightHand.position); diff --git a/Assets/Scripts/ControlWPFWindow.cs b/Assets/Scripts/ControlWPFWindow.cs index f67bfba1..c0c8233a 100644 --- a/Assets/Scripts/ControlWPFWindow.cs +++ b/Assets/Scripts/ControlWPFWindow.cs @@ -177,7 +177,7 @@ await mainThreadInvoker.InvokeAsync(async () => else if (e.CommandType == typeof(PipeCommands.ImportVRM)) { var d = (PipeCommands.ImportVRM)e.Data; - ImportVRM(d.Path, d.ImportForCalibration); + ImportVRM(d.Path, d.ImportForCalibration, d.EnableNormalMapFix); } else if (e.CommandType == typeof(PipeCommands.Calibrate)) @@ -485,7 +485,7 @@ private VRMData LoadVRM() public float LeftUpperArmAngle = -60f; public float RightUpperArmAngle = -60f; - private async void ImportVRM(string path, bool ImportForCalibration) + private async void ImportVRM(string path, bool ImportForCalibration, bool EnableNormalMapFix) { CurrentSettings.VRMPath = path; var context = new VRMImporterContext(UniGLTF.UnityPath.FromFullpath(path)); @@ -513,6 +513,13 @@ private async void ImportVRM(string path, bool ImportForCalibration) // ParseしたJSONをシーンオブジェクトに変換していく CurrentModel = await VRMImporter.LoadVrmAsync(context); + CurrentSettings.EnableNormalMapFix = EnableNormalMapFix; + if (EnableNormalMapFix) + { + //VRoidモデルのNormalMapテカテカを修正する + Yashinut.VRoid.CorrectNormalMapImport.CorrectNormalMap(CurrentModel); + } + //モデルのSkinnedMeshRendererがカリングされないように、すべてのオプション変更 foreach (var renderer in CurrentModel.GetComponentsInChildren(true)) { @@ -1793,6 +1800,9 @@ private class Settings [OptionalField] public float RightHandTrackerOffsetToBodySide = 0.05f; + [OptionalField] + public bool EnableNormalMapFix = true; + //初期値 [OnDeserializing()] internal void OnDeserializingMethod(StreamingContext context) @@ -1817,6 +1827,8 @@ internal void OnDeserializingMethod(StreamingContext context) RightHandTrackerOffsetToBodySide = 0.05f; PositionFixedCameraTransform = null; + + EnableNormalMapFix = true; } } @@ -1863,7 +1875,7 @@ private async void LoadSettings(bool LoadDefault = false, bool IsFirstTime = fal if (string.IsNullOrWhiteSpace(CurrentSettings.VRMPath) == false) { await server.SendCommandAsync(new PipeCommands.LoadVRMPath { Path = CurrentSettings.VRMPath }); - ImportVRM(CurrentSettings.VRMPath, false); + ImportVRM(CurrentSettings.VRMPath, false, CurrentSettings.EnableNormalMapFix); } if (CurrentSettings.BackgroundColor != null) { diff --git a/ControlWindowWPF/ControlWindowWPF/VRMImportWindow.xaml b/ControlWindowWPF/ControlWindowWPF/VRMImportWindow.xaml index f5a03b08..e2af3c42 100644 --- a/ControlWindowWPF/ControlWindowWPF/VRMImportWindow.xaml +++ b/ControlWindowWPF/ControlWindowWPF/VRMImportWindow.xaml @@ -23,7 +23,12 @@ -