Exemple #1
0
        public Awaitable <Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture)
        {
            if (i == 0 && m_materials.Count == 0)
            {
                // dummy
                return(MaterialFactory.DefaultCreateMaterialAsync(gltf, i, getTexture));
            }

            return(MToonMaterialItem.CreateAsync(gltf, i, m_materials[i], getTexture));
        }
Exemple #2
0
 public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
 {
     if (getTexture == null)
     {
         getTexture = (_x, _y, _z) => Task.FromResult <Texture2D>(default);
Exemple #3
0
        public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, GltfParser parser, int i, GetTextureAsyncFunc getTexture)
        {
            if (getTexture == null)
            {
                getTexture = (IAwaitCaller _awaitCaller, glTF _gltf, TextureImportParam _param) => Task.FromResult <Texture2D>(null);
            }

            var material = new Material(Shader.Find(ShaderName));

            if (i < 0 || i >= parser.GLTF.materials.Count)
            {
                material.name = MaterialFactory.MaterialName(i, null);
                return(material);
            }

            var src = parser.GLTF.materials[i];

            material.name = MaterialFactory.MaterialName(i, src);
            var standardParam = default(TextureImportParam);

            if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)
            {
                if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null)
                {
                    standardParam = StandardTexture(parser, src);
                }
                if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
                {
                    var color = src.pbrMetallicRoughness.baseColorFactor;
                    material.color = (new Color(color[0], color[1], color[2], color[3])).gamma;
                }

                if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
                {
                    var param = BaseColorTexture(parser, src);
                    material.mainTexture = await getTexture(awaitCaller, parser.GLTF, param);

                    // Texture Offset and Scale
                    MaterialFactory.SetTextureOffsetAndScale(material, "_MainTex", param.Offset, param.Scale);
                }

                if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
                {
                    material.EnableKeyword("_METALLICGLOSSMAP");

                    var texture = await getTexture(awaitCaller, parser.GLTF, standardParam);

                    if (texture != null)
                    {
                        material.SetTexture(TextureImportParam.METALLIC_GLOSS_PROP, texture);
                    }

                    material.SetFloat("_Metallic", 1.0f);
                    // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
                    material.SetFloat("_GlossMapScale", 1.0f);

                    // Texture Offset and Scale
                    var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.pbrMetallicRoughness.metallicRoughnessTexture);
                    MaterialFactory.SetTextureOffsetAndScale(material, "_MetallicGlossMap", offset, scale);
                }
                else
                {
                    material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor);
                    material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
                }
            }

            if (src.normalTexture != null && src.normalTexture.index != -1)
            {
                material.EnableKeyword("_NORMALMAP");
                var param   = NormalTexture(parser, src);
                var texture = await getTexture(awaitCaller, parser.GLTF, param);

                if (texture != null)
                {
                    material.SetTexture(TextureImportParam.NORMAL_PROP, texture);
                    material.SetFloat("_BumpScale", src.normalTexture.scale);
                }

                // Texture Offset and Scale
                MaterialFactory.SetTextureOffsetAndScale(material, "_BumpMap", param.Offset, param.Scale);
            }

            if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
            {
                var texture = await getTexture(awaitCaller, parser.GLTF, standardParam);

                if (texture != null)
                {
                    material.SetTexture(TextureImportParam.OCCLUSION_PROP, texture);
                    material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength);
                }

                // Texture Offset and Scale
                var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.occlusionTexture);
                MaterialFactory.SetTextureOffsetAndScale(material, "_OcclusionMap", offset, scale);
            }

            if (src.emissiveFactor != null ||
                (src.emissiveTexture != null && src.emissiveTexture.index != -1))
            {
                material.EnableKeyword("_EMISSION");
                material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

                if (src.emissiveFactor != null && src.emissiveFactor.Length == 3)
                {
                    material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2]));
                }

                if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
                {
                    var(offset, scale) = MaterialFactory.GetTextureOffsetAndScale(src.emissiveTexture);
                    var param   = TextureFactory.CreateSRGB(parser, src.emissiveTexture.index, offset, scale);
                    var texture = await getTexture(awaitCaller, parser.GLTF, param);

                    if (texture != null)
                    {
                        material.SetTexture("_EmissionMap", texture);
                    }

                    // Texture Offset and Scale

                    MaterialFactory.SetTextureOffsetAndScale(material, "_EmissionMap", param.Offset, param.Scale);
                }
            }

            BlendMode blendMode = BlendMode.Opaque;

            // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
            switch (src.alphaMode)
            {
            case "BLEND":
                blendMode = BlendMode.Fade;
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;

            case "MASK":
                blendMode = BlendMode.Cutout;
                material.SetOverrideTag("RenderType", "TransparentCutout");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.SetFloat("_Cutoff", src.alphaCutoff);
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;

                break;

            default:     // OPAQUE
                blendMode = BlendMode.Opaque;
                material.SetOverrideTag("RenderType", "");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = -1;
                break;
            }

            material.SetFloat("_Mode", (float)blendMode);

            return(material);
        }
Exemple #4
0
        public async Task <Material> LoadAsync(MaterialDescriptor matDesc, GetTextureAsyncFunc getTexture, IAwaitCaller awaitCaller)
        {
            if (m_externalMap.TryGetValue(matDesc.SubAssetKey, out Material material))
            {
                m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, true));
                return(material);
            }

            if (getTexture == null)
            {
                getTexture = (x, y) => Task.FromResult <Texture>(null);
            }

            var shaderName = matDesc.ShaderName;

            if (String.IsNullOrEmpty(shaderName))
            {
                throw new Exception("no shader name");
            }
            if (m_fallbackShaders.TryGetValue(shaderName, out string fallback))
            {
                Debug.LogWarning($"fallback: {shaderName} => {fallback}");
                shaderName = fallback;
            }

            var shader = Shader.Find(shaderName);

            if (shader == null)
            {
                throw new Exception($"shader: {shaderName} not found");
            }

            material      = new Material(shader);
            material.name = matDesc.SubAssetKey.Name;

            foreach (var kv in matDesc.TextureSlots)
            {
                var texture = await getTexture(kv.Value, awaitCaller);

                if (texture != null)
                {
                    material.SetTexture(kv.Key, texture);
                    SetTextureOffsetAndScale(material, kv.Key, kv.Value.Offset, kv.Value.Scale);
                }
            }

            foreach (var kv in matDesc.Colors)
            {
                material.SetColor(kv.Key, kv.Value);
            }

            foreach (var kv in matDesc.Vectors)
            {
                material.SetVector(kv.Key, kv.Value);
            }

            foreach (var kv in matDesc.FloatValues)
            {
                material.SetFloat(kv.Key, kv.Value);
            }

            if (matDesc.RenderQueue.HasValue)
            {
                material.renderQueue = matDesc.RenderQueue.Value;
            }

            foreach (var action in matDesc.Actions)
            {
                action(material);
            }

            m_materials.Add(new MaterialLoadInfo(matDesc.SubAssetKey, material, false));

            return(material);
        }
Exemple #5
0
        public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
        {
            var item       = vrmMaterial;
            var shaderName = item.shader;
            var shader     = Shader.Find(shaderName);

            if (shader == null)
            {
                //
                // no shader
                //
                if (VRM_SHADER_NAMES.Contains(shaderName))
                {
                    Debug.LogErrorFormat("shader {0} not found. set Assets/VRM/Shaders/VRMShaders to Edit - project setting - Graphics - preloaded shaders", shaderName);
                }
                else
                {
                    // #if VRM_DEVELOP
                    //                     Debug.LogWarningFormat("unknown shader {0}.", shaderName);
                    // #endif
                }
                return(await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, gltf, m_index, getTexture));
            }

            //
            // restore VRM material
            //
            var material = new Material(shader);

            // use material.name, because material name may renamed in GltfParser.
            material.name        = gltf.materials[m_index].name;
            material.renderQueue = item.renderQueue;

            foreach (var kv in item.floatProperties)
            {
                material.SetFloat(kv.Key, kv.Value);
            }
            foreach (var kv in item.vectorProperties)
            {
                if (item.textureProperties.ContainsKey(kv.Key))
                {
                    // texture offset & scale
                    material.SetTextureOffset(kv.Key, new Vector2(kv.Value[0], kv.Value[1]));
                    material.SetTextureScale(kv.Key, new Vector2(kv.Value[2], kv.Value[3]));
                }
                else
                {
                    // vector4
                    var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]);
                    material.SetVector(kv.Key, v);
                }
            }
            foreach (var kv in item.textureProperties)
            {
                var param   = GetTextureParam.Create(gltf, kv.Value, kv.Key, 1, 1);
                var texture = await getTexture(awaitCaller, gltf, param);

                if (texture != null)
                {
                    material.SetTexture(kv.Key, texture);
                }
            }
            foreach (var kv in item.keywordMap)
            {
                if (kv.Value)
                {
                    material.EnableKeyword(kv.Key);
                }
                else
                {
                    material.DisableKeyword(kv.Key);
                }
            }
            foreach (var kv in item.tagMap)
            {
                material.SetOverrideTag(kv.Key, kv.Value);
            }

            if (shaderName == MToon.Utils.ShaderName)
            {
                // TODO: Material拡張にMToonの項目が追加されたら旧バージョンのshaderPropから変換をかける
                // インポート時にUniVRMに含まれるMToonのバージョンに上書きする
                material.SetFloat(MToon.Utils.PropVersion, MToon.Utils.VersionNumber);
            }

            return(material);
        }
Exemple #6
0
        public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, GltfParser parser, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
        {
            var item       = vrmMaterial;
            var shaderName = item.shader;
            var shader     = Shader.Find(shaderName);

            if (shader == null)
            {
                //
                // no shader
                //
                if (VRM_SHADER_NAMES.Contains(shaderName))
                {
                    Debug.LogErrorFormat("shader {0} not found. set Assets/VRM/Shaders/VRMShaders to Edit - project setting - Graphics - preloaded shaders", shaderName);
                }
                else
                {
                    // #if VRM_DEVELOP
                    //                     Debug.LogWarningFormat("unknown shader {0}.", shaderName);
                    // #endif
                }
                return(await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, parser, m_index, getTexture));
            }

            //
            // restore VRM material
            //
            var material = new Material(shader);

            // use material.name, because material name may renamed in GltfParser.
            material.name        = parser.GLTF.materials[m_index].name;
            material.renderQueue = item.renderQueue;

            foreach (var kv in item.floatProperties)
            {
                material.SetFloat(kv.Key, kv.Value);
            }

            var offsetScaleMap = new Dictionary <string, float[]>();

            foreach (var kv in item.vectorProperties)
            {
                if (item.textureProperties.ContainsKey(kv.Key))
                {
                    // texture offset & scale
                    offsetScaleMap.Add(kv.Key, kv.Value);
                }
                else
                {
                    // vector4
                    var v = new Vector4(kv.Value[0], kv.Value[1], kv.Value[2], kv.Value[3]);
                    material.SetVector(kv.Key, v);
                }
            }

            foreach (var kv in item.textureProperties)
            {
                var(offset, scale) = (Vector2.zero, Vector2.one);
                if (offsetScaleMap.TryGetValue(kv.Key, out float[] value))
Exemple #7
0
        public Task <Material> CreateMaterialAsync(IAwaitCaller awaitCaller, GltfParser parser, int i, GetTextureAsyncFunc getTexture)
        {
            if (i == 0 && m_materials.Count == 0)
            {
                // dummy
                return(MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, parser, i, getTexture));
            }

            return(MToonMaterialItem.CreateAsync(awaitCaller, parser, i, m_materials[i], getTexture));
        }
Exemple #8
0
 public static async Awaitable <Material> CreateAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
 {
     if (getTexture == null)
     {
         getTexture = (_x, _y) => Awaitable.FromResult <Texture2D>(default);