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); }
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); }
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); }