| | 1 | | using DCL.Helpers; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using UnityEngine; |
| | 4 | | using UnityEngine.Rendering; |
| | 5 | |
|
| | 6 | | namespace MainScripts.DCL.Components.Avatar.VRMExporter |
| | 7 | | { |
| | 8 | | public static class VRMExporterUtils |
| | 9 | | { |
| 0 | 10 | | private static readonly int _Color = Shader.PropertyToID("_Color"); |
| 0 | 11 | | private static readonly int _BaseColor = Shader.PropertyToID("_BaseColor"); |
| 0 | 12 | | private static readonly int _ShadeTexture = Shader.PropertyToID("_ShadeTexture"); |
| 0 | 13 | | private static readonly int _ShadeColor = Shader.PropertyToID("_ShadeColor"); |
| 0 | 14 | | private static readonly int _CullMode = Shader.PropertyToID("_CullMode"); |
| 0 | 15 | | private static readonly int _Cull = Shader.PropertyToID("_Cull"); |
| 0 | 16 | | private static readonly int _EmissionColor = Shader.PropertyToID("_EmissionColor"); |
| 0 | 17 | | private static readonly int _EmissionMap = Shader.PropertyToID("_EmissionMap"); |
| 0 | 18 | | private static readonly int _BlendMode = Shader.PropertyToID("_BlendMode"); |
| 0 | 19 | | private static readonly int _SrcBlend = Shader.PropertyToID("_SrcBlend"); |
| 0 | 20 | | private static readonly int _DstBlend = Shader.PropertyToID("_DstBlend"); |
| 0 | 21 | | private static readonly int _ZWrite = Shader.PropertyToID("_ZWrite"); |
| 0 | 22 | | private static readonly int _Cutoff = Shader.PropertyToID("_Cutoff"); |
| 0 | 23 | | private static readonly int _AlphaToMask = Shader.PropertyToID("_AlphaToMask"); |
| 0 | 24 | | private static readonly int _EyesTexture = Shader.PropertyToID("_EyesTexture"); |
| 0 | 25 | | private static readonly int _BaseMap = Shader.PropertyToID("_BaseMap"); |
| | 26 | | private const string _ALPHATEST_ON = "_ALPHATEST_ON"; |
| | 27 | | private const string _ALPHABLEND_ON = "_ALPHABLEND_ON"; |
| | 28 | | private const string _ALPHAPREMULTIPLY_ON = "_ALPHAPREMULTIPLY_ON"; |
| | 29 | | private const string RenderType = "RenderType"; |
| | 30 | | private const string Opaque = "Opaque"; |
| | 31 | | private const string TransparentCutout = "TransparentCutout"; |
| | 32 | | private const string Transparent = "Transparent"; |
| | 33 | |
|
| | 34 | | public static Dictionary<string, Transform> CacheFBXBones(Transform root) |
| | 35 | | { |
| | 36 | | void GatherBonesRecursively(Transform current, Dictionary<string, Transform> bones) |
| | 37 | | { |
| 0 | 38 | | bones.Add(current.name, current); |
| | 39 | |
|
| 0 | 40 | | foreach (Transform child in current) |
| 0 | 41 | | GatherBonesRecursively(child, bones); |
| 0 | 42 | | } |
| | 43 | |
|
| 0 | 44 | | var bones = new Dictionary<string, Transform>(); |
| 0 | 45 | | GatherBonesRecursively(root, bones); |
| 0 | 46 | | return bones; |
| | 47 | | } |
| | 48 | |
|
| | 49 | | public static SkinnedMeshRenderer CloneSmr(GameObject container, SkinnedMeshRenderer source) |
| | 50 | | { |
| 0 | 51 | | var smr = container.AddComponent<SkinnedMeshRenderer>(); |
| 0 | 52 | | smr.sharedMesh = source.sharedMesh; |
| 0 | 53 | | smr.quality = source.quality; |
| 0 | 54 | | smr.updateWhenOffscreen = source.updateWhenOffscreen; |
| 0 | 55 | | return smr; |
| | 56 | | } |
| | 57 | |
|
| | 58 | | public static void ConvertEyesMaterial(Material fromMaterial, Texture mainTex, Material outMaterial) |
| | 59 | | { |
| 0 | 60 | | if (fromMaterial == null) |
| 0 | 61 | | return; |
| | 62 | |
|
| 0 | 63 | | outMaterial.name = fromMaterial.name; |
| | 64 | |
|
| | 65 | | // Set main textures and colors |
| 0 | 66 | | outMaterial.mainTexture = mainTex; |
| 0 | 67 | | outMaterial.SetFloat(_Cutoff, outMaterial.GetFloat(_Cutoff)); |
| | 68 | |
|
| | 69 | | // Set render queue and blend mode |
| 0 | 70 | | outMaterial.renderQueue = fromMaterial.renderQueue; |
| 0 | 71 | | SetBlendMode(outMaterial, 1); |
| 0 | 72 | | } |
| | 73 | |
|
| | 74 | | public static void ConvertLitMaterial(Material fromMaterial, Material outMaterial) |
| | 75 | | { |
| | 76 | | const int EMISSIVE_FACTOR = 20; |
| | 77 | |
|
| 0 | 78 | | if (fromMaterial == null) |
| 0 | 79 | | return; |
| | 80 | |
|
| 0 | 81 | | var mainTex = fromMaterial.mainTexture; |
| | 82 | |
|
| 0 | 83 | | outMaterial.name = fromMaterial.name; |
| | 84 | |
|
| | 85 | | // Set main textures and colors |
| 0 | 86 | | outMaterial.mainTexture = mainTex; |
| 0 | 87 | | outMaterial.SetTexture(_ShadeTexture, mainTex); |
| | 88 | |
|
| 0 | 89 | | var baseColor = fromMaterial.GetColor(_BaseColor); |
| 0 | 90 | | outMaterial.SetColor(_Color, baseColor); |
| 0 | 91 | | outMaterial.SetColor(_ShadeColor, baseColor); |
| | 92 | |
|
| 0 | 93 | | outMaterial.SetColor(_EmissionColor, fromMaterial.GetColor(_EmissionColor) * EMISSIVE_FACTOR); |
| 0 | 94 | | outMaterial.SetFloat(_CullMode, fromMaterial.GetFloat(_Cull)); |
| 0 | 95 | | if(fromMaterial.HasProperty(_EmissionMap)) |
| 0 | 96 | | outMaterial.SetTexture(_EmissionMap, fromMaterial.GetTexture(_EmissionMap)); |
| | 97 | |
|
| | 98 | | // Set render queue and blend mode |
| 0 | 99 | | outMaterial.renderQueue = fromMaterial.renderQueue; |
| 0 | 100 | | if (fromMaterial.renderQueue <= 2450) |
| 0 | 101 | | SetBlendMode(outMaterial, 0); |
| 0 | 102 | | else if (fromMaterial.renderQueue < 3000) |
| 0 | 103 | | SetBlendMode(outMaterial, 1); |
| | 104 | | else |
| 0 | 105 | | SetBlendMode(outMaterial, 2); |
| 0 | 106 | | } |
| | 107 | |
|
| | 108 | | private static void SetBlendMode(Material material, int value) |
| | 109 | | { |
| 0 | 110 | | if (value == 0) |
| | 111 | | { |
| 0 | 112 | | material.SetFloat(_BlendMode, 0); |
| | 113 | |
|
| 0 | 114 | | material.SetOverrideTag(RenderType, Opaque); |
| 0 | 115 | | material.SetInt(_SrcBlend, (int)BlendMode.One); |
| 0 | 116 | | material.SetInt(_DstBlend, (int)BlendMode.Zero); |
| 0 | 117 | | material.SetInt(_ZWrite, 1); |
| 0 | 118 | | material.SetInt(_AlphaToMask, 0); |
| 0 | 119 | | material.DisableKeyword(_ALPHATEST_ON); |
| 0 | 120 | | material.DisableKeyword(_ALPHABLEND_ON); |
| 0 | 121 | | material.DisableKeyword(_ALPHAPREMULTIPLY_ON); |
| | 122 | | } |
| 0 | 123 | | else if (value == 1) |
| | 124 | | { |
| 0 | 125 | | material.SetFloat(_BlendMode, 1); |
| | 126 | |
|
| 0 | 127 | | material.SetOverrideTag(RenderType, TransparentCutout); |
| 0 | 128 | | material.SetInt(_SrcBlend, (int)BlendMode.One); |
| 0 | 129 | | material.SetInt(_DstBlend, (int)BlendMode.Zero); |
| 0 | 130 | | material.SetInt(_ZWrite, 1); |
| 0 | 131 | | material.SetInt(_AlphaToMask, 1); |
| 0 | 132 | | material.EnableKeyword(_ALPHATEST_ON); |
| 0 | 133 | | material.DisableKeyword(_ALPHABLEND_ON); |
| 0 | 134 | | material.DisableKeyword(_ALPHAPREMULTIPLY_ON); |
| | 135 | | } |
| | 136 | | else |
| | 137 | | { |
| 0 | 138 | | material.SetFloat(_BlendMode, 2); |
| | 139 | |
|
| 0 | 140 | | material.SetOverrideTag(RenderType, Transparent); |
| 0 | 141 | | material.SetInt(_SrcBlend, (int)BlendMode.SrcAlpha); |
| 0 | 142 | | material.SetInt(_DstBlend, (int)BlendMode.OneMinusSrcAlpha); |
| 0 | 143 | | material.SetInt(_ZWrite, 0); |
| 0 | 144 | | material.SetInt(_AlphaToMask, 0); |
| 0 | 145 | | material.DisableKeyword(_ALPHATEST_ON); |
| 0 | 146 | | material.EnableKeyword(_ALPHABLEND_ON); |
| 0 | 147 | | material.DisableKeyword(_ALPHAPREMULTIPLY_ON); |
| | 148 | | } |
| 0 | 149 | | } |
| | 150 | |
|
| 0 | 151 | | public static Texture2D ExtractComposedEyesTexture(Material source) => ExtractComposedTexture(source, source.Get |
| 0 | 152 | | public static Texture2D ExtractComposedBaseMapTexture(Material source) => ExtractComposedTexture(source, source. |
| | 153 | |
|
| | 154 | | private static Texture2D ExtractComposedTexture(Material source, Texture sourceMainTex) |
| | 155 | | { |
| 0 | 156 | | float cutoff = source.GetFloat(_Cutoff); |
| 0 | 157 | | source.SetFloat(_Cutoff, 0.0f); |
| 0 | 158 | | var rt = RenderTexture.GetTemporary(sourceMainTex.width, sourceMainTex.height); |
| 0 | 159 | | Graphics.Blit(sourceMainTex, rt, source); |
| 0 | 160 | | source.SetFloat(_Cutoff, cutoff); |
| | 161 | |
|
| 0 | 162 | | Texture2D tex = new Texture2D(sourceMainTex.width, sourceMainTex.height); |
| 0 | 163 | | tex.ReadPixels(new Rect(0,0, tex.width, tex.height), 0, 0); |
| 0 | 164 | | tex.Apply(); |
| 0 | 165 | | return tex; |
| | 166 | | } |
| | 167 | | } |
| | 168 | | } |