Пример #1
0
        private void BlendShadingModel(MaterialBlendLayerContext parent, MaterialBlendLayerPerStageContext pendingPixelLayerContext, MaterialBlendLayerPerStageContext parentPixelLayerContext)
        {
            var shaderBlendingSource = new ShaderMixinSource();

            shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingBlend"));

            parent.SetStreamBlend(MaterialShaderStage.Pixel, parent.BlendMapForShadingModel);

            // Add shader source already setup for the parent
            foreach (var shaderSource in pendingPixelLayerContext.ShaderSources)
            {
                shaderBlendingSource.AddCompositionToArray("layers", shaderSource);
            }

            // Add shader source generated for blending this layer
            foreach (var shaderSource in parent.ShadingModels.Generate(this))
            {
                shaderBlendingSource.AddCompositionToArray("layers", shaderSource);
            }
            parent.ShadingModels.Clear();

            parentPixelLayerContext.ShaderSources.Add(shaderBlendingSource);

            pendingPixelLayerContext.Reset();
            parent.BlendMapForShadingModel = null;
        }
Пример #2
0
        public ShaderSource GetSource(RenderVoxelVolumeData data)
        {
            var writermixin = new ShaderMixinSource();

            writermixin.Mixins.Add(storage);
            foreach (var attr in data.AttributeIndirect)
            {
                writermixin.AddCompositionToArray("AttributesIndirect", attr);
            }
            foreach (var attr in data.AttributeModifiers)
            {
                writermixin.AddCompositionToArray("Modifiers", attr);
            }
            return(writermixin);
        }
Пример #3
0
        private void Generate(MaterialShaderStage stage, MaterialGeneratorContext context)
        {
            if (!context.HasSurfaceShaders(stage))
            {
                return;
            }

            // Blend setup for this layer
            context.SetStream(stage, BlendStream, BlendMap, MaterialKeys.BlendMap, MaterialKeys.BlendValue);

            // Generate a dynamic shader name
            // Create a mixin
            var shaderMixinSource = new ShaderMixinSource();

            shaderMixinSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceStreamsBlend"));

            // Add all streams
            foreach (var stream in context.Streams[stage])
            {
                shaderMixinSource.AddCompositionToArray("blends", context.GetStreamBlendShaderSource(stream));
            }

            var materialBlendLayerMixin = context.GenerateSurfaceShader(stage);

            // Add the shader to the mixin
            shaderMixinSource.AddComposition("layer", materialBlendLayerMixin);

            context.ResetSurfaceShaders(stage);
            context.AddSurfaceShader(stage, shaderMixinSource);
        }
Пример #4
0
        /// <summary>
        /// Squash <see cref="ShaderSources"/> to a single ShaderSource (compatible with IComputeColor)
        /// </summary>
        /// <returns>The squashed <see cref="ShaderSource"/> or null if nothing to squash</returns>
        public ShaderSource ComputeShaderSource()
        {
            if (ShaderSources.Count == 0)
            {
                return(null);
            }

            ShaderSource result;

            // If there is only a single op, don't generate a mixin
            if (ShaderSources.Count == 1)
            {
                result = ShaderSources[0];
            }
            else
            {
                var mixin = new ShaderMixinSource();
                result = mixin;
                mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray"));

                // Squash all operations into MaterialLayerArray
                foreach (var operation in ShaderSources)
                {
                    mixin.AddCompositionToArray("layers", operation);
                }
            }
            return(result);
        }
Пример #5
0
            public ShaderSource GenerateSurfaceShader(MaterialShaderStage stage)
            {
                var surfaceShaders = GetSurfaceShaders(stage);

                if (surfaceShaders.Count == 0)
                {
                    return(null);
                }

                ShaderSource result;

                // If there is only a single op, don't generate a mixin
                if (surfaceShaders.Count == 1)
                {
                    result = surfaceShaders[0];
                }
                else
                {
                    var mixin = new ShaderMixinSource();
                    result = mixin;
                    mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray"));

                    // Squash all operations into MaterialLayerArray
                    foreach (var operation in surfaceShaders)
                    {
                        mixin.AddCompositionToArray("layers", operation);
                    }
                }

                surfaceShaders.Clear();
                Streams[stage].Clear();
                return(result);
            }
        /// <summary>
        /// Squash <see cref="ShaderSources"/> to a single ShaderSource (compatible with IComputeColor)
        /// </summary>
        /// <returns>The squashed <see cref="ShaderSource"/> or null if nothing to squash</returns>
        public ShaderSource ComputeShaderSource()
        {
            if (ShaderSources.Count == 0)
            {
                return null;
            }

            ShaderSource result;
            // If there is only a single op, don't generate a mixin
            if (ShaderSources.Count == 1)
            {
                result = ShaderSources[0];
            }
            else
            {
                var mixin = new ShaderMixinSource();
                result = mixin;
                mixin.Mixins.Add(new ShaderClassSource("MaterialSurfaceArray"));

                // Squash all operations into MaterialLayerArray
                foreach (var operation in ShaderSources)
                {
                    mixin.AddCompositionToArray("layers", operation);
                }
            }
            return result;
        }
Пример #7
0
        public ShaderSource GetVoxelizationShader(VoxelizationPass pass, ProcessedVoxelVolume data)
        {
            bool              singleClip = UpdatesOneClipPerFrame();
            ShaderSource      VoxelizationMethodSource = pass.method.GetVoxelizationShader();
            ShaderMixinSource cachedMixin = new ShaderMixinSource();

            cachedMixin.Mixins.Add(storage);
            cachedMixin.AddComposition("method", VoxelizationMethodSource);
            if (singleClip)
            {
                cachedMixin.AddMacro("singleClip", true);
            }

            string IndirectStoreMacro = "";

            for (int i = 0; i < pass.AttributesIndirect.Count; i++)
            {
                string iStr = i.ToString();
                IndirectStoreMacro += $"AttributesIndirect[{iStr}].IndirectWrite(fragmentsBuffer, writeindex + {pass.AttributesIndirect[i].BufferOffset});\n";
            }

            cachedMixin.AddMacro("IndirectStoreMacro", IndirectStoreMacro);

            foreach (var attr in pass.AttributesTemp)
            {
                cachedMixin.AddCompositionToArray("AttributesTemp", attr.GetVoxelizationShader());
            }

            foreach (var attr in pass.AttributesDirect)
            {
                cachedMixin.AddCompositionToArray("AttributesDirect", attr.GetVoxelizationShader());
            }

            foreach (var attr in pass.AttributesIndirect)
            {
                cachedMixin.AddCompositionToArray("AttributesIndirect", attr.GetVoxelizationShader());
            }

            return(cachedMixin);
        }
        public ShaderSource GetShaderFloat4(List <IVoxelModifierEmissionOpacity> modifiers)
        {
            var mixin = new ShaderMixinSource();

            mixin.Mixins.Add(writer);
            StorageMethod.Apply(mixin);
            foreach (var attr in modifiers)
            {
                ShaderSource applier = attr.GetApplier("Anisotropic");
                if (applier != null)
                {
                    mixin.AddCompositionToArray("Modifiers", applier);
                }
            }
            return(mixin);
        }
        virtual public ShaderSource GetVoxelizationShader(List <VoxelModifierEmissionOpacity> modifiers)
        {
            var mixin = new ShaderMixinSource();

            mixin.Mixins.Add(Writer);
            StorageMethod.Apply(mixin);
            foreach (var modifier in modifiers)
            {
                if (!modifier.Enabled)
                {
                    continue;
                }

                ShaderSource applier = modifier.GetApplier(ApplierKey);
                if (applier != null)
                {
                    mixin.AddCompositionToArray("Modifiers", applier);
                }
            }
            return(mixin);
        }
Пример #10
0
        private void BlendStreams(MaterialBlendLayerContext layer)
        {
            // Generate Vertex and Pixel surface shaders
            foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage)))
            {
                // If we don't have any stream set, we have nothing to blend
                var stageContext = layer.GetContextPerStage(stage);
                if (stageContext.Streams.Count == 0)
                {
                    continue;
                }

                // Blend setup for this layer
                layer.SetStreamBlend(stage, layer.BlendMap);

                // Generate a dynamic shader name
                // Create a mixin
                var shaderMixinSource = new ShaderMixinSource();
                shaderMixinSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceStreamsBlend"));

                // Add all streams that we need to blend
                foreach (var stream in stageContext.Streams)
                {
                    shaderMixinSource.AddCompositionToArray("blends", GetStreamBlendShaderSource(stream));
                }
                stageContext.Streams.Clear();

                // Squash all ShaderSources to a single shader source
                var materialBlendLayerMixin = stageContext.ComputeShaderSource();
                stageContext.ShaderSources.Clear();

                // Add the shader to the mixin
                shaderMixinSource.AddComposition("layer", materialBlendLayerMixin);

                // Squash the shader sources
                stageContext.ShaderSources.Add(shaderMixinSource);
            }
        }
Пример #11
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;
            }
        }
Пример #12
0
        private void Generate(MaterialShaderStage stage, MaterialGeneratorContext context)
        {
            if (!context.HasSurfaceShaders(stage))
            {
                return;
            }

            // Blend setup for this layer
            context.SetStream(stage, BlendStream, BlendMap, MaterialKeys.BlendMap, MaterialKeys.BlendValue);

            // Generate a dynamic shader name
            // Create a mixin
            var shaderMixinSource = new ShaderMixinSource();
            shaderMixinSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceStreamsBlend"));

            // Add all streams
            foreach (var stream in context.Streams[stage])
            {
                shaderMixinSource.AddCompositionToArray("blends", context.GetStreamBlendShaderSource(stream));
            }

            var materialBlendLayerMixin = context.GenerateSurfaceShader(stage);

            // Add the shader to the mixin
            shaderMixinSource.AddComposition("layer", materialBlendLayerMixin);

            context.ResetSurfaceShaders(stage);
            context.AddSurfaceShader(stage, shaderMixinSource);
        }
Пример #13
0
        private void ProcessIntermediateLayer(MaterialBlendLayerContext layer, bool isLastChild)
        {
            var parent = layer.Parent;
            var hasParentShadingModel = parent.ShadingModelCount > 0;

            // If current shading model is not set,
            if (!hasParentShadingModel && layer.ShadingModelCount > 0)
            {
                layer.ShadingModels.CopyTo(parent.ShadingModels);
                hasParentShadingModel = true;
                parent.ShadingModelCount++;
            }

            var sameShadingModel = hasParentShadingModel && layer.ShadingModels.Equals(parent.ShadingModels);

            if (sameShadingModel)
            {
                // If shading model is not changing, we generate the BlendStream shaders
                BlendStreams(layer);
            }
            else
            {
                parent.ShadingModelCount++;
            }

            var parentPixelLayerContext  = parent.GetContextPerStage(MaterialShaderStage.Pixel);
            var pendingPixelLayerContext = parent.PendingPixelLayerContext;

            // Copy streams to parent
            foreach (MaterialShaderStage stage in Enum.GetValues(typeof(MaterialShaderStage)))
            {
                var stageContext       = layer.GetContextPerStage(stage);
                var parentStageContext = parent.GetContextPerStage(stage);

                // the Initializers
                parentStageContext.StreamInitializers.AddRange(stageContext.StreamInitializers);

                // skip pixel shader if shading model need to be blended
                if (stage == MaterialShaderStage.Pixel)
                {
                    if (!sameShadingModel)
                    {
                        continue;
                    }
                    // If same shading model, use temporarely the ParentPixelLayerContext
                    parentStageContext = pendingPixelLayerContext;
                }

                // Add shaders except Pixels if we have a different ShadingModel
                parentStageContext.ShaderSources.AddRange(stageContext.ShaderSources);
            }

            var forceBlendingShadingModel = isLastChild && (parent.ShadingModelCount > 1 || !sameShadingModel);

            if (!sameShadingModel || forceBlendingShadingModel)
            {
                if (forceBlendingShadingModel && parent.BlendMapForShadingModel == null)
                {
                    if (!sameShadingModel)
                    {
                        foreach (var shaderSource in pendingPixelLayerContext.ShaderSources)
                        {
                            parentPixelLayerContext.ShaderSources.Add(shaderSource);
                        }
                        pendingPixelLayerContext.Reset();

                        foreach (var shaderSource in parent.ShadingModels.Generate(this))
                        {
                            parentPixelLayerContext.ShaderSources.Add(shaderSource);
                        }
                        parent.ShadingModels.Clear();
                        layer.ShadingModels.CopyTo(parent.ShadingModels);
                    }

                    parent.BlendMapForShadingModel = layer.BlendMap;
                    var currentPixelLayerContext = layer.GetContextPerStage(MaterialShaderStage.Pixel);
                    pendingPixelLayerContext.ShaderSources.AddRange(currentPixelLayerContext.ShaderSources);
                }

                // Do we need to blend shading model?
                if (parent.BlendMapForShadingModel != null)
                {
                    var shaderBlendingSource = new ShaderMixinSource();
                    shaderBlendingSource.Mixins.Add(new ShaderClassSource("MaterialSurfaceShadingBlend"));

                    parent.SetStreamBlend(MaterialShaderStage.Pixel, parent.BlendMapForShadingModel);

                    // Add shader source already setup for the parent
                    foreach (var shaderSource in pendingPixelLayerContext.ShaderSources)
                    {
                        shaderBlendingSource.AddCompositionToArray("layers", shaderSource);
                    }

                    // Add shader source generated for blending this layer
                    foreach (var shaderSource in parent.ShadingModels.Generate(this))
                    {
                        shaderBlendingSource.AddCompositionToArray("layers", shaderSource);
                    }
                    parent.ShadingModels.Clear();

                    parentPixelLayerContext.ShaderSources.Add(shaderBlendingSource);

                    pendingPixelLayerContext.Reset();
                    parent.BlendMapForShadingModel = null;
                }
                else
                {
                    foreach (var shaderSource in pendingPixelLayerContext.ShaderSources)
                    {
                        parentPixelLayerContext.ShaderSources.Add(shaderSource);
                    }
                    pendingPixelLayerContext.Reset();

                    foreach (var shaderSource in parent.ShadingModels.Generate(this))
                    {
                        parentPixelLayerContext.ShaderSources.Add(shaderSource);
                    }
                    parent.ShadingModels.Clear();
                    parent.BlendMapForShadingModel = layer.BlendMap;

                    // Copy the shading model of this layer to the parent
                    layer.ShadingModels.CopyTo(parent.ShadingModels);
                }

                // If the shading model is different, the current attributes of the layer are not part of this blending
                // So they will contribute to the next blending
                if (!sameShadingModel && !forceBlendingShadingModel)
                {
                    var currentPixelLayerContext = layer.GetContextPerStage(MaterialShaderStage.Pixel);
                    pendingPixelLayerContext.ShaderSources.AddRange(currentPixelLayerContext.ShaderSources);
                }
            }
        }