/// <summary> /// Called when [create assimp material]. /// </summary> /// <param name="material">The material.</param> /// <returns></returns> protected virtual global::Assimp.Material OnCreateAssimpMaterial(MaterialCore material) { var assimpMaterial = new global::Assimp.Material() { Name = string.IsNullOrEmpty(material.Name) ? $"MAT_{Interlocked.Increment(ref MaterialIndexForNoName)}" : material.Name }; if (material is PhongMaterialCore phong) { AddProperties(phong, assimpMaterial); } else if (material is PBRMaterialCore pbr) { AddProperties(pbr, assimpMaterial); } else if (material is DiffuseMaterialCore diffuse) { AddProperties(diffuse, assimpMaterial); } else if (material is ColorMaterialCore vColor) { assimpMaterial.ShadingMode = ShadingMode.Flat; } else if (material is LineMaterialCore line) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_DIFFUSE_BASE, line.LineColor.ToAssimpColor4D())); } else if (material is PointMaterialCore point) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_DIFFUSE_BASE, point.PointColor.ToAssimpColor4D())); } return(assimpMaterial); }
/// <summary> /// Adds the properties. /// </summary> /// <param name="pbr">The PBR.</param> /// <param name="assimpMaterial">The assimp material.</param> protected virtual void AddProperties(PBRMaterialCore pbr, global::Assimp.Material assimpMaterial) { assimpMaterial.ShadingMode = ShadingMode.Fresnel; assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_DIFFUSE_BASE, pbr.AlbedoColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR, pbr.AlbedoColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_EMISSIVE_BASE, pbr.EmissiveColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR, pbr.MetallicFactor)); assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_ROUGHNESS_FACTOR, pbr.RoughnessFactor)); if (pbr.AmbientOcclusionFactor != 1) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_AMBIENT, new Color4D(pbr.AmbientOcclusionFactor))); } if (pbr.ReflectanceFactor != 0) { assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, true)); assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbr.ReflectanceFactor)); } if (pbr.AlbedoColor.Alpha < 1) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.OPACITY, pbr.AlbedoColor.Alpha)); } if (pbr.AlbedoMap != null && !string.IsNullOrEmpty(pbr.AlbedoMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, pbr.AlbedoMapFilePath, TextureType.Diffuse, 0)); assimpMaterial.AddProperty(new MaterialProperty( AiMatKeys.GetFullTextureName(AiMatKeys.MAPPINGMODE_U_BASE, TextureType.Diffuse, 0), (int)ToAssimpAddressMode(pbr.SurfaceMapSampler.AddressU))); assimpMaterial.AddProperty(new MaterialProperty( AiMatKeys.GetFullTextureName(AiMatKeys.MAPPINGMODE_V_BASE, TextureType.Diffuse, 0), (int)ToAssimpAddressMode(pbr.SurfaceMapSampler.AddressV))); } if (pbr.RoughnessMetallicMap != null && !string.IsNullOrEmpty(pbr.RoughnessMetallicMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLICROUGHNESSAO_TEXTURE, pbr.RoughnessMetallicMapFilePath, TextureType.Unknown, 0)); } if (pbr.EmissiveMap != null && !string.IsNullOrEmpty(pbr.EmissiveMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, pbr.EmissiveMapFilePath, TextureType.Emissive, 0)); } if (pbr.NormalMap != null && !string.IsNullOrEmpty(pbr.NormalMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, pbr.NormalMapFilePath, TextureType.Normals, 0)); } if (pbr.DisplacementMap != null && !string.IsNullOrEmpty(pbr.DisplacementMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, pbr.DisplacementMapFilePath, TextureType.Displacement, 0)); } if (pbr.IrradianceMap != null && !string.IsNullOrEmpty(pbr.IrradianceMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, pbr.IrradianceMapFilePath, TextureType.Lightmap, 0)); } if (pbr.UVTransform.HasUVTransform) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.UVTRANSFORM_BASE, pbr.UVTransform.ToArray())); } }
/// <summary> /// Adds the properties. /// </summary> /// <param name="phong">The phong.</param> /// <param name="assimpMaterial">The assimp material.</param> protected virtual void AddProperties(PhongMaterialCore phong, global::Assimp.Material assimpMaterial) { assimpMaterial.ShadingMode = ShadingMode.Blinn; assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_DIFFUSE_BASE, phong.DiffuseColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_SPECULAR_BASE, phong.SpecularColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_REFLECTIVE_BASE, phong.ReflectiveColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_EMISSIVE_BASE, phong.EmissiveColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_AMBIENT_BASE, phong.AmbientColor.ToAssimpColor4D())); assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.SHININESS_BASE, phong.SpecularShininess)); if (phong.DiffuseColor.Alpha < 1f) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.OPACITY_BASE, phong.DiffuseColor.Alpha)); } if (phong.DiffuseMap != null && !string.IsNullOrEmpty(phong.DiffuseMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.DiffuseMapFilePath, TextureType.Diffuse, 0)); assimpMaterial.AddProperty(new MaterialProperty( AiMatKeys.GetFullTextureName(AiMatKeys.MAPPINGMODE_U_BASE, TextureType.Diffuse, 0), (int)ToAssimpAddressMode(phong.DiffuseMapSampler.AddressU))); assimpMaterial.AddProperty(new MaterialProperty( AiMatKeys.GetFullTextureName(AiMatKeys.MAPPINGMODE_V_BASE, TextureType.Diffuse, 0), (int)ToAssimpAddressMode(phong.DiffuseMapSampler.AddressV))); } if (phong.EmissiveMap != null && !string.IsNullOrEmpty(phong.EmissiveMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.EmissiveMapFilePath, TextureType.Emissive, 0)); } if (phong.NormalMap != null && !string.IsNullOrEmpty(phong.NormalMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.NormalMapFilePath, TextureType.Normals, 0)); } if (phong.DisplacementMap != null && !string.IsNullOrEmpty(phong.DisplacementMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.DisplacementMapFilePath, TextureType.Displacement, 0)); } if (phong.SpecularColorMap != null && !string.IsNullOrEmpty(phong.SpecularColorMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.SpecularColorMapFilePath, TextureType.Specular, 0)); } if (phong.DiffuseAlphaMap != null && !string.IsNullOrEmpty(phong.DiffuseAlphaMapFilePath)) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.TEXTURE_BASE, phong.DiffuseAlphaMapFilePath, TextureType.Opacity, 0)); } if (phong.UVTransform.HasUVTransform) { assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.UVTRANSFORM_BASE, phong.UVTransform.ToArray())); } }
/// <summary> /// To the phong material. /// </summary> /// <param name="material">The material.</param> /// <returns></returns> protected virtual PhongMaterialCore OnCreatePhongMaterial(global::Assimp.Material material) { var phong = new PhongMaterialCore { AmbientColor = (material.HasColorAmbient && !configuration.IgnoreAmbientColor) ? material.ColorAmbient.ToSharpDXColor4() : Color.Black, DiffuseColor = material.HasColorDiffuse ? material.ColorDiffuse.ToSharpDXColor4() : Color.White, SpecularColor = material.HasColorSpecular ? material.ColorSpecular.ToSharpDXColor4() : Color.Black, EmissiveColor = (material.HasColorEmissive && !configuration.IgnoreEmissiveColor) ? material.ColorEmissive.ToSharpDXColor4() : Color.Black, ReflectiveColor = material.HasColorReflective ? material.ColorReflective.ToSharpDXColor4() : Color.Black, SpecularShininess = material.Shininess }; if (material.HasOpacity) { var c = phong.DiffuseColor; c.Alpha = material.Opacity; phong.DiffuseColor = c; } if (material.HasTextureDiffuse) { phong.DiffuseMap = LoadTexture(material.TextureDiffuse.FilePath); phong.DiffuseMapFilePath = material.TextureDiffuse.FilePath; var desc = Shaders.DefaultSamplers.LinearSamplerClampAni1; desc.AddressU = ToDXAddressMode(material.TextureDiffuse.WrapModeU); desc.AddressV = ToDXAddressMode(material.TextureDiffuse.WrapModeV); phong.DiffuseMapSampler = desc; } if (material.HasTextureNormal) { phong.NormalMap = LoadTexture(material.TextureNormal.FilePath); phong.NormalMapFilePath = material.TextureNormal.FilePath; } else if (material.HasTextureHeight) { phong.NormalMap = LoadTexture(material.TextureHeight.FilePath); phong.NormalMapFilePath = material.TextureHeight.FilePath; } if (material.HasTextureSpecular) { phong.SpecularColorMap = LoadTexture(material.TextureSpecular.FilePath); phong.SpecularColorMapFilePath = material.TextureSpecular.FilePath; } if (material.HasTextureDisplacement) { phong.DisplacementMap = LoadTexture(material.TextureDisplacement.FilePath); phong.DisplacementMapFilePath = material.TextureDisplacement.FilePath; } if (material.HasTextureOpacity) { phong.DiffuseAlphaMap = LoadTexture(material.TextureOpacity.FilePath); phong.DiffuseAlphaMapFilePath = material.TextureOpacity.FilePath; } if (material.HasTextureEmissive) { phong.EmissiveMap = LoadTexture(material.TextureEmissive.FilePath); phong.EmissiveMapFilePath = material.TextureEmissive.FilePath; } if (material.HasNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE)) { var values = material.GetNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE).GetFloatArrayValue(); if (values != null && values.Length == 5) { phong.UVTransform = new UVTransform(values[0], new Vector2(values[1], values[2]), new Vector2(values[3], values[4])); } } return(phong); }
/// <summary> /// To the helix material. /// </summary> /// <param name="material">The material.</param> /// <returns></returns> /// <exception cref="System.NotSupportedException">Shading Mode {material.ShadingMode}</exception> protected virtual KeyValuePair <global::Assimp.Material, MaterialCore> OnCreateHelixMaterial(global::Assimp.Material material) { MaterialCore core = null; if (!material.HasShadingMode) { if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR) || material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_ROUGHNESS_FACTOR) || material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR)) { material.ShadingMode = ShadingMode.Fresnel; } else if (material.HasColorSpecular || material.HasColorDiffuse || material.HasTextureDiffuse) { material.ShadingMode = ShadingMode.Blinn; } else { material.ShadingMode = ShadingMode.Gouraud; } } var mode = material.ShadingMode; if (Configuration.ImportMaterialType != MaterialType.Auto) { switch (Configuration.ImportMaterialType) { case MaterialType.BlinnPhong: mode = ShadingMode.Blinn; break; case MaterialType.Diffuse: mode = ShadingMode.Gouraud; break; case MaterialType.PBR: mode = ShadingMode.Fresnel; break; case MaterialType.VertexColor: core = new ColorMaterialCore(); break; case MaterialType.Normal: core = new NormalMaterialCore(); break; case MaterialType.Position: core = new PositionMaterialCore(); break; } } if (core == null) { switch (mode) { case ShadingMode.Blinn: case ShadingMode.Phong: case ShadingMode.None: core = OnCreatePhongMaterial(material); break; case ShadingMode.CookTorrance: case ShadingMode.Fresnel: case ShadingMode.OrenNayar: core = OnCreatePBRMaterial(material); break; case ShadingMode.Gouraud: var diffuse = new DiffuseMaterialCore { DiffuseColor = material.ColorDiffuse.ToSharpDXColor4() }; if (material.HasOpacity) { var c = diffuse.DiffuseColor; c.Alpha = material.Opacity; diffuse.DiffuseColor = c; } if (material.HasTextureDiffuse) { diffuse.DiffuseMap = LoadTexture(material.TextureDiffuse.FilePath); diffuse.DiffuseMapFilePath = material.TextureDiffuse.FilePath; } if (material.ShadingMode == ShadingMode.Flat) { diffuse.EnableFlatShading = true; } core = diffuse; break; case ShadingMode.Flat: core = OnCreatePhongMaterial(material); if (core is PhongMaterialCore p) { p.EnableFlatShading = true; } break; default: switch (Configuration.ImportMaterialType) { case MaterialType.Position: core = new PositionMaterialCore(); break; case MaterialType.Normal: core = new NormalMaterialCore(); break; default: Log(HelixToolkit.Logger.LogLevel.Warning, $"Shading Mode is not supported:{material.ShadingMode}"); core = new DiffuseMaterialCore() { DiffuseColor = Color.Red, EnableUnLit = true }; break; } break; } } if (core != null) { core.Name = string.IsNullOrEmpty(material.Name) ? $"Material_{Interlocked.Increment(ref MaterialIndexForNoName)}" : material.Name; } return(new KeyValuePair <global::Assimp.Material, MaterialCore>(material, core)); }
/// <summary> /// To the PBR material. /// </summary> /// <param name="material">The material.</param> /// <returns></returns> protected virtual PBRMaterialCore OnCreatePBRMaterial(global::Assimp.Material material) { var pbr = new PBRMaterialCore { AlbedoColor = material.HasColorDiffuse ? material.ColorDiffuse.ToSharpDXColor4() : Color.Black, EmissiveColor = material.HasColorEmissive && !Configuration.IgnoreEmissiveColor ? material.ColorEmissive.ToSharpDXColor4() : Color.Black, }; if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR)) { pbr.AlbedoColor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_BASECOLOR_FACTOR) .GetColor4DValue().ToSharpDXColor4(); } if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR)) { pbr.MetallicFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR) .GetFloatValue(); } if (material.HasColorAmbient) { pbr.AmbientOcclusionFactor = material.ColorAmbient.R; } if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_ROUGHNESS_FACTOR)) { pbr.RoughnessFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLIC_FACTOR) .GetFloatValue(); } else if (material.HasColorSpecular && material.HasShininess) { //Ref https://github.com/assimp/assimp/blob/master/code/glTF2Exporter.cpp float specularIntensity = material.ColorSpecular.R * 0.2125f + material.ColorSpecular.G * 0.7154f + material.ColorSpecular.B * 0.0721f; float normalizedShininess = (float)Math.Sqrt(material.Shininess / 1000); normalizedShininess = Math.Min(Math.Max(normalizedShininess, 0), 1f); normalizedShininess *= specularIntensity; pbr.RoughnessFactor = 1 - normalizedShininess; } if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS)) { var hasGlossiness = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS).GetBooleanValue(); if (hasGlossiness) { if (material.HasNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR)) { pbr.ReflectanceFactor = material.GetNonTextureProperty(GLTFMatKeys.AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR).GetFloatValue(); } else if (material.HasShininess) { pbr.ReflectanceFactor = material.Shininess / 1000; } } } if (material.HasOpacity) { var c = pbr.AlbedoColor; c.Alpha = material.Opacity; pbr.AlbedoColor = c; } if (material.HasTextureDiffuse) { pbr.AlbedoMap = LoadTexture(material.TextureDiffuse.FilePath); pbr.AlbedoMapFilePath = material.TextureDiffuse.FilePath; var desc = Shaders.DefaultSamplers.LinearSamplerClampAni1; desc.AddressU = ToDXAddressMode(material.TextureDiffuse.WrapModeU); desc.AddressV = ToDXAddressMode(material.TextureDiffuse.WrapModeV); pbr.SurfaceMapSampler = desc; } if (material.HasTextureNormal) { pbr.NormalMap = LoadTexture(material.TextureNormal.FilePath); pbr.NormalMapFilePath = material.TextureNormal.FilePath; } else if (material.HasTextureHeight) { pbr.NormalMap = LoadTexture(material.TextureHeight.FilePath); pbr.NormalMapFilePath = material.TextureHeight.FilePath; } if (material.HasProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLICROUGHNESSAO_TEXTURE, TextureType.Unknown, 0)) { var t = material.GetProperty(GLTFMatKeys.AI_MATKEY_GLTF_METALLICROUGHNESSAO_TEXTURE, TextureType.Unknown, 0); pbr.RoughnessMetallicMap = LoadTexture(t.GetStringValue()); pbr.RoughnessMetallicMapFilePath = t.GetStringValue(); } else if (material.HasTextureSpecular) { pbr.RoughnessMetallicMap = LoadTexture(material.TextureSpecular.FilePath); pbr.RoughnessMetallicMapFilePath = material.TextureSpecular.FilePath; } if (material.HasTextureDisplacement) { pbr.DisplacementMap = LoadTexture(material.TextureDisplacement.FilePath); pbr.DisplacementMapFilePath = material.TextureDisplacement.FilePath; } if (material.HasTextureLightMap) { pbr.AmbientOcculsionMap = LoadTexture(material.TextureLightMap.FilePath); pbr.AmbientOcculsionMapFilePath = material.TextureLightMap.FilePath; } if (material.HasTextureEmissive) { pbr.EmissiveMap = LoadTexture(material.TextureEmissive.FilePath); pbr.EmissiveMapFilePath = material.TextureEmissive.FilePath; } if (material.HasNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE)) { var values = material.GetNonTextureProperty(AiMatKeys.UVTRANSFORM_BASE).GetFloatArrayValue(); if (values != null && values.Length == 5) { pbr.UVTransform = new UVTransform(values[0], new Vector2(values[1], values[2]), new Vector2(values[3], values[4])); } } return(pbr); }
/// <summary> /// Adds the properties. /// </summary> /// <param name="diffuse">The diffuse.</param> /// <param name="assimpMaterial">The assimp material.</param> protected virtual void AddProperties(DiffuseMaterialCore diffuse, global::Assimp.Material assimpMaterial) { assimpMaterial.ShadingMode = ShadingMode.Gouraud; assimpMaterial.AddProperty(new MaterialProperty(AiMatKeys.COLOR_DIFFUSE_BASE, diffuse.DiffuseColor.ToAssimpColor4D())); }