public override void SetupResources(EffectMesh effectMesh)
        {
            var blendStateDesc = new BlendStateDescription();

            blendStateDesc.SetDefaults();
            blendStateDesc.AlphaToCoverageEnable        = false;
            blendStateDesc.IndependentBlendEnable       = false;
            blendStateDesc.RenderTargets[0].BlendEnable = true;

            blendStateDesc.RenderTargets[0].AlphaBlendFunction    = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].AlphaSourceBlend      = Blend.One;
            blendStateDesc.RenderTargets[0].AlphaDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorBlendFunction    = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].ColorSourceBlend      = Blend.One;
            blendStateDesc.RenderTargets[0].ColorDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.All;

            // "LightPrePassAdditiveBlend"
            Effect.Parameters.Set(BlendStateKey, BlendState.New(GraphicsDevice, blendStateDesc));

            if (Debug)
            {
                var rasterizer = RasterizerState.New(GraphicsDevice, new RasterizerStateDescription()
                {
                    FillMode = FillMode.Wireframe
                });
                rasterizer.Name = "LightPrePassWireFrame";
                Effect.Parameters.Set(RasterizerStateKey, rasterizer);
            }

            Effect.PrepareMesh    += SetupMeshResources;
            Effect.UpdateMeshData += UpdateMeshResources;
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BlendStateFactory"/> class.
        /// </summary>
        /// <param name="device">The device.</param>
        internal BlendStateFactory(GraphicsDevice device)
        {
            var blendDescription = new BlendStateDescription(Blend.One, Blend.Zero);
            blendDescription.SetDefaults();
            Default = BlendState.New(device, blendDescription).DisposeBy(device);
            Default.Name = "Default";

            Additive = BlendState.New(device, new BlendStateDescription(Blend.SourceAlpha, Blend.One)).DisposeBy(device);
            Additive.Name = "Additive";

            AlphaBlend = BlendState.New(device, new BlendStateDescription(Blend.One, Blend.InverseSourceAlpha)).DisposeBy(device);
            AlphaBlend.Name = "AlphaBlend";

            NonPremultiplied = BlendState.New(device, new BlendStateDescription(Blend.SourceAlpha, Blend.InverseSourceAlpha)).DisposeBy(device);
            NonPremultiplied.Name = "NonPremultiplied";

            Opaque = BlendState.New(device, new BlendStateDescription(Blend.One, Blend.Zero)).DisposeBy(device);
            Opaque.Name = "Opaque";

            var colorDisabledDescription = new BlendStateDescription();
            colorDisabledDescription.SetDefaults();
            colorDisabledDescription.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.None;
            ColorDisabled = BlendState.New(device, colorDisabledDescription).DisposeBy(device);
            ColorDisabled.Name = "ColorDisabled";
        }
示例#3
0
        static BlendStates()
        {
            var blendDescription = new BlendStateDescription(Blend.One, Blend.Zero);
            blendDescription.SetDefaults();
            Default = blendDescription;

            var colorDisabledDescription = new BlendStateDescription();
            colorDisabledDescription.SetDefaults();
            colorDisabledDescription.RenderTarget0.ColorWriteChannels = ColorWriteChannels.None;
            ColorDisabled = colorDisabledDescription;
        }
示例#4
0
        public override void SetupResources(EffectMesh effectMesh)
        {
            base.SetupResources(effectMesh);

            Effect.Parameters.RegisterParameter(BlendStateKey);
            Effect.Parameters.RegisterParameter(RasterizerStateKey);

            // Create blendstate for min calculation
            var bbBlendDesc = new BlendStateDescription();

            bbBlendDesc.SetDefaults();
            bbBlendDesc.AlphaToCoverageEnable                  = false;
            bbBlendDesc.IndependentBlendEnable                 = false;
            bbBlendDesc.RenderTargets[0].BlendEnable           = true;
            bbBlendDesc.RenderTargets[0].ColorSourceBlend      = Blend.One;
            bbBlendDesc.RenderTargets[0].ColorDestinationBlend = Blend.One;

            bbBlendDesc.RenderTargets[0].ColorBlendFunction = BlendFunction.Max;
            bbBlendDesc.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.Red;
            var blendMinState = BlendState.New(GraphicsDevice, bbBlendDesc);

            blendMinState.Name = "MinBlend";

            // Create blendstate for max calculation
            bbBlendDesc.RenderTargets[0].ColorBlendFunction = BlendFunction.Max;
            bbBlendDesc.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.Green;
            var blendMaxState = BlendState.New(GraphicsDevice, bbBlendDesc);

            blendMaxState.Name = "MaxBlend";

            maxPass.Parameters.Set(RasterizerStateKey, GraphicsDevice.RasterizerStates.CullFront);
            maxPass.Parameters.Set(BlendStateKey, blendMaxState);

            minPass.Parameters.Set(RasterizerStateKey, GraphicsDevice.RasterizerStates.CullBack);
            minPass.Parameters.Set(BlendStateKey, blendMinState);
        }
示例#5
0
        public override void Initialize()
        {
            base.Initialize();

            boundingBoxPass   = new RenderPass("BoundingBoxPass");
            minMaxPass        = new RenderPass("MinmaxPass");
            lightShaftPass    = new RenderPass("LightShaftPass");
            filterUpscalePass = new RenderPass("UpscalePass");
            RenderPass.AddPass(boundingBoxPass, minMaxPass, lightShaftPass, filterUpscalePass);

            var useUpScaling = false;

            var bbRenderTargetPlugin = new RenderTargetsPlugin("BoundingBoxRenderTargetPlugin")
            {
                EnableSetTargets  = true,
                EnableClearTarget = true,
                RenderPass        = boundingBoxPass,
                Services          = Services,
            };

            var minMaxEffectBuilder = this.EffectSystemOld.BuildEffect("MinMax")
                                      .Using(new MinMaxShaderPlugin("MinMaxShaderPlugin")
            {
                RenderPassPlugin = bbRenderTargetPlugin
            })
                                      .Using(new BasicShaderPlugin("TransformationWVP")
            {
                RenderPassPlugin = bbRenderTargetPlugin
            });


            var minmaxEffectBuilder = this.EffectSystemOld.BuildEffect("LightShaftsMinMax")
                                      .Using(new PostEffectSeparateShaderPlugin()
            {
                RenderPass = minMaxPass
            })
                                      .Using(new BasicShaderPlugin("ForwardShadowMapBase")
            {
                RenderPass = minMaxPass
            })
                                      .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectMinMax", "ShadowMapUtils.shadowMapTexture", "PointSampler", 4, 4, 0.0, 1.0))
            {
                RenderPass = minMaxPass
            });

            var lightShaftsEffectBuilder = this.EffectSystemOld.BuildEffect("LightShafts")
                                           .Using(new PostEffectSeparateShaderPlugin()
            {
                RenderPass = lightShaftPass
            })
                                           .Using(new StateShaderPlugin()
            {
                UseBlendState = !useUpScaling, RenderPass = lightShaftPass
            })
                                           //.Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectLightShafts", Debug ? 1 : 0, RenderContext.IsZReverse ? 1 : 0, StepCount)) { RenderPass = lightShaftPass });
                                           .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectLightShafts", Debug ? 1 : 0, false ? 1 : 0, StepCount))
            {
                RenderPass = lightShaftPass
            });

            if (OfflineCompilation)
            {
                minMaxEffectBuilder.InstantiatePermutation();
                minmaxEffectBuilder.InstantiatePermutation();
                lightShaftsEffectBuilder.InstantiatePermutation();
                return;
            }

            Parameters.AddSources(ViewParameters);
            Parameters.Set(RenderTargetKeys.DepthStencilSource, DepthStencil.Texture);
            Parameters.Set(TexturingKeys.Sampler, GraphicsDevice.SamplerStates.PointClamp);

            // BoundingBox prepass
            var gbufferDesc    = RenderTarget.Description;
            var bbRenderTarget = Texture2D.New(GraphicsDevice, gbufferDesc.Width / 8, gbufferDesc.Height / 8, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);

            // Use MinMax Plugin
            bbRenderTargetPlugin.RenderTarget = bbRenderTarget.ToRenderTarget();
            bbRenderTargetPlugin.Parameters.AddSources(Parameters);
            bbRenderTargetPlugin.Apply();

            EffectOld minMaxEffect = minMaxEffectBuilder.InstantiatePermutation();

            // Add meshes
            foreach (var bbMeshData in BoundingBoxes)
            {
                // Mesh for MinPass
                var bbMesh = new EffectMesh(minMaxEffect, bbMeshData).KeepAliveBy(this);
                // Add mesh
                // boundingBoxPass.AddPass(bbMesh.EffectMeshPasses[0].EffectPass);
                RenderSystem.GlobalMeshes.AddMesh(bbMesh);
            }

            // MinMax render target
            var minMaxRenderTarget = Texture2D.New(GraphicsDevice, 256, 256, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);

            minMaxPass.Parameters = new ParameterCollection(null);
            minMaxPass.Parameters.AddSources(ShadowMap.Parameters);
            minMaxPass.Parameters.AddSources(Parameters);
            minMaxPass.Parameters.AddDynamic(PostEffectMinMaxKeys.MinMaxCoords, ParameterDynamicValue.New(LightingPlugin.CascadeTextureCoords, (ref Vector4[] cascadeTextureCoords, ref Vector4 output) =>
            {
                output = cascadeTextureCoords[0];
            }, autoCheckDependencies: false));

            EffectOld minmaxEffect = minmaxEffectBuilder.InstantiatePermutation();

            var minMaxMesh = new EffectMesh(minmaxEffect).KeepAliveBy(this);

            minMaxMesh.Parameters.Set(RenderTargetKeys.RenderTarget, minMaxRenderTarget.ToRenderTarget());
            RenderSystem.GlobalMeshes.AddMesh(minMaxMesh);

            // Light Shafts effect
            var blendStateDesc = new BlendStateDescription();

            blendStateDesc.SetDefaults();
            blendStateDesc.AlphaToCoverageEnable        = false;
            blendStateDesc.IndependentBlendEnable       = false;
            blendStateDesc.RenderTargets[0].BlendEnable = true;

            blendStateDesc.RenderTargets[0].AlphaBlendFunction    = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].AlphaSourceBlend      = Blend.One;
            blendStateDesc.RenderTargets[0].AlphaDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorBlendFunction    = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].ColorSourceBlend      = Blend.One;
            blendStateDesc.RenderTargets[0].ColorDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.All;

            var additiveBlending = BlendState.New(GraphicsDevice, blendStateDesc);

            additiveBlending.Name = "LightShaftAdditiveBlend";

            var shaftRenderTarget = useUpScaling ? Texture2D.New(GraphicsDevice, gbufferDesc.Width / 2, gbufferDesc.Height / 2, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget() : RenderTarget;


            lightShaftPass.Parameters = new ParameterCollection();
            lightShaftPass.Parameters.AddSources(ShadowMap.Parameters);
            lightShaftPass.Parameters.AddSources(Parameters);

            this.lightShaftsEffect = lightShaftsEffectBuilder.InstantiatePermutation();


            var mesh = new EffectMesh(lightShaftsEffect).KeepAliveBy(this);

            mesh.Parameters.Set(TexturingKeys.Texture0, minMaxRenderTarget);
            mesh.Parameters.Set(TexturingKeys.Texture1, bbRenderTarget);
            mesh.Parameters.Set(RenderTargetKeys.RenderTarget, shaftRenderTarget);

            if (!useUpScaling)
            {
                mesh.Parameters.Set(EffectPlugin.BlendStateKey, additiveBlending);
            }
            RenderSystem.GlobalMeshes.AddMesh(mesh);

            // Bilateral Gaussian filtering for up-sampling
            if (useUpScaling)
            {
                var bbRenderTargetUpScaleH = Texture2D.New(GraphicsDevice, gbufferDesc.Width, gbufferDesc.Height / 2, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                var bbRenderTargetUpScaleV = RenderTarget;
                //var bbRenderTargetUpScaleV = GraphicsDevice.RenderTarget2D.New(gbufferDesc.Width, gbufferDesc.Height, PixelFormat.HalfVector4);

                var blurEffects = new EffectOld[] {
                    this.EffectSystemOld.BuildEffect("BilateralGaussianFiltering")
                    .Using(new PostEffectSeparateShaderPlugin())
                    .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectBilateralGaussian", 0))),
                    this.EffectSystemOld.BuildEffect("BilateralGaussianFiltering")
                    .Using(new StateShaderPlugin()
                    {
                        UseBlendState = true
                    })
                    .Using(new PostEffectSeparateShaderPlugin())
                    .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectBilateralGaussian", 1))),
                };

                Texture2D    textureSourceH = (Texture2D)shaftRenderTarget.Texture;
                Texture2D    textureSourceV = bbRenderTargetUpScaleH;
                RenderTarget renderTargetH  = bbRenderTargetUpScaleH.ToRenderTarget();
                RenderTarget renderTargetV  = bbRenderTargetUpScaleV;

                var blurQuadMesh = new EffectMesh[2];
                for (int i = 0; i < 2; ++i)
                {
                    blurQuadMesh[i] = new EffectMesh(blurEffects[i]).KeepAliveBy(this);
                    filterUpscalePass.AddPass(blurQuadMesh[i].EffectPass);
                    RenderSystem.GlobalMeshes.AddMesh(blurQuadMesh[i]);
                }

                blurQuadMesh[0].Parameters.Set(TexturingKeys.Texture0, textureSourceH);
                blurQuadMesh[1].Parameters.Set(TexturingKeys.Texture0, textureSourceV);
                blurQuadMesh[0].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetH);
                blurQuadMesh[1].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetV);

                // Additive blending for 2nd render target
                blurQuadMesh[1].Parameters.Set(EffectPlugin.BlendStateKey, additiveBlending);
            }
        }
示例#6
0
        public override void Initialize()
        {
            base.Initialize();

            boundingBoxPass = new RenderPass("BoundingBoxPass");
            minMaxPass = new RenderPass("MinmaxPass");
            lightShaftPass = new RenderPass("LightShaftPass");
            filterUpscalePass = new RenderPass("UpscalePass");
            RenderPass.AddPass(boundingBoxPass, minMaxPass, lightShaftPass, filterUpscalePass);

            var useUpScaling = false;

            var bbRenderTargetPlugin = new RenderTargetsPlugin("BoundingBoxRenderTargetPlugin")
                {
                    EnableSetTargets = true,
                    EnableClearTarget = true,
                    RenderPass = boundingBoxPass,
                    Services = Services,
                };

            var minMaxEffectBuilder = this.EffectSystemOld.BuildEffect("MinMax")
                .Using(new MinMaxShaderPlugin("MinMaxShaderPlugin") { RenderPassPlugin = bbRenderTargetPlugin })
                .Using(new BasicShaderPlugin("TransformationWVP") { RenderPassPlugin = bbRenderTargetPlugin });


            var minmaxEffectBuilder = this.EffectSystemOld.BuildEffect("LightShaftsMinMax")
                .Using(new PostEffectSeparateShaderPlugin() { RenderPass = minMaxPass })
                .Using(new BasicShaderPlugin("ForwardShadowMapBase") { RenderPass = minMaxPass })
                .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectMinMax", "ShadowMapUtils.shadowMapTexture", "PointSampler", 4, 4, 0.0, 1.0)) { RenderPass = minMaxPass });

            var lightShaftsEffectBuilder = this.EffectSystemOld.BuildEffect("LightShafts")
                .Using(new PostEffectSeparateShaderPlugin() { RenderPass = lightShaftPass })
                .Using(new StateShaderPlugin() { UseBlendState = !useUpScaling, RenderPass = lightShaftPass })
                //.Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectLightShafts", Debug ? 1 : 0, RenderContext.IsZReverse ? 1 : 0, StepCount)) { RenderPass = lightShaftPass });
                .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectLightShafts", Debug ? 1 : 0, false ? 1 : 0, StepCount)) { RenderPass = lightShaftPass });

            if (OfflineCompilation)
            {
                minMaxEffectBuilder.InstantiatePermutation();
                minmaxEffectBuilder.InstantiatePermutation();
                lightShaftsEffectBuilder.InstantiatePermutation();
                return;
            }

            Parameters.AddSources(ViewParameters);
            Parameters.Set(RenderTargetKeys.DepthStencilSource, DepthStencil.Texture);
            Parameters.Set(TexturingKeys.Sampler, GraphicsDevice.SamplerStates.PointClamp);

            // BoundingBox prepass
            var gbufferDesc = RenderTarget.Description;
            var bbRenderTarget = Texture.New2D(GraphicsDevice, gbufferDesc.Width / 8, gbufferDesc.Height / 8, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);

            // Use MinMax Plugin
            bbRenderTargetPlugin.RenderTarget = bbRenderTarget.ToRenderTarget();
            bbRenderTargetPlugin.Parameters.AddSources(Parameters);
            bbRenderTargetPlugin.Apply();

            EffectOld minMaxEffect = minMaxEffectBuilder.InstantiatePermutation();
           
            // Add meshes
            foreach (var bbMeshData in BoundingBoxes)
            {
                // Mesh for MinPass
                var bbMesh = new EffectMesh(minMaxEffect, bbMeshData).KeepAliveBy(this);
                // Add mesh
                // boundingBoxPass.AddPass(bbMesh.EffectMeshPasses[0].EffectPass);
                RenderSystem.GlobalMeshes.AddMesh(bbMesh);
            }

            // MinMax render target
            var minMaxRenderTarget = Texture.New2D(GraphicsDevice, 256, 256, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
            minMaxPass.Parameters = new ParameterCollection(null);
            minMaxPass.Parameters.AddSources(ShadowMap.Parameters);
            minMaxPass.Parameters.AddSources(Parameters);
            minMaxPass.Parameters.AddDynamic(PostEffectMinMaxKeys.MinMaxCoords, ParameterDynamicValue.New(LightingPlugin.CascadeTextureCoords, (ref Vector4[] cascadeTextureCoords, ref Vector4 output) =>
                {
                    output = cascadeTextureCoords[0];
                }, autoCheckDependencies: false));

            EffectOld minmaxEffect = minmaxEffectBuilder.InstantiatePermutation();

            var minMaxMesh = new EffectMesh(minmaxEffect).KeepAliveBy(this);
            minMaxMesh.Parameters.Set(RenderTargetKeys.RenderTarget, minMaxRenderTarget.ToRenderTarget());
            RenderSystem.GlobalMeshes.AddMesh(minMaxMesh);

            // Light Shafts effect
            var blendStateDesc = new BlendStateDescription();
            blendStateDesc.SetDefaults();
            blendStateDesc.AlphaToCoverageEnable = false;
            blendStateDesc.IndependentBlendEnable = false;
            blendStateDesc.RenderTargets[0].BlendEnable = true;

            blendStateDesc.RenderTargets[0].AlphaBlendFunction = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].AlphaSourceBlend = Blend.One;
            blendStateDesc.RenderTargets[0].AlphaDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorBlendFunction = BlendFunction.Add;
            blendStateDesc.RenderTargets[0].ColorSourceBlend = Blend.One;
            blendStateDesc.RenderTargets[0].ColorDestinationBlend = Blend.One;

            blendStateDesc.RenderTargets[0].ColorWriteChannels = ColorWriteChannels.All;

            var additiveBlending = BlendState.New(GraphicsDevice, blendStateDesc);
            additiveBlending.Name = "LightShaftAdditiveBlend";

            var shaftRenderTarget = useUpScaling ? Texture.New2D(GraphicsDevice, gbufferDesc.Width / 2, gbufferDesc.Height / 2, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).ToRenderTarget() : RenderTarget;
            

            lightShaftPass.Parameters = new ParameterCollection();
            lightShaftPass.Parameters.AddSources(ShadowMap.Parameters);
            lightShaftPass.Parameters.AddSources(Parameters);

            this.lightShaftsEffect = lightShaftsEffectBuilder.InstantiatePermutation();


            var mesh = new EffectMesh(lightShaftsEffect).KeepAliveBy(this);
            mesh.Parameters.Set(TexturingKeys.Texture0, minMaxRenderTarget);
            mesh.Parameters.Set(TexturingKeys.Texture1, bbRenderTarget);
            mesh.Parameters.Set(RenderTargetKeys.RenderTarget, shaftRenderTarget);

            if (!useUpScaling)
            {
                mesh.Parameters.Set(EffectPlugin.BlendStateKey, additiveBlending);
            }
            RenderSystem.GlobalMeshes.AddMesh(mesh);

            // Bilateral Gaussian filtering for up-sampling
            if (useUpScaling)
            {
                var bbRenderTargetUpScaleH = Texture.New2D(GraphicsDevice, gbufferDesc.Width, gbufferDesc.Height / 2, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                var bbRenderTargetUpScaleV = RenderTarget;
                //var bbRenderTargetUpScaleV = GraphicsDevice.RenderTarget2D.New(gbufferDesc.Width, gbufferDesc.Height, PixelFormat.HalfVector4);

                var blurEffects = new EffectOld[] {
                                                   this.EffectSystemOld.BuildEffect("BilateralGaussianFiltering")
                                                       .Using(new PostEffectSeparateShaderPlugin())
                                                       .Using(new BasicShaderPlugin( new ShaderClassSource("PostEffectBilateralGaussian", 0))),
                                                   this.EffectSystemOld.BuildEffect("BilateralGaussianFiltering")
                                                       .Using(new StateShaderPlugin() { UseBlendState = true })
                                                       .Using(new PostEffectSeparateShaderPlugin())
                                                       .Using(new BasicShaderPlugin( new ShaderClassSource("PostEffectBilateralGaussian", 1))),
                                               };

                Texture2D textureSourceH = (Texture2D)shaftRenderTarget.Texture;
                Texture2D textureSourceV = bbRenderTargetUpScaleH;
                RenderTarget renderTargetH = bbRenderTargetUpScaleH.ToRenderTarget();
                RenderTarget renderTargetV = bbRenderTargetUpScaleV;

                var blurQuadMesh = new EffectMesh[2];
                for (int i = 0; i < 2; ++i)
                {
                    blurQuadMesh[i] = new EffectMesh(blurEffects[i]).KeepAliveBy(this);
                    filterUpscalePass.AddPass(blurQuadMesh[i].EffectPass);
                    RenderSystem.GlobalMeshes.AddMesh(blurQuadMesh[i]);
                }

                blurQuadMesh[0].Parameters.Set(TexturingKeys.Texture0, textureSourceH);
                blurQuadMesh[1].Parameters.Set(TexturingKeys.Texture0, textureSourceV);
                blurQuadMesh[0].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetH);
                blurQuadMesh[1].Parameters.Set(RenderTargetKeys.RenderTarget, renderTargetV);

                // Additive blending for 2nd render target
                blurQuadMesh[1].Parameters.Set(EffectPlugin.BlendStateKey, additiveBlending);
            }
        }