public bool Equals(MaterialShadingModelCollection node) { if (node == null || ReferenceEquals(node, this)) { return(true); } if (Count != node.Count) { return(false); } if (Count == 0 || node.Count == 0) { return(true); } foreach (var shadingModelKeyPair in this) { KeyValuePair <IMaterialShadingModelFeature, ShaderSource> shadingModelAgainst; if (!node.TryGetValue(shadingModelKeyPair.Key, out shadingModelAgainst)) { return(false); } if (!shadingModelKeyPair.Value.Key.Equals(shadingModelAgainst.Key)) { return(false); } } return(true); }
/// <summary> /// Copies the shading models of this instance to the destination instance. /// </summary> /// <param name="node">The destination collection</param> public void CopyTo(MaterialShadingModelCollection node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } foreach (var keyValue in this) { node[keyValue.Key] = keyValue.Value; } }
public MaterialBlendLayerNode(MaterialGeneratorContext context, MaterialBlendLayerNode parentNode) { this.context = context; this.parentNode = parentNode; Children = new List <MaterialBlendLayerNode>(); ShadingModels = new MaterialShadingModelCollection(); foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { SurfaceShaders[stage] = new List <ShaderSource>(); StreamInitializers[stage] = new List <string>(); Streams[stage] = new HashSet <string>(); } }
/// <summary> /// Initializes a new instance of <see cref="MaterialBlendLayerContext"/>. /// </summary> /// <param name="context">The material generator context</param> /// <param name="parentLayerContext">The parent layer context</param> /// <param name="blendMap">The blend map used for this layer</param> public MaterialBlendLayerContext(MaterialGeneratorContext context, MaterialBlendLayerContext parentLayerContext, IComputeScalar blendMap) { if (context == null) { throw new ArgumentNullException(nameof(context)); } Context = context; Parent = parentLayerContext; BlendMap = blendMap; Children = new List <MaterialBlendLayerContext>(); ShadingModels = new MaterialShadingModelCollection(); ContextPerStage = new Dictionary <MaterialShaderStage, MaterialBlendLayerPerStageContext>(); foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { ContextPerStage[stage] = new MaterialBlendLayerPerStageContext(); } PendingPixelLayerContext = new MaterialBlendLayerPerStageContext(); }
/// <summary> /// Compares the shading models of this instance against the specified instance. /// </summary> /// <param name="node">The shading model</param> /// <returns><c>true</c> if shading models are equvalent; <c>false</c> otherwise</returns> public bool Equals(MaterialShadingModelCollection node) { // Methods that allows to deeply compare shading models if (node == null || ReferenceEquals(node, this)) { return(true); } if (Count != node.Count) { return(false); } if (Count == 0 || node.Count == 0) { return(true); } // Because we expect the same number of shading models, we can perform the whole check in a single pass foreach (var shadingModelKeyPair in this) { KeyValuePair <IMaterialShadingModelFeature, ShaderSource> shadingModelAgainst; if (!node.TryGetValue(shadingModelKeyPair.Key, out shadingModelAgainst)) { return(false); } // Note: this method is going to compare deeply the shading models (all implem of IMaterialShadingModelFeature) // and calling their respective Equals method implemented. if (!shadingModelKeyPair.Value.Key.Equals(shadingModelAgainst.Key)) { return(false); } } return(true); }
public void PopLayer() { // If current shading model is not set, if (CurrentShadingModel == null && Current.ShadingModels.Count > 0) { CurrentShadingModel = Current.ShadingModels; } var sameShadingModel = Current.ShadingModels.Equals(CurrentShadingModel); if (!sameShadingModel) { shadingModelCount++; } var shouldBlendShadingModels = CurrentShadingModel != null && (!sameShadingModel || Current.Parent == null); // current shading model different from next shading model // -------------------------------------------------------------------- // Copy the shading surfaces and the stream initializer to the parent. // -------------------------------------------------------------------- if (Current.Parent != null) { foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage))) { // the Initializers Current.Parent.StreamInitializers[stage].AddRange(Current.StreamInitializers[stage]); // skip pixel shader if shading model need to be blended if (stage == MaterialShaderStage.Pixel && shouldBlendShadingModels) { continue; } // the surface shaders Current.Parent.SurfaceShaders[stage].AddRange(Current.SurfaceShaders[stage]); } } // ------------------------------------------------- // Blend shading models between layers if necessary // ------------------------------------------------- if (shouldBlendShadingModels) { var shadingSources = CurrentShadingModel.Generate(this); // If we are in a multi-shading-blending, only blend shading models after 1st shading model if (shadingModelCount > 1) { var shaderBlendingSource = new ShaderMixinSource(); shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceBlendShading")); foreach (var shaderSource in shadingSources) { shaderBlendingSource.AddCompositionToArray("layers", shaderSource); } shadingSources = new List <ShaderSource>() { shaderBlendingSource }; } var currentOrParentLayer = Current.Parent ?? Current; foreach (var shaderSource in shadingSources) { currentOrParentLayer.SurfaceShaders[MaterialShaderStage.Pixel].Add(shaderSource); } } // In case of the root material, add all stream modifiers just at the end and call final callbacks if (Current.Parent == null) { foreach (var modifierKey in inputStreamModifiers.Keys) { Current.SurfaceShaders[modifierKey.Key].Add(inputStreamModifiers[modifierKey]); } // Clear final callback foreach (var callbackKeyPair in finalCallbacks) { var stage = callbackKeyPair.Key; var callbacks = callbackKeyPair.Value; foreach (var callback in callbacks) { callback(stage, this); } callbacks.Clear(); } } // ---------------------------------------------- // Pop to Parent and set Current // ---------------------------------------------- if (Current.Parent != null && !sameShadingModel) { CurrentShadingModel = Current.ShadingModels; } if (Current.Parent != null) { Current = Current.Parent; } }