예제 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PostProcessingEffects"/> class.
 /// </summary>
 public PostProcessingEffects()
 {
     depthOfField         = new DepthOfField();
     luminanceEffect      = new LuminanceEffect();
     brightFilter         = new BrightFilter();
     bloom                = new Bloom();
     lightStreak          = new LightStreak();
     lensFlare            = new LensFlare();
     ssaa                 = new FXAAEffect();
     colorTransformsGroup = new ColorTransformGroup();
 }
예제 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PostProcessingEffects"/> class.
 /// </summary>
 public PostProcessingEffects()
 {
     depthOfField = new DepthOfField();
     luminanceEffect = new LuminanceEffect();
     brightFilter = new BrightFilter();
     bloom = new Bloom();
     lightStreak = new LightStreak();
     lensFlare = new LensFlare();
     ssaa = new FXAAEffect();
     colorTransformsGroup = new ColorTransformGroup();
 }
예제 #3
0
        protected override void InitializeCore()
        {
            base.InitializeCore();

            depthOfField         = ToLoadAndUnload(depthOfField);
            luminanceEffect      = ToLoadAndUnload(luminanceEffect);
            brightFilter         = ToLoadAndUnload(brightFilter);
            bloom                = ToLoadAndUnload(bloom);
            lightStreak          = ToLoadAndUnload(lightStreak);
            lensFlare            = ToLoadAndUnload(lensFlare);
            ssaa                 = ToLoadAndUnload(ssaa);
            colorTransformsGroup = ToLoadAndUnload(colorTransformsGroup);
        }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PostProcessingEffects"/> class.
 /// </summary>
 public PostProcessingEffects()
 {
     AmbientOcclusion     = new AmbientOcclusion();
     DepthOfField         = new DepthOfField();
     luminanceEffect      = new LuminanceEffect();
     BrightFilter         = new BrightFilter();
     Bloom                = new Bloom();
     LightStreak          = new LightStreak();
     LensFlare            = new LensFlare();
     Antialiasing         = new FXAAEffect();
     rangeCompress        = new ImageEffectShader("RangeCompressorShader");
     rangeDecompress      = new ImageEffectShader("RangeDecompressorShader");
     colorTransformsGroup = new ColorTransformGroup();
 }
예제 #5
0
        protected override void InitializeCore()
        {
            base.InitializeCore();

            depthOfField    = ToLoadAndUnload(depthOfField);
            luminanceEffect = ToLoadAndUnload(luminanceEffect);
            brightFilter    = ToLoadAndUnload(brightFilter);
            bloom           = ToLoadAndUnload(bloom);
            lightStreak     = ToLoadAndUnload(lightStreak);
            lensFlare       = ToLoadAndUnload(lensFlare);
            //this can be null if no SSAA is selected in the editor
            if (ssaa != null)
            {
                ssaa = ToLoadAndUnload(ssaa);
            }
            colorTransformsGroup = ToLoadAndUnload(colorTransformsGroup);
        }
예제 #6
0
        protected override void InitializeCore()
        {
            base.InitializeCore();

            depthOfField = ToLoadAndUnload(depthOfField);
            luminanceEffect = ToLoadAndUnload(luminanceEffect);
            brightFilter = ToLoadAndUnload(brightFilter);
            bloom = ToLoadAndUnload(bloom);
            lightStreak = ToLoadAndUnload(lightStreak);
            lensFlare = ToLoadAndUnload(lensFlare);
            ssaa = ToLoadAndUnload(ssaa);
            colorTransformsGroup = ToLoadAndUnload(colorTransformsGroup);
        }
예제 #7
0
        protected override void InitializeCore()
        {
            base.InitializeCore();

            depthOfField = ToLoadAndUnload(depthOfField);
            luminanceEffect = ToLoadAndUnload(luminanceEffect);
            brightFilter = ToLoadAndUnload(brightFilter);
            bloom = ToLoadAndUnload(bloom);
            lightStreak = ToLoadAndUnload(lightStreak);
            lensFlare = ToLoadAndUnload(lensFlare);
            //this can be null if no SSAA is selected in the editor
            if(ssaa != null) ssaa = ToLoadAndUnload(ssaa);
            colorTransformsGroup = ToLoadAndUnload(colorTransformsGroup);
        }
예제 #8
0
        public bool RequiresSsrGBuffers => false; // localReflections.Enabled; TODO : to merge with RLR branch.

        protected override void DrawCore(RenderDrawContext context)
        {
            var input  = GetInput(0);
            var output = GetOutput(0);

            if (input == null || output == null)
            {
                return;
            }

            var inputDepthTexture = GetInput(1); // Depth

            // Update the parameters for this post effect
            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);
                context.CommandList.Copy(input, newInput);
                input = newInput;
            }

            var currentInput = input;

            var  fxaa    = Antialiasing as FXAAEffect;
            bool aaFirst = Bloom != null && Bloom.StableConvolution;
            bool needAA  = fxaa != null && fxaa.Enabled;

            // do AA here, first. (hybrid method from Karis2013)
            if (aaFirst && needAA)
            {
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.HybridFxaa))
                {
                    // explanation:
                    // The Karis method (Unreal Engine 4.1x), uses a hybrid pipeline to execute AA.
                    // The AA is usually done at the end of the pipeline, but we don't benefit from
                    // AA for the posteffects, which is a shame.
                    // The Karis method, executes AA at the beginning, but for AA to be correct, it must work post tonemapping,
                    // and even more in fact, in gamma space too. Plus, it waits for the alpha=luma to be a "perceptive luma" so also gamma space.
                    // in our case, working in gamma space created monstruous outlining artefacts around eggageratedely strong constrasted objects (way in hdr range).
                    // so AA works in linear space, but still with gamma luma, as a light tradeoff to supress artefacts.

                    // create a 16 bits target for FXAA:
                    var aaSurface = NewScopedRenderTarget2D(input.Width, input.Height, input.Format);

                    // render range compression & perceptual luma to alpha channel:
                    rangeCompress.SetInput(currentInput);
                    rangeCompress.SetOutput(aaSurface);
                    rangeCompress.Draw(context);

                    // do AA:
                    fxaa.InputLuminanceInAlpha = true;
                    Antialiasing.SetInput(aaSurface);
                    Antialiasing.SetOutput(currentInput);
                    Antialiasing.Draw(context);

                    // reverse tone LDR to HDR:
                    rangeDecompress.SetInput(currentInput);
                    rangeDecompress.SetOutput(aaSurface);
                    rangeDecompress.Draw(context);
                    currentInput = aaSurface;
                }
            }

            if (AmbientOcclusion.Enabled && inputDepthTexture != null)
            {
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.AmbientOcclusion))
                {
                    // Ambient Occlusion
                    var aoOutput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format);
                    AmbientOcclusion.SetColorDepthInput(currentInput, inputDepthTexture);
                    AmbientOcclusion.SetOutput(aoOutput);
                    AmbientOcclusion.Draw(context);
                    currentInput = aoOutput;
                }
            }

            if (DepthOfField.Enabled && inputDepthTexture != null)
            {
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.DepthOfField))
                {
                    // DoF
                    var dofOutput = NewScopedRenderTarget2D(input.Width, input.Height, input.Format);
                    DepthOfField.SetColorDepthInput(currentInput, 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 && toneMap != null && toneMap.Enabled)
            {
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.AverageLumiance))
                {
                    Texture luminanceTexture = null;
                    if (toneMap.UseLocalLuminance)
                    {
                        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);
                        luminanceTexture = NewScopedRenderTarget2D(lumSize.Width, lumSize.Height, PixelFormat.R16_Float, 1);

                        luminanceEffect.SetOutput(luminanceTexture);
                    }

                    luminanceEffect.EnableLocalLuminanceCalculation = toneMap.UseLocalLuminance;
                    luminanceEffect.SetInput(currentInput);
                    luminanceEffect.Draw(context);

                    // Set this parameter that will be used by the tone mapping
                    colorTransformsGroup.Parameters.Set(LuminanceEffect.LuminanceResult, new LuminanceResult(luminanceEffect.AverageLuminance, luminanceTexture));
                }
            }

            if (BrightFilter.Enabled && (Bloom.Enabled || LightStreak.Enabled || LensFlare.Enabled))
            {
                Texture brightTexture = NewScopedRenderTarget2D(currentInput.Width, currentInput.Height, currentInput.Format, 1);
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.BrightFilter))
                {
                    // Bright filter pass

                    BrightFilter.SetInput(currentInput);
                    BrightFilter.SetOutput(brightTexture);
                    BrightFilter.Draw(context);
                }

                // Bloom pass
                if (Bloom.Enabled)
                {
                    using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.Bloom))
                    {
                        Bloom.SetInput(brightTexture);
                        Bloom.SetOutput(currentInput);
                        Bloom.Draw(context);
                    }
                }

                // Light streak pass
                if (LightStreak.Enabled)
                {
                    using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.LightStreak))
                    {
                        LightStreak.SetInput(brightTexture);
                        LightStreak.SetOutput(currentInput);
                        LightStreak.Draw(context);
                    }
                }

                // Lens flare pass
                if (LensFlare.Enabled)
                {
                    using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.LensFlare))
                    {
                        LensFlare.SetInput(brightTexture);
                        LensFlare.SetOutput(currentInput);
                        LensFlare.Draw(context);
                    }
                }
            }

            bool aaLast     = needAA && !aaFirst;
            var  toneOutput = aaLast ? NewScopedRenderTarget2D(input.Width, input.Height, input.Format) : output;

            // When FXAA is enabled we need to detect whether the ColorTransformGroup should output the Luminance into the alpha or not
            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;
            }

            using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.ColorTransformGroup))
            {
                // Color transform group pass (tonemap, color grading)
                var lastEffect = colorTransformsGroup.Enabled ? (ImageEffect)colorTransformsGroup : Scaler;
                lastEffect.SetInput(currentInput);
                lastEffect.SetOutput(toneOutput);
                lastEffect.Draw(context);
            }

            // do AA here, last, if not already done.
            if (aaLast)
            {
                using (context.QueryManager.BeginProfile(Color.Green, ImageEffectProfilingKeys.Fxaa))
                {
                    Antialiasing.SetInput(toneOutput);
                    Antialiasing.SetOutput(output);
                    Antialiasing.Draw(context);
                }
            }
        }