private PbrMetallicRoughness ExportPBRMetallicRoughness(UnityEngine.Material material)
        {
            var pbr = new PbrMetallicRoughness();

            if (material.HasProperty("_Color"))
            {
                pbr.BaseColorFactor = material.GetColor("_Color").ToNumericsColorRaw();
            }

            if (material.HasProperty("_MainTex"))
            {
                var mainTex = material.GetTexture("_MainTex");

                if (mainTex != null)
                {
                    pbr.BaseColorTexture = ExportTextureInfo(mainTex);
                    ExportTextureTransform(pbr.BaseColorTexture, material, "_MainTex");
                }
            }

            if (material.HasProperty("_Metallic"))
            {
                pbr.MetallicFactor = material.GetFloat("_Metallic");
            }

            if (material.HasProperty("_Roughness"))
            {
                pbr.RoughnessFactor = material.GetFloat("_Roughness");
            }
            else if (material.HasProperty("_Glossiness"))
            {
                pbr.RoughnessFactor = 1 - material.GetFloat("_Glossiness");
            }

            if (material.HasProperty("_MetallicRoughnessMap"))
            {
                var mrTex = material.GetTexture("_MetallicRoughnessMap");

                if (mrTex != null)
                {
                    pbr.MetallicRoughnessTexture = ExportTextureInfo(mrTex);
                    ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicRoughnessMap");
                }
            }
            else if (material.HasProperty("_MetallicGlossMap"))
            {
                var mgTex = material.GetTexture("_MetallicGlossMap");

                if (mgTex != null)
                {
                    pbr.MetallicRoughnessTexture = ExportTextureInfo(mgTex);
                    ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicGlossMap");
                }
            }

            return(pbr);
        }
Esempio n. 2
0
        public GltfModel writeToGLtf()
        {
            GltfModel _model = new GltfModel();

            #region "asset"
            _model.Asset.Generator = "3dxmlToGLTF";
            _model.Asset.Version   = "2.0";
            #endregion

            #region "scene" and "scenes"
            // 为 "scene" 添加 0
            _model.Scene = 0;
            // 为 "scenes" 添加 根节点 nodes
            Scene scene = new Scene();
            scene.Name = nameofscene;
            scene.Nodes.Add(0);
            _model.Scenes.Add(scene);
            #endregion

            #region "nodes"  有待添加
            Node node = new Node();
            node.Mesh = 0;
            _model.Nodes.Add(node);
            #endregion

            #region "meshes"
            Mesh      mesh      = new Mesh();
            Primitive primitive = new Primitive();
            var       atts      = new Dictionary <string, int>();
            atts.Add("POSITION", 1);
            //atts.Add("NORMAL", 2);
            primitive.Attributes = atts;
            primitive.Indices    = 0;
            primitive.Material   = 0;
            primitive.Mode       = Mode.Triangles;
            mesh.Primitives.Add(primitive);

            _model.Meshes.Add(mesh);
            #endregion

            #region "materials"
            Material             material             = new Material();
            PbrMetallicRoughness pbrMetallicRoughness = new PbrMetallicRoughness();
            pbrMetallicRoughness.BaseColorFactor = new double[] { 0.1, 0.1, 0.1, 1 };
            pbrMetallicRoughness.MetallicFactor  = 0.0;
            material.PbrMetallicRoughness        = pbrMetallicRoughness;
            material.DoubleSided = true;
            material.Name        = "color";
            material.AlphaMode   = AlphaMode.OPAQUE;
            _model.Materials.Add(material);
            #endregion

            #region "buffers"
            List <byte> bytes = new List <byte>();
            foreach (int e in this.indexes)
            {
                byte[] b = BitConverter.GetBytes(e);
                foreach (byte elementofb in b)
                {
                    bytes.Add(elementofb);
                }
            }
            //若索引为int,顶点位置为float,则不用去判断是否需要添加0字节以达到整除的目的,因为这种情况下必定整除
            foreach (float e in this.positions)
            {
                byte[] b = BitConverter.GetBytes(e);
                foreach (byte elementofb in b)
                {
                    bytes.Add(elementofb);
                }
            }

            byte[] byteflow = bytes.ToArray();

            Arctron.Gltf.Buffer buffer = new Arctron.Gltf.Buffer();
            buffer.ByteLength = byteflow.Length;
            buffer.Uri        = "data:application/octet-stream;base64," + Convert.ToBase64String(byteflow); //byte数组转化为Base64
            _model.Buffers.Add(buffer);
            #endregion

            #region  "bufferViews"
            //索引段
            BufferView bufferView0 = new BufferView();
            bufferView0.Buffer     = 0;
            bufferView0.ByteOffset = 0;
            bufferView0.ByteLength = indexes.Count * sizeof(int);
            bufferView0.Target     = 34963;
            //数据段
            BufferView bufferView1 = new BufferView();
            bufferView1.Buffer     = 0;
            bufferView1.ByteOffset = indexes.Count * sizeof(int);
            bufferView1.ByteLength = positions.Count * sizeof(float);
            bufferView1.Target     = 34962;
            //添加到gltf模型中
            _model.BufferViews.Add(bufferView0);
            _model.BufferViews.Add(bufferView1);
            #endregion

            #region "accessors"
            //索引段
            int index_num  = indexes.Count;
            int vertex_num = positions.Count / 3;

            Accessor accessor0 = new Accessor();
            accessor0.BufferView    = 0;
            accessor0.ByteOffset    = 0;
            accessor0.ComponentType = 5125;
            accessor0.Count         = index_num;
            accessor0.Type          = AccessorType.SCALAR;
            double[] min = new double[1] {
                0
            };
            accessor0.Min = min;
            double[] max = new double[1] {
                vertex_num - 1
            };
            accessor0.Max = max;
            //顶点位置
            Accessor accessor1 = new Accessor();
            accessor1.BufferView    = 1;
            accessor1.ByteOffset    = 0;
            accessor1.ComponentType = 5126;
            accessor1.Count         = vertex_num;
            accessor1.Type          = AccessorType.VEC3;
            accessor1.Min           = accessor1.GetMinVec(positions);
            accessor1.Max           = accessor1.GetMaxVec(positions);
            _model.Accessors.Add(accessor0);
            _model.Accessors.Add(accessor1);
            #endregion

            #region "textures"

            #endregion

            #region "images"

            #endregion

            #region "samplers"

            #endregion

            _model.Clean();



            return(_model);
        }
        static bool ExportPbrMetallicRoughness(UnityEngine.Material material, out PbrMetallicRoughness pbr, IGltfWritable gltf, ICodeLogger logger)
        {
            var success = true;

            pbr = new PbrMetallicRoughness {
                metallicFactor = 0, roughnessFactor = 1.0f
            };

            if (material.HasProperty(k_BaseColor))
            {
                pbr.baseColor = material.GetColor(k_BaseColor);
            }
            else
            if (material.HasProperty(k_Color))
            {
                pbr.baseColor = material.GetColor(k_Color);
            }

            if (material.HasProperty(k_TintColor))
            {
                //particles use _TintColor instead of _Color
                float white = 1;
                if (material.HasProperty(k_Color))
                {
                    var c = material.GetColor(k_Color);
                    white = (c.r + c.g + c.b) / 3.0f; //multiply alpha by overall whiteness of TintColor
                }

                pbr.baseColor = material.GetColor(k_TintColor) * white;
            }

            if (material.HasProperty(k_MainTex) || material.HasProperty("_BaseMap"))
            {
                // TODO if additive particle, render black into alpha
                // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+
                var mainTexProperty = material.HasProperty(k_BaseMap) ? k_BaseMap : k_MainTex;
                var mainTex         = material.GetTexture(mainTexProperty);

                if (mainTex)
                {
                    if (mainTex is Texture2D)
                    {
                        pbr.baseColorTexture = ExportTextureInfo(mainTex, TextureMapType.Main, gltf);
                        ExportTextureTransform(pbr.baseColorTexture, material, mainTexProperty, gltf);
                    }
                    else
                    {
                        logger?.Error(LogCode.TextureInvalidType, "main", material.name);
                        success = false;
                    }
                }
            }

            if (material.HasProperty(k_Metallic) && !material.IsKeywordEnabled("_METALLICGLOSSMAP"))
            {
                pbr.metallicFactor = material.GetFloat(k_Metallic);
            }

            if (material.HasProperty(k_Glossiness) || material.HasProperty(k_Smoothness))
            {
                var   smoothnessPropertyName = material.HasProperty(k_Smoothness) ?  k_Smoothness : k_Glossiness;
                var   metallicGlossMap       = material.GetTexture(k_MetallicGlossMap);
                float smoothness             = material.GetFloat(smoothnessPropertyName);
                // legacy workaround: the UnityGLTF shaders misuse k_Glossiness as roughness but don't have a keyword for it.
                if (material.shader.name.Equals("GLTF/PbrMetallicRoughness", StringComparison.Ordinal))
                {
                    smoothness = 1 - smoothness;
                }
                pbr.roughnessFactor = (metallicGlossMap != null && material.HasProperty(k_GlossMapScale))
                                        ? material.GetFloat(k_GlossMapScale)
                                        : 1f - smoothness;
            }

            if (material.HasProperty(k_MetallicGlossMap))
            {
                var mrTex = material.GetTexture(k_MetallicGlossMap);

                if (mrTex != null)
                {
                    if (mrTex is Texture2D)
                    {
                        // pbr.metallicRoughnessTexture = ExportTextureInfo(mrTex, TextureMapType.MetallicGloss);
                        // if (material.IsKeywordEnabled("_METALLICGLOSSMAP"))
                        //  pbr.metallicFactor = 1.0f;
                        // ExportTextureTransform(pbr.MetallicRoughnessTexture, material, k_MetallicGlossMap);
                    }
                    else
                    {
                        logger?.Error(LogCode.TextureInvalidType, "metallic/gloss", material.name);
                        success = false;
                    }
                }
            }

            return(success);
        }
Esempio n. 4
0
        static bool ExportPbrMetallicRoughness(
            UnityEngine.Material uMaterial,
            Material material,
            IGltfWritable gltf,
            ICodeLogger logger
            )
        {
            var success = true;
            var pbr     = new PbrMetallicRoughness {
                metallicFactor = 0, roughnessFactor = 1.0f
            };

            MaskMapImageExport ormImageExport = null;

            if (uMaterial.IsKeywordEnabled(k_KeywordMaskMap) && uMaterial.HasProperty(k_MaskMap))
            {
                var maskMap = uMaterial.GetTexture(k_MaskMap) as Texture2D;
                if (maskMap != null)
                {
                    ormImageExport = new MaskMapImageExport(maskMap);
                    if (AddImageExport(gltf, ormImageExport, out var ormTextureId))
                    {
                        // TODO: smartly detect if metallic roughness channels are used and not create the
                        // texture info if not.
                        pbr.metallicRoughnessTexture = new TextureInfo {
                            index = ormTextureId
                        };
                        ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, k_MaskMap, gltf);

                        // TODO: smartly detect if occlusion channel is used and not create the
                        // texture info if not.
                        material.occlusionTexture = new OcclusionTextureInfo {
                            index = ormTextureId
                        };
                        if (uMaterial.HasProperty(k_AORemapMin))
                        {
                            var occMin = uMaterial.GetFloat(k_AORemapMin);
                            material.occlusionTexture.strength = math.clamp(1 - occMin, 0, 1);
                            var occMax = uMaterial.GetFloat(k_AORemapMax);
                            if (occMax < 1f)
                            {
                                // TODO: remap texture values
                                logger?.Warning(LogCode.RemapUnsupported, "AO");
                            }
                        }
                    }
                }
            }

            if (uMaterial.HasProperty(k_BaseColor))
            {
                pbr.baseColor = uMaterial.GetColor(k_BaseColor);
            }
            else
            if (uMaterial.HasProperty(k_Color))
            {
                pbr.baseColor = uMaterial.GetColor(k_Color);
            }

            if (uMaterial.HasProperty(k_BaseColorMap))
            {
                // TODO if additive particle, render black into alpha
                // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+
                var mainTex = uMaterial.GetTexture(k_BaseColorMap);

                if (mainTex)
                {
                    if (mainTex is Texture2D)
                    {
                        pbr.baseColorTexture = ExportTextureInfo(mainTex, gltf);
                        ExportTextureTransform(pbr.baseColorTexture, uMaterial, k_BaseColorMap, gltf);
                    }
                    else
                    {
                        logger?.Error(LogCode.TextureInvalidType, "main", uMaterial.name);
                        success = false;
                    }
                }
            }

            if (uMaterial.HasProperty(k_Metallic))
            {
                pbr.metallicFactor = uMaterial.GetFloat(k_Metallic);
            }

            if (ormImageExport != null && uMaterial.HasProperty(k_SmoothnessRemapMax))
            {
                pbr.roughnessFactor = uMaterial.GetFloat(k_SmoothnessRemapMax);
                if (uMaterial.HasProperty(k_SmoothnessRemapMin) && uMaterial.GetFloat(k_SmoothnessRemapMin) > 0)
                {
                    logger?.Warning(LogCode.RemapUnsupported, "Smoothness");
                }
            }
            else
            if (uMaterial.HasProperty(k_Smoothness))
            {
                pbr.roughnessFactor = 1f - uMaterial.GetFloat(k_Smoothness);
            }

            material.pbrMetallicRoughness = pbr;
            return(success);
        }
        static bool ExportPbrMetallicRoughness(
            UnityEngine.Material uMaterial,
            Material material,
            int mainTexProperty,
            OrmImageExport ormImageExport,
            IGltfWritable gltf,
            ICodeLogger logger
            )
        {
            var success = true;
            var pbr     = new PbrMetallicRoughness {
                metallicFactor = 0, roughnessFactor = 1.0f
            };

            var hasAlphaSmoothness = uMaterial.IsKeywordEnabled(k_KeywordSmoothnessTextureAlbedoChannelA);

            if (uMaterial.HasProperty(k_BaseColor))
            {
                pbr.baseColor = uMaterial.GetColor(k_BaseColor);
            }
            else
            if (uMaterial.HasProperty(k_Color))
            {
                pbr.baseColor = uMaterial.GetColor(k_Color);
            }

            if (uMaterial.HasProperty(k_TintColor))
            {
                //particles use _TintColor instead of _Color
                float white = 1;
                if (uMaterial.HasProperty(k_Color))
                {
                    var c = uMaterial.GetColor(k_Color);
                    white = (c.r + c.g + c.b) / 3.0f; //multiply alpha by overall whiteness of TintColor
                }

                pbr.baseColor = uMaterial.GetColor(k_TintColor) * white;
            }

            if (uMaterial.HasProperty(mainTexProperty))
            {
                // TODO if additive particle, render black into alpha
                // TODO use private Material.GetFirstPropertyNameIdByAttribute here, supported from 2020.1+
                var mainTex = uMaterial.GetTexture(mainTexProperty);

                if (mainTex)
                {
                    if (mainTex is Texture2D)
                    {
                        pbr.baseColorTexture = ExportTextureInfo(
                            mainTex,
                            gltf,
                            // Force RGB for the baseColor, so that the alpha (which is smoothness)
                            // is not used for alpha-opacity
                            hasAlphaSmoothness
                                ? ImageExportBase.Format.Jpg
                                : ImageExportBase.Format.Unknown
                            );
                        if (pbr.baseColorTexture != null)
                        {
                            ExportTextureTransform(pbr.baseColorTexture, uMaterial, mainTexProperty, gltf);
                        }
                    }
                    else
                    {
                        logger?.Error(LogCode.TextureInvalidType, "main", uMaterial.name);
                        success = false;
                    }
                }
            }

            if (uMaterial.HasProperty(k_Metallic) && !HasMetallicGlossMap(uMaterial))
            {
                pbr.metallicFactor = uMaterial.GetFloat(k_Metallic);
            }

            if (uMaterial.HasProperty(k_Glossiness) || uMaterial.HasProperty(k_Smoothness))
            {
                var smoothnessPropId = uMaterial.HasProperty(k_Smoothness) ?  k_Smoothness : k_Glossiness;
                var metallicGlossMap = uMaterial.HasProperty(k_MetallicGlossMap) ? uMaterial.GetTexture(k_MetallicGlossMap) : null;
                var smoothness       = uMaterial.GetFloat(smoothnessPropId);
                pbr.roughnessFactor = (metallicGlossMap != null || hasAlphaSmoothness) && uMaterial.HasProperty(k_GlossMapScale)
                    ? uMaterial.GetFloat(k_GlossMapScale)
                    : 1f - smoothness;
            }

            if (uMaterial.HasProperty(k_MetallicGlossMap))
            {
                var mrTex = uMaterial.GetTexture(k_MetallicGlossMap);
                if (mrTex != null)
                {
                    if (mrTex is Texture2D mrTex2d)
                    {
                        pbr.metallicRoughnessTexture = pbr.metallicRoughnessTexture ?? new TextureInfo();
                        ormImageExport.SetMetalGlossTexture(mrTex2d);
                        if (HasMetallicGlossMap(uMaterial))
                        {
                            pbr.metallicFactor = 1.0f;
                        }
                        ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, k_MetallicGlossMap, gltf);
                    }
                    else
                    {
                        logger?.Error(LogCode.TextureInvalidType, "metallic/gloss", uMaterial.name);
                        success = false;
                    }
                }
            }

            if (uMaterial.IsKeywordEnabled(k_KeywordSmoothnessTextureAlbedoChannelA))
            {
                var smoothnessTex = uMaterial.GetTexture(mainTexProperty) as Texture2D;
                if (smoothnessTex != null)
                {
                    pbr.metallicRoughnessTexture = pbr.metallicRoughnessTexture ?? new TextureInfo();
                    ormImageExport.SetSmoothnessTexture(smoothnessTex);
                    ExportTextureTransform(pbr.metallicRoughnessTexture, uMaterial, mainTexProperty, gltf);
                }
            }

            material.pbrMetallicRoughness = pbr;
            return(success);
        }