/// <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> /// /// </summary> /// <param name="disposeManagedResources"></param> protected override void OnDispose(bool disposeManagedResources) { this.Material = null; TextureResources = null; SamplerResources = null; TextureBindingMap = null; SamplerBindingMap = null; OnInvalidateRenderer = null; currentPass = null; base.OnDispose(disposeManagedResources); }
/// <summary> /// Initializes a new instance of the <see cref="MaterialVariable"/> class. /// </summary> /// <param name="manager">The manager.</param> /// <param name="technique">The technique.</param> /// <param name="meshConstantBufferDesc">The Constant Buffer description</param> /// <param name="materialCore"></param> public MaterialVariable(IEffectsManager manager, IRenderTechnique technique, ConstantBufferDescription meshConstantBufferDesc, MaterialCore materialCore) { Technique = technique; EffectsManager = manager; if (materialCore != null) { material = materialCore; material.PropertyChanged += MaterialCore_PropertyChanged; } ConstantBuffer = new ConstantBufferComponent(meshConstantBufferDesc); }
public static Material ConvertToMaterial(this MaterialCore core) { if (core is PhongMaterialCore p) { return(p.ConvertToPhongMaterial()); } else { throw new NotSupportedException($"Current material core to material conversion has not been supported yet."); } }
/// <summary> /// Gets the material from node. Currently only supports <see cref="HxScene.MaterialGeometryNode"/> /// </summary> /// <param name="node">The node.</param> /// <param name="material">The material.</param> /// <returns></returns> protected virtual bool GetMaterialFromNode(HxScene.SceneNode node, out MaterialCore material) { if (node is HxScene.MaterialGeometryNode geo) { material = geo.Material; return(material != null); } else { material = null; return(false); } }
/// <summary> /// Creates the skeleton node. /// </summary> /// <param name="node">The node.</param> /// <param name="material">The material.</param> /// <param name="effectName">Name of the effect.</param> /// <param name="scale">The scale.</param> /// <returns></returns> public static BoneSkinMeshNode CreateSkeletonNode(BoneSkinMeshNode node, MaterialCore material, string effectName, float scale) { var skNode = new BoneSkinMeshNode() { Material = material, IsSkeletonNode = true, }; skNode.Geometry = BoneSkinnedMeshGeometry3D.CreateSkeletonMesh(node.Bones, scale); skNode.PostEffects = effectName; skNode.Bones = node.Bones; return(skNode); }
/// <summary> /// /// </summary> /// <param name="disposeManagedResources"></param> protected override void OnDispose(bool disposeManagedResources) { this.Material = null; for (int i = 0; i < NUMTEXTURES; ++i) { TextureResources[i]?.Detach(ModelGuid); TextureResources[i] = null; } SamplerResources = null; TextureBindingMap = null; SamplerBindingMap = null; OnInvalidateRenderer = null; base.OnDispose(disposeManagedResources); }
/// <summary> /// Initializes a new instance of the <see cref="MaterialVariable"/> class. /// </summary> /// <param name="manager">The manager.</param> /// <param name="technique">The technique.</param> /// <param name="meshMaterialConstantBufferDesc">The Constant Buffer description</param> /// <param name="materialCore"></param> public MaterialVariable(IEffectsManager manager, IRenderTechnique technique, ConstantBufferDescription meshMaterialConstantBufferDesc, MaterialCore materialCore) { Technique = technique; EffectsManager = manager; if (materialCore != null) { material = materialCore; material.PropertyChanged += MaterialCore_PropertyChanged; } materialCBDescription = meshMaterialConstantBufferDesc; if (manager != null) { storage = manager.StructArrayPool.Register(materialCBDescription.StructSize); storageId = storage.GetId(); } }
/// <summary> /// Create a Mesh, with found props /// </summary> /// <param name="positions"></param> /// <param name="textureCoordinates"></param> /// <param name="triangleIndices"></param> /// <param name="normals"></param> /// <param name="tangents"></param> /// <param name="bitangents"></param> /// <param name="material"></param> /// <param name="transforms"></param> private void CreateMesh(Vector3Collection positions, Vector2Collection textureCoordinates, IntCollection triangleIndices, List <Matrix> transforms, out Vector3Collection normals, out Vector3Collection tangents, out Vector3Collection bitangents, MaterialCore material) { ComputeNormals(positions, triangleIndices, out normals); if (textureCoordinates == null) { textureCoordinates = new Vector2Collection(); foreach (var pos in positions) { textureCoordinates.Add(Vector2.One); } } MeshBuilder.ComputeTangents(positions, normals, textureCoordinates, triangleIndices, out tangents, out bitangents); MeshGeometry3D mesh = new MeshGeometry3D() { Positions = positions, Normals = normals, TextureCoordinates = textureCoordinates, Indices = triangleIndices, Tangents = tangents, BiTangents = bitangents }; Object3D ob3d = new Object3D(); ob3d.Geometry = mesh; ob3d.Material = material; ob3d.Transform = transforms; ob3d.Name = "Default"; this.obGroup.Add(ob3d); }
/// <summary> /// Reads a triangular mesh. /// </summary> /// <param name="reader"> /// The reader. /// </param> /// <param name="chunkSize"> /// The chunk size. /// </param> private void ReadTriangularMesh(BinaryReader reader, int chunkSize) { MeshBuilder builder = new MeshBuilder(); int bytesRead = 6; Vector3Collection positions = null; IntCollection faces = null; Vector2Collection textureCoordinates = null; List <FaceSet> facesets = null; IntCollection triangleIndices = null; Vector3Collection normals = null; //Matrix matrix = Matrix.Identity; Vector3Collection tangents = null; Vector3Collection bitangents = null; List <Matrix> transforms = new List <Matrix>(); while (bytesRead < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); bytesRead += size; switch (id) { case ChunkID.TRI_VERTEXL: positions = this.ReadVertexList(reader); break; case ChunkID.TRI_FACEL1: faces = ReadFaceList(reader); size -= (faces.Count / 3 * 8) + 2; facesets = this.ReadFaceSets(reader, size - 6); break; case ChunkID.TRI_TEXCOORD: textureCoordinates = ReadTexCoords(reader); break; case ChunkID.TRI_LOCAL: transforms.Add(this.ReadTransformation(reader)); break; default: this.ReadData(reader, size - 6); break; } } if (faces == null) { //no faces defined?? return... return; } if (facesets == null || facesets.Count == 0) { triangleIndices = faces; CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, new PhongMaterial() { Name = "Gray", AmbientColor = new Color4(0.1f, 0.1f, 0.1f, 1.0f), DiffuseColor = new Color4(0.254902f, 0.254902f, 0.254902f, 1.0f), SpecularColor = new Color4(0.0225f, 0.0225f, 0.0225f, 1.0f), EmissiveColor = new Color4(0.0f, 0.0f, 0.0f, 1.0f), SpecularShininess = 12.8f, }); //Add default get and setter } else { foreach (var fm in facesets) { triangleIndices = ConvertFaceIndices(fm.Faces, faces); MaterialCore mat = null; if (this.materials.ContainsKey(fm.Name)) { mat = this.materials[fm.Name]; } CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, mat); } } }
/// <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> /// The export material. /// </summary> /// <param name="matName"> /// The mat name. /// </param> /// <param name="material"> /// The material. /// </param> private void ExportMaterial(string matName, MaterialCore material) { this.mwriter.WriteLine(string.Format("newmtl {0}", matName)); var pm = material as PhongMaterialCore; if (pm != null) { if (pm.DiffuseMap == null) { this.mwriter.WriteLine(string.Format("Kd {0}", this.ToColorString(pm.DiffuseColor))); if (this.UseDissolveForTransparency) { // Dissolve factor this.mwriter.WriteLine( string.Format(CultureInfo.InvariantCulture, "d {0:F4}", pm.DiffuseColor.Alpha)); } else { // Transparency this.mwriter.WriteLine( string.Format(CultureInfo.InvariantCulture, "Tr {0:F4}", pm.DiffuseColor.Alpha)); } } else { var textureFilename = matName + ".png"; var texturePath = Path.Combine(this.directory, textureFilename); // create .png bitmap file for the brush RenderBrush(texturePath, pm.DiffuseMap.CompressedStream); this.mwriter.WriteLine(string.Format("map_Ka {0}", textureFilename)); } } // Illumination model 1 // This is a diffuse illumination model using Lambertian shading. The // color includes an ambient constant term and a diffuse shading term for // each light source. The formula is // color = KaIa + Kd { SUM j=1..ls, (N * Lj)Ij } int illum = 1; // Lambertian if (pm != null) { this.mwriter.WriteLine( string.Format( "Ks {0}", this.ToColorString(pm.DiffuseMap == null ? pm.SpecularColor : new Color4(0.2f, 0.2f, 0.2f, 1.0f)))); // Illumination model 2 // This is a diffuse and specular illumination model using Lambertian // shading and Blinn's interpretation of Phong's specular illumination // model (BLIN77). The color includes an ambient constant term, and a // diffuse and specular shading term for each light source. The formula // is: color = KaIa + Kd { SUM j=1..ls, (N*Lj)Ij } + Ks { SUM j=1..ls, ((H*Hj)^Ns)Ij } illum = 2; // Specifies the specular exponent for the current material. This defines the focus of the specular highlight. // "exponent" is the value for the specular exponent. A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000. this.mwriter.WriteLine(string.Format(CultureInfo.InvariantCulture, "Ns {0:F4}", pm.SpecularShininess)); } // roughness this.mwriter.WriteLine(string.Format("Ns {0}", 2)); // Optical density (index of refraction) this.mwriter.WriteLine(string.Format("Ni {0}", 1)); // Transmission filter this.mwriter.WriteLine(string.Format("Tf {0} {1} {2}", 1, 1, 1)); // Illumination model // Illumination Properties that are turned on in the // model Property Editor // 0 Color on and Ambient off // 1 Color on and Ambient on // 2 Highlight on // 3 Reflection on and Ray trace on // 4 Transparency: Glass on // Reflection: Ray trace on // 5 Reflection: Fresnel on and Ray trace on // 6 Transparency: Refraction on // Reflection: Fresnel off and Ray trace on // 7 Transparency: Refraction on // Reflection: Fresnel on and Ray trace on // 8 Reflection on and Ray trace off // 9 Transparency: Glass on // Reflection: Ray trace off // 10 Casts shadows onto invisible surfaces this.mwriter.WriteLine(string.Format("illum {0}", illum)); }
/// <summary> /// Creates the skeleton node. /// </summary> /// <param name="material">The material.</param> /// <param name="effectName">Name of the effect.</param> /// <param name="scale">The scale.</param> /// <returns></returns> public BoneSkinMeshNode CreateSkeletonNode(MaterialCore material, string effectName, float scale = 0.1f) { return(CreateSkeletonNode(this, material, effectName, scale)); }
/// <summary> /// Initializes a new instance of the <see cref="Material"/> class. /// </summary> /// <param name="core">The core.</param> public Material(MaterialCore core) { this.core = core; Name = core.Name; }