/// <summary> /// Modify the material to comply with its transparency parameters. /// </summary> /// <param name="material">The material/</param> private static void AdjustForTransparency(MaterialDescription material) { // Note: at this point, there is no other nodes than diffuse, specular, transparent, normal and displacement if (material.ColorNodes.ContainsKey(MaterialParameters.AlbedoDiffuse)) { var diffuseNode = material.GetMaterialNode(MaterialParameters.AlbedoDiffuse); if (material.ColorNodes.ContainsKey(MaterialParameters.TransparencyMap)) { var diffuseNodeName = material.ColorNodes[MaterialParameters.AlbedoDiffuse]; var transparentNodeName = material.ColorNodes[MaterialParameters.TransparencyMap]; var transparentNode = material.GetMaterialNode(MaterialParameters.TransparencyMap); if (diffuseNode == null || transparentNode == null) { return; } var foundTextureDiffuse = FindTextureNode(material, diffuseNodeName); var foundTextureTransparent = FindTextureNode(material, transparentNodeName); if (foundTextureDiffuse != null && foundTextureTransparent != null) { if (foundTextureDiffuse != foundTextureTransparent) { var alphaMixNode = new MaterialBinaryNode(diffuseNode, transparentNode, MaterialBinaryOperand.SubstituteAlpha); material.AddColorNode(MaterialParameters.AlbedoDiffuse, "pdx_diffuseWithAlpha", alphaMixNode); } } // set the key if it was missing material.Parameters.Set(MaterialParameters.UseTransparent, true); } else { // NOTE: MaterialParameters.UseTransparent is mostly runtime var isTransparent = false; if (material.Parameters.ContainsKey(MaterialParameters.UseTransparent)) { isTransparent = (bool)material.Parameters[MaterialParameters.UseTransparent]; } if (!isTransparent) { // remove the diffuse node var diffuseName = material.ColorNodes[MaterialParameters.AlbedoDiffuse]; material.Nodes.Remove(diffuseName); // add the new one var opaqueNode = new MaterialBinaryNode(diffuseNode, null, MaterialBinaryOperand.Opaque); material.AddColorNode(MaterialParameters.AlbedoDiffuse, "pdx_diffuseOpaque", opaqueNode); } } } }
/// <summary> /// Build the ShaderMixinSource to evaluate the binaryNode. /// </summary> /// <param name="binaryNode">The MaterialBinaryNode binaryNode used as source to find the ShaderMixinSource.</param> /// <returns>The corresponding ShaderMixinSource.</returns> private ShaderSource GetShaderSource(MaterialBinaryNode binaryNode) { var leftShaderSource = GetShaderSource(binaryNode.LeftChild); var rightShaderSource = GetShaderSource(binaryNode.RightChild); var shaderSource = new ShaderClassSource(GetCorrespondingShaderSourceName(binaryNode.Operand)); var mixin = new ShaderMixinSource(); mixin.Mixins.Add(shaderSource); if (leftShaderSource != null) { mixin.AddComposition(BackgroundCompositionName, leftShaderSource); } if (binaryNode.Operand != MaterialBinaryOperand.None && binaryNode.Operand != MaterialBinaryOperand.Opaque && rightShaderSource != null) { mixin.AddComposition(ForegroundCompositionName, rightShaderSource); } return(mixin); }
/// <summary> /// Reduce the binaryNode to its most compact form. /// </summary> /// <param name="binaryNode">The MaterialBinaryNode binaryNode to reduce.</param> /// <returns>The reduced binaryNode.</returns> private IMaterialNode Reduce(MaterialBinaryNode binaryNode) { var left = Reduce(binaryNode.LeftChild); var right = Reduce(binaryNode.RightChild); bool canReduce = true; //if (binaryNode.LeftChild is IMaterialValueNode) // canReduce &= !(binaryNode.LeftChild as IMaterialValueNode).IsParameter; //if (binaryNode.RightChild is IMaterialValueNode) // canReduce &= !(binaryNode.RightChild as IMaterialValueNode).IsParameter; if (canReduce) { if (left is MaterialFloatNode) { if (right is MaterialFloatNode) { (left as MaterialFloatNode).Value = MaterialReductionUtils.MixFloat((left as MaterialFloatNode).Value, (right as MaterialFloatNode).Value, binaryNode.Operand); return(left); } if (right is MaterialFloat4Node) { var value = (left as MaterialFloatNode).Value; (right as MaterialFloat4Node).Value = MaterialReductionUtils.MixFloat4(new Vector4(value, value, value, value), (right as MaterialFloat4Node).Value, binaryNode.Operand); return(right); } if (right is MaterialColorNode) { var value = (left as MaterialFloatNode).Value; (right as MaterialColorNode).Value = MaterialReductionUtils.MixColor(new Color4(value, value, value, value), (right as MaterialColorNode).Value, binaryNode.Operand); return(right); } } else if (left is MaterialFloat4Node) { if (right is MaterialFloatNode) { var value = (right as MaterialFloatNode).Value; (left as MaterialFloat4Node).Value = MaterialReductionUtils.MixFloat4((left as MaterialFloat4Node).Value, new Vector4(value, value, value, value), binaryNode.Operand); return(left); } if (right is MaterialFloat4Node) { (left as MaterialFloat4Node).Value = MaterialReductionUtils.MixFloat4((left as MaterialFloat4Node).Value, (right as MaterialFloat4Node).Value, binaryNode.Operand); return(left); } if (right is MaterialColorNode) { var value = (left as MaterialFloat4Node).Value; (left as MaterialFloat4Node).Value = MaterialReductionUtils.MixFloat4(value, (right as MaterialColorNode).Value.ToVector4(), binaryNode.Operand); return(left); } } else if (left is MaterialColorNode) { if (right is MaterialFloatNode) { var value = (right as MaterialFloatNode).Value; (left as MaterialColorNode).Value = MaterialReductionUtils.MixColor((left as MaterialColorNode).Value, new Color4(value, value, value, value), binaryNode.Operand); return(left); } if (right is MaterialFloat4Node) { (right as MaterialFloat4Node).Value = MaterialReductionUtils.MixFloat4((left as MaterialColorNode).Value.ToVector4(), (right as MaterialFloat4Node).Value, binaryNode.Operand); return(right); } if (right is MaterialColorNode) { var value = (left as MaterialColorNode).Value; (left as MaterialColorNode).Value = MaterialReductionUtils.MixColor((left as MaterialColorNode).Value, (right as MaterialColorNode).Value, binaryNode.Operand); return(left); } } } binaryNode.LeftChild = left; binaryNode.RightChild = right; return(binaryNode); }