public static Component_Material CreateMaterial( Component materialsGroup, MaterialData data ) { //create material var material = materialsGroup.CreateComponent<Component_Material>( enabled: false ); material.Name = data.Name; material.ShadingModel = data.ShadingModel; material.TwoSided = data.TwoSided; if( !string.IsNullOrEmpty( data.OpacityTexture ) ) material.BlendMode = Component_Material.BlendModeEnum.Masked; //create shader graph Component_FlowGraph graph; { graph = material.CreateComponent<Component_FlowGraph>(); graph.Name = material.Name + " shader graph"; graph.Specialization = ReferenceUtility.MakeReference<Component_FlowGraphSpecialization>( null, MetadataManager.GetTypeOfNetType( typeof( Component_FlowGraphSpecialization_Shader ) ).Name + "|Instance" ); var node = graph.CreateComponent<Component_FlowGraphNode>(); node.Name = "Node " + material.Name; node.Position = new Vector2I( 10, -7 ); node.ControlledObject = ReferenceUtility.MakeThisReference( node, material ); } const int step = 9; Vector2I position = new Vector2I( -20, -data.GetTextureUsedCount() * step / 2 ); var addedTextures = new Dictionary<string, Component_ShaderTextureSample>(); Component_ShaderTextureSample GetOrCreateTextureSample( string channelDisplayName, string textureName ) { if( !addedTextures.TryGetValue( textureName, out var sample ) ) { var node = graph.CreateComponent<Component_FlowGraphNode>(); node.Name = "Node Texture Sample " + channelDisplayName;//"BaseColor"; node.Position = position; position.Y += step; sample = node.CreateComponent<Component_ShaderTextureSample>(); sample.Name = ComponentUtility.GetNewObjectUniqueName( sample ); sample.Texture = new Reference<Component_Image>( null, textureName );// data.BaseColorTexture ); node.ControlledObject = ReferenceUtility.MakeThisReference( node, sample ); addedTextures[ textureName ] = sample; } return sample; } //BaseColor if( !string.IsNullOrEmpty( data.BaseColorTexture ) ) { var sample = GetOrCreateTextureSample( "Base Color", data.BaseColorTexture ); material.BaseColor = ReferenceUtility.MakeThisReference( material, sample, "RGBA" ); } else if( data.BaseColor.HasValue ) material.BaseColor = data.BaseColor.Value; //Metallic if( !string.IsNullOrEmpty( data.MetallicTexture ) ) { var sample = GetOrCreateTextureSample( "Metallic", data.MetallicTexture ); material.Metallic = ReferenceUtility.MakeThisReference( material, sample, data.MetallicTextureChannel ); } //Roughness if( !string.IsNullOrEmpty( data.RoughnessTexture ) ) { var sample = GetOrCreateTextureSample( "Roughness", data.RoughnessTexture ); material.Roughness = ReferenceUtility.MakeThisReference( material, sample, data.RoughnessTextureChannel ); } //Normal if( !string.IsNullOrEmpty( data.NormalTexture ) ) { var sample = GetOrCreateTextureSample( "Normal", data.NormalTexture ); material.Normal = ReferenceUtility.MakeThisReference( material, sample, "RGBA" ); } //Displacement if( !string.IsNullOrEmpty( data.DisplacementTexture ) ) { var sample = GetOrCreateTextureSample( "Displacement", data.DisplacementTexture ); material.Displacement = ReferenceUtility.MakeThisReference( material, sample, data.DisplacementTextureChannel ); } //AmbientOcclusion if( !string.IsNullOrEmpty( data.AmbientOcclusionTexture ) ) { var sample = GetOrCreateTextureSample( "Ambient Occlusion", data.AmbientOcclusionTexture ); material.AmbientOcclusion = ReferenceUtility.MakeThisReference( material, sample, data.AmbientOcclusionTextureChannel ); } //Emissive if( !string.IsNullOrEmpty( data.EmissiveTexture ) ) { var sample = GetOrCreateTextureSample( "Emissive", data.EmissiveTexture ); material.Emissive = ReferenceUtility.MakeThisReference( material, sample, "RGBA" ); } //Opacity if( !string.IsNullOrEmpty( data.OpacityTexture ) ) { var sample = GetOrCreateTextureSample( "Opacity", data.OpacityTexture ); material.Opacity = ReferenceUtility.MakeThisReference( material, sample, data.OpacityTextureChannel ); } material.Enabled = true; return material; }