protected override void DrawCore(RenderContext context) { var input = GetInput(0); var output = GetOutput(0); if (input == null || output == null) { return; } // Gets the current camera state var camera = context.GetCameraFromSlot(Camera); if (camera != null) { // Update the parameters for this post effect CameraComponentRenderer.UpdateParameters(context, camera); } if (!Enabled) { if (input != output) { Scaler.SetInput(input); Scaler.SetOutput(output); Scaler.Draw(context); } return; } // If input == output, than copy the input to a temporary texture if (input == output) { var newInput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format); GraphicsDevice.Copy(input, newInput); input = newInput; } var currentInput = input; if (depthOfField.Enabled && !depthOfField.Faulted && InputCount > 1 && GetInput(1) != null && GetInput(1).IsDepthStencil) { // DoF var dofOutput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format); var inputDepthTexture = GetInput(1); // Depth depthOfField.SetColorDepthInput(input, inputDepthTexture); depthOfField.SetOutput(dofOutput); depthOfField.Draw(context); currentInput = dofOutput; } // Luminance pass (only if tone mapping is enabled) // TODO: This is not super pluggable to have this kind of dependencies. Check how to improve this var toneMap = colorTransformsGroup.Transforms.Get <ToneMap>(); if (colorTransformsGroup.Enabled && !colorTransformsGroup.Faulted && toneMap != null && toneMap.Enabled) { const int LocalLuminanceDownScale = 3; // The luminance chain uses power-of-two intermediate targets, so it expects to output to one as well var lumWidth = Math.Min(MathUtil.NextPowerOfTwo(currentInput.Size.Width), MathUtil.NextPowerOfTwo(currentInput.Size.Height)); lumWidth = Math.Max(1, lumWidth / 2); var lumSize = new Size3(lumWidth, lumWidth, 1).Down2(LocalLuminanceDownScale); var luminanceTexture = NewScopedRenderTarget2D(lumSize.Width, lumSize.Height, PixelFormat.R16_Float, 1); luminanceEffect.SetInput(currentInput); luminanceEffect.SetOutput(luminanceTexture); luminanceEffect.Draw(context); // Set this parameter that will be used by the tone mapping colorTransformsGroup.Parameters.Set(LuminanceEffect.LuminanceResult, new LuminanceResult(luminanceEffect.AverageLuminance, luminanceTexture)); } // Bright filter pass Texture brightTexture = null; if ((bloom.Enabled && !bloom.Faulted) || (lightStreak.Enabled && !lightStreak.Faulted) || (lensFlare.Enabled && !lensFlare.Faulted)) { brightTexture = NewScopedRenderTarget2D(currentInput.Width, currentInput.Height, currentInput.Format, 1); brightFilter.SetInput(currentInput); brightFilter.SetOutput(brightTexture); brightFilter.Draw(context); } // Bloom pass if (bloom.Enabled && !bloom.Faulted) { bloom.SetInput(brightTexture); bloom.SetOutput(currentInput); bloom.Draw(context); } // Light streak pass if (lightStreak.Enabled && !lightStreak.Faulted) { lightStreak.SetInput(brightTexture); lightStreak.SetOutput(currentInput); lightStreak.Draw(context); } // Lens flare pass if (lensFlare.Enabled && !lensFlare.Faulted) { lensFlare.SetInput(brightTexture); lensFlare.SetOutput(currentInput); lensFlare.Draw(context); } var outputForLastEffectBeforeAntiAliasing = output; if (ssaa != null && ssaa.Enabled && !ssaa.Faulted) { outputForLastEffectBeforeAntiAliasing = NewScopedRenderTarget2D(output.Width, output.Height, output.Format); } // When FXAA is enabled we need to detect whether the ColorTransformGroup should output the Luminance into the alpha or not var fxaa = ssaa as FXAAEffect; var luminanceToChannelTransform = colorTransformsGroup.PostTransforms.Get <LuminanceToChannelTransform>(); if (fxaa != null) { if (luminanceToChannelTransform == null) { luminanceToChannelTransform = new LuminanceToChannelTransform { ColorChannel = ColorChannel.A }; colorTransformsGroup.PostTransforms.Add(luminanceToChannelTransform); } // Only enabled when FXAA is enabled and InputLuminanceInAlpha is true luminanceToChannelTransform.Enabled = fxaa.Enabled && fxaa.InputLuminanceInAlpha; } else if (luminanceToChannelTransform != null) { luminanceToChannelTransform.Enabled = false; } // Color transform group pass (tonemap, color grading) var lastEffect = colorTransformsGroup.Enabled && !colorTransformsGroup.Faulted ? (ImageEffect)colorTransformsGroup: Scaler; lastEffect.SetInput(currentInput); lastEffect.SetOutput(outputForLastEffectBeforeAntiAliasing); lastEffect.Draw(context); if (ssaa != null && ssaa.Enabled && !ssaa.Faulted) { ssaa.SetInput(outputForLastEffectBeforeAntiAliasing); ssaa.SetOutput(output); ssaa.Draw(context); } }
protected override void DrawCore(RenderContext context) { var input = GetInput(0); var output = GetOutput(0); if (input == null || output == null) { return; } // Gets the current camera state var camera = context.GetCameraFromSlot(Camera); if (camera != null) { // Update the parameters for this post effect CameraComponentRenderer.UpdateParameters(context, camera); } if (!Enabled) { if (input != output) { Scaler.SetInput(input); Scaler.SetOutput(output); Scaler.Draw(context); } return; } // If input == output, than copy the input to a temporary texture if (input == output) { var newInput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format); GraphicsDevice.Copy(input, newInput); input = newInput; } var currentInput = input; if (depthOfField.Enabled && InputCount > 1 && GetInput(1) != null && GetInput(1).IsDepthStencil) { // DoF var dofOutput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format); var inputDepthTexture = GetInput(1); // Depth depthOfField.SetColorDepthInput(input, inputDepthTexture); depthOfField.SetOutput(dofOutput); depthOfField.Draw(context); currentInput = dofOutput; } // Luminance pass (only if tone mapping is enabled) // TODO: This is not super pluggable to have this kind of dependencies. Check how to improve this if (colorTransformsGroup.Enabled && colorTransformsGroup.Transforms.IsEnabled <ToneMap>()) { const int LocalLuminanceDownScale = 3; var lumSize = currentInput.Size.Down2(LocalLuminanceDownScale); var luminanceTexture = NewScopedRenderTarget2D(lumSize.Width, lumSize.Height, PixelFormat.R16_Float, 1); luminanceEffect.SetInput(currentInput); luminanceEffect.SetOutput(luminanceTexture); luminanceEffect.Draw(context); // Set this parameter that will be used by the tone mapping colorTransformsGroup.Parameters.Set(LuminanceEffect.LuminanceResult, new LuminanceResult(luminanceEffect.AverageLuminance, luminanceTexture)); } // Bright filter pass Texture brightTexture = null; if (bloom.Enabled || lightStreak.Enabled || lensFlare.Enabled) { brightTexture = NewScopedRenderTarget2D(currentInput.Width, currentInput.Height, currentInput.Format, 1); brightFilter.SetInput(currentInput); brightFilter.SetOutput(brightTexture); brightFilter.Draw(context); } // Bloom pass if (bloom.Enabled) { bloom.SetInput(brightTexture); bloom.SetOutput(currentInput); bloom.Draw(context); } // Light streak pass if (lightStreak.Enabled) { lightStreak.SetInput(brightTexture); lightStreak.SetOutput(currentInput); lightStreak.Draw(context); } // Lens flare pass if (lensFlare.Enabled) { lensFlare.SetInput(brightTexture); lensFlare.SetOutput(currentInput); lensFlare.Draw(context); } var outputForLastEffectBeforeAntiAliasing = output; if (ssaa != null && ssaa.Enabled) { outputForLastEffectBeforeAntiAliasing = NewScopedRenderTarget2D(output.Width, output.Height, output.Format); } // Color transform group pass (tonemap, color grading, gamma correction) var lastEffect = colorTransformsGroup.Enabled ? (ImageEffect)colorTransformsGroup: Scaler; lastEffect.SetInput(currentInput); lastEffect.SetOutput(outputForLastEffectBeforeAntiAliasing); lastEffect.Draw(context); if (ssaa != null && ssaa.Enabled) { ssaa.SetInput(outputForLastEffectBeforeAntiAliasing); ssaa.SetOutput(output); ssaa.Draw(context); } }