public LightShaftsProcessor(MainPlugin mainPlugin, RenderTargetsPlugin mainTargetPlugin, RenderPass lightShaftsPass)
     : base(new PropertyKey[] { LightShaftsComponent.Key, LightComponent.Key })
 {
     this.mainPlugin       = mainPlugin;
     this.mainTargetPlugin = mainTargetPlugin;
     this.lightShaftsPass  = lightShaftsPass;
 }
示例#2
0
        public LightProcessor(LightingPlugin lightingPlugin, RenderTargetsPlugin renderTargetsPlugin, EffectOld lightEffect, bool enableIcons)
            : base(new PropertyKey[] { LightComponent.Key, TransformationComponent.Key })
        {
            this.enableIcons         = enableIcons;
            this.lightingPlugin      = lightingPlugin;
            this.lightEffect         = lightEffect;
            this.renderTargetsPlugin = renderTargetsPlugin;

            renderPassEnumerator = new RenderPassListEnumerator();
        }
示例#3
0
        public override void Load()
        {
            base.Load();

            RenderPass.AddPass(boundingBoxPass, heatShimmerPass, heatShimmerComposePass);

            // Use MinMax Plugin
            var bbRenderTargetPlugin = new RenderTargetsPlugin("BoundingBoxRenderTargetPlugin")
                {
                    EnableSetTargets = true,
                    EnableClearTarget = true,
                    RenderTarget = null,
                    RenderPass = boundingBoxPass,
                    Services = Services
                };
            bbRenderTargetPlugin.Apply();

            Parameters.AddSources(ViewParameters);
            Parameters.SetDefault(RenderTargetKeys.DepthStencilSource);
            Parameters.SetDefault(TexturingKeys.Sampler);
            bbRenderTargetPlugin.Parameters.AddSources(Parameters);

            EffectOld minMaxEffect = this.EffectSystemOld.BuildEffect("MinMax")
                .Using(new MinMaxShaderPlugin("MinMaxShaderPlugin") { RenderPassPlugin = bbRenderTargetPlugin })
                .Using(new BasicShaderPlugin("TransformationWVP") { RenderPassPlugin = bbRenderTargetPlugin })
                .KeepAliveBy(ActiveObjects)
                .InstantiatePermutation()
                .KeepAliveBy(ActiveObjects);

            heatShimmerPass.Parameters = new ParameterCollection();
            heatShimmerPass.Parameters.AddSources(Parameters);
            heatShimmerPass.Parameters.AddSources(NoisePlugin.Parameters);

            EffectOld heatShimmerEffect = this.EffectSystemOld.BuildEffect("HeatShimmer")
                .Using(new PostEffectSeparateShaderPlugin() { RenderPass = heatShimmerPass })
                .Using(
                    new BasicShaderPlugin(
                        new ShaderMixinSource()
                                        {
                                            Mixins = new List<ShaderClassSource>()
                                            {
                                            // TODO add support for IsZReverse
                                            //new ShaderClassSource("PostEffectHeatShimmer", Debug ? 1 : 0, effectSystemOld.IsZReverse ? 1 : 0, 3),
                                            new ShaderClassSource("PostEffectHeatShimmer", Debug ? 1 : 0, false ? 1 : 0, 3)},
                                            Compositions = new Dictionary<string, ShaderSource>() {
                                            {"NoiseSource", new ShaderClassSource("SimplexNoise")}},
                                            
                                        }
                        ) { RenderPass = heatShimmerPass })
                .KeepAliveBy(ActiveObjects)
                .InstantiatePermutation()
                .KeepAliveBy(ActiveObjects);

            EffectOld heatShimmerDisplayEffect = this.EffectSystemOld.BuildEffect("HeatShimmer")
                .Using(new PostEffectSeparateShaderPlugin() { RenderPass = heatShimmerComposePass })
                .Using(new BasicShaderPlugin(new ShaderClassSource("PostEffectHeatShimmerDisplay", Debug ? 1 : 0)) { RenderPass = heatShimmerComposePass })
                .KeepAliveBy(ActiveObjects)
                .InstantiatePermutation()
                .KeepAliveBy(ActiveObjects);

            if (OfflineCompilation)
                return;

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

            // ------------------------------------------
            // BoundingBox prepass
            // ------------------------------------------
            var renderTargetDesc = RenderSource.Description;
            var bbRenderTarget = Texture.New2D(GraphicsDevice, renderTargetDesc.Width, renderTargetDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects);

            bbRenderTargetPlugin.RenderTarget = bbRenderTarget.ToRenderTarget();

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

            // ------------------------------------------
            // Heat Compute
            // ------------------------------------------
            var shimmerTexture = Texture.New2D(GraphicsDevice, renderTargetDesc.Width, renderTargetDesc.Height, PixelFormat.R8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
            var shimmerRenderTarget = shimmerTexture.ToRenderTarget();
            heatShimmerPass.StartPass += context => context.GraphicsDevice.Clear(shimmerRenderTarget, Color.Black);

            var quadMesh = new EffectMesh(heatShimmerEffect).KeepAliveBy(ActiveObjects);
            quadMesh.Parameters.Set(TexturingKeys.Texture1, bbRenderTarget);
            quadMesh.Parameters.Set(RenderTargetKeys.RenderTarget, shimmerRenderTarget);

            effectMeshes.Add(quadMesh);
            RenderSystem.GlobalMeshes.AddMesh(quadMesh);

            // ------------------------------------------
            // Heat display
            // ------------------------------------------
            quadMesh = new EffectMesh(heatShimmerDisplayEffect).KeepAliveBy(ActiveObjects);
            quadMesh.Parameters.Set(TexturingKeys.Texture0, RenderSource);
            quadMesh.Parameters.Set(TexturingKeys.Texture1, shimmerTexture);
            quadMesh.Parameters.Set(RenderTargetKeys.RenderTarget, RenderTarget);

            effectMeshes.Add(quadMesh);
            RenderSystem.GlobalMeshes.AddMesh(quadMesh);
        }
示例#4
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);
            }
        }
示例#5
0
        public override void Load()
        {
            base.Load();

            if (OfflineCompilation)
                return;

            // Declare post render pass
            PostPass = new RenderPass("PostPass").KeepAliveBy(ActiveObjects);
            RenderPass.AddPass(PostPass);


            var depthStencilTexture = Texture.New2D(GraphicsDevice, AtlasSize, AtlasSize, PixelFormat.D32_Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource).KeepAliveBy(ActiveObjects);
            var depthStencilBuffer = depthStencilTexture.ToDepthStencilBuffer(false);
            ShadowMapDepth = depthStencilBuffer;

            //MainTargetPlugin.Parameters.Set(ShadowMapKeys.Texture0, ShadowMapDepth);

            // Setup clear of this target
            var renderTargetPlugin = new RenderTargetsPlugin
                {
                    Services = Services,
                    EnableClearDepth = true,
                    EnableSetTargets = false,
                    RenderPass = RenderPass,
                    RenderTarget = null,
                    DepthStencil = depthStencilBuffer,
                };
            renderTargetPlugin.Apply();

            // Use Default ZTest for GBuffer
            depthStencilStateZStandard = DepthStencilState.New(GraphicsDevice, new DepthStencilStateDescription().Default()).KeepAliveBy(ActiveObjects);
            depthStencilStateZStandard.Name = "ZStandard";

            Parameters.Set(EffectPlugin.DepthStencilStateKey, depthStencilStateZStandard);

            casterRasterizerState = RasterizerState.New(GraphicsDevice, new RasterizerStateDescription(CullMode.Back)).KeepAliveBy(ActiveObjects);

            // Variance Shadow Mapping
            // Create the blur temporary texture
            var shadowMapTextureDesc = ShadowMapDepth.Description;
            var shadowMapBlurH = Texture.New2D(GraphicsDevice, shadowMapTextureDesc.Width, shadowMapTextureDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects);
            var shadowMapBlurV = Texture.New2D(GraphicsDevice, shadowMapTextureDesc.Width, shadowMapTextureDesc.Height, PixelFormat.R32G32_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget).KeepAliveBy(ActiveObjects);

            Texture2D textureSourceH = ShadowMapDepth.Texture;
            Texture2D textureSourceV = shadowMapBlurH;
            RenderTarget renderTargetH = shadowMapBlurH.ToRenderTarget();
            RenderTarget renderTargetV = shadowMapBlurV.ToRenderTarget();

            var blurQuadMesh = new EffectMesh[2];
            for (int j = 0; j < BlurCount; j++)
            {
                for (int i = 0; i < 2; ++i)
                {
                    blurQuadMesh[i] = new EffectMesh(j > 0 ? blurEffects[1] : blurEffects[i]).KeepAliveBy(ActiveObjects);
                    blurQuadMesh[i].Parameters.Set(PostEffectBlurKeys.Coefficients, new[] { 0.2270270270f, 0.3162162162f, 0.3162162162f, 0.0702702703f, 0.0702702703f });
                    var unit = i == 0 ? Vector2.UnitX : Vector2.UnitY;
                    blurQuadMesh[i].Parameters.Set(PostEffectBlurKeys.Offsets, new[] { Vector2.Zero, unit * -1.3846153846f, unit * +1.3846153846f, unit * -3.2307692308f, unit * +3.2307692308f });

                    PostPass.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);

                textureSourceH = shadowMapBlurV;
                textureSourceV = shadowMapBlurH;
            }

            ShadowMapVsm = shadowMapBlurV;

            // Final texture for VSM is result of blur
            //MainTargetPlugin.Parameters.Set(ShadowMapKeys.Texture0, shadowMapBlurV);
        }