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); }
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); } }
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 = Texture2D.New(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 = Texture2D.New(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); }