Ejemplo n.º 1
0
            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);
            }
Ejemplo n.º 2
0
 /// <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;
     }
 }
Ejemplo n.º 3
0
            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>();
                }
            }
Ejemplo n.º 4
0
        /// <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();
        }
Ejemplo n.º 5
0
        /// <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);
        }
Ejemplo n.º 6
0
        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;
            }
        }