Example #1
0
        /// <summary>
        /// Applies a bloom effect to the specified render target, writes the result
        /// to the specified render target.
        /// </summary>
        /// <param name="source">The render target to use as the source</param>
        /// <param name="result">The render target to use as the result</param>
        public void Bloom(RenderTarget2D source, RenderTarget2D result, float threshold, float bloom_intensity, float base_intensity, float bloom_saturation, float base_saturation)
        {
            float sigma = 2.5f;
            int   scale = 1;

            IntermediateTexture downscaleTexture = GetIntermediateTexture(source.Width / scale, source.Height / scale, SurfaceFormat.Color);

            extractEffect.CurrentTechnique = extractEffect.Techniques["BloomExtract"];
            extractEffect.Parameters["BloomThreshold"].SetValue(threshold);
            PostProcess(source, downscaleTexture.RenderTarget, extractEffect);

            Blur(downscaleTexture.RenderTarget, downscaleTexture.RenderTarget, sigma);

            bloomEffect.CurrentTechnique = bloomEffect.Techniques["BloomCombine"];
            bloomEffect.Parameters["BloomIntensity"].SetValue(bloom_intensity);
            bloomEffect.Parameters["BaseIntensity"].SetValue(base_intensity);
            bloomEffect.Parameters["BloomSaturation"].SetValue(bloom_saturation);
            bloomEffect.Parameters["BaseSaturation"].SetValue(base_saturation);

            RenderTarget2D[] sources = new RenderTarget2D[2];
            sources[0] = downscaleTexture.RenderTarget;
            sources[1] = source;
            PostProcess(sources, result, bloomEffect);

            downscaleTexture.InUse = false;
        }
Example #2
0
        /// <summary>
        /// Downscales the source to 1/16th size, using software(shader) filtering
        /// </summary>
        /// <param name="source">The source to be downscaled</param>
        /// <param name="result">The RT in which to store the result</param>
        private void GenerateDownscaleTargetSW(RenderTarget2D source, RenderTarget2D result)
        {
            String techniqueName = "Downscale4";

            IntermediateTexture downscale1 = GetIntermediateTexture(source.Width / 4, source.Height / 4, source.Format);

            scalingEffect.CurrentTechnique = scalingEffect.Techniques[techniqueName];
            PostProcess(source, downscale1.RenderTarget, scalingEffect);

            scalingEffect.CurrentTechnique = scalingEffect.Techniques[techniqueName];
            PostProcess(downscale1.RenderTarget, result, scalingEffect);
            downscale1.InUse = false;
        }
Example #3
0
        protected IntermediateTexture GetIntermediateTexture(
            int width,
            int height,
            SurfaceFormat format,
            MultiSampleType msType,
            int msQuality)
        {
            width  = Math.Max(1, width);
            height = Math.Max(1, height);

            // Look for a matching rendertarget in the cache

            var match = _intermediateTextures.FirstOrDefault(
                t => !t.InUse &&
                height == t.RenderTarget.Height &&
                format == t.RenderTarget.Format &&
                width == t.RenderTarget.Width &&
                msType == t.RenderTarget.MultiSampleType &&
                msQuality == t.RenderTarget.MultiSampleQuality);

            if (match != null)
            {
                match.InUse = true;
                return(match);
            }

            // We didn't find one, let's make one
            var newTexture = new IntermediateTexture
            {
                RenderTarget = new RenderTarget2D(
                    _graphicsDevice,
                    width,
                    height,
                    1,
                    format,
                    msType,
                    msQuality,
                    RenderTargetUsage.DiscardContents)
            };

            _intermediateTextures.Add(newTexture);

            newTexture.InUse = true;

            return(newTexture);
        }
Example #4
0
        /// <summary>
        /// Applies a blur to the specified render target, writes the result
        /// to the specified render target.
        /// </summary>
        /// <param name="source">The render target to use as the source</param>
        /// <param name="result">The render target to use as the result</param>
        /// <param name="sigma">The standard deviation used for gaussian weights</param>
        public void Blur(RenderTarget2D source, RenderTarget2D result, float sigma)
        {
            IntermediateTexture blurH = GetIntermediateTexture(source.Width, source.Height, source.Format, source.MultiSampleCount);

            string baseTechniqueName = "GaussianBlur";

            // Do horizontal pass first
            blurEffect.CurrentTechnique = blurEffect.Techniques[baseTechniqueName + "H"];
            blurEffect.Parameters["g_fSigma"].SetValue(sigma);

            PostProcess(source, blurH.RenderTarget, blurEffect);

            // Now the vertical pass
            blurEffect.CurrentTechnique = blurEffect.Techniques[baseTechniqueName + "V"];

            PostProcess(blurH.RenderTarget, result, blurEffect);

            blurH.InUse = false;
        }
Example #5
0
        /// <summary>
        /// Downscales the source to 1/16th size, using hardware filtering
        /// </summary>
        /// <param name="source">The source to be downscaled</param>
        /// <param name="result">The RT in which to store the result</param>
        private void GenerateDownscaleTargetHW(RenderTarget2D source, RenderTarget2D result)
        {
            IntermediateTexture downscale1 = GetIntermediateTexture(source.Width / 2, source.Height / 2, source.Format);

            scalingEffect.CurrentTechnique = scalingEffect.Techniques["ScaleHW"];
            PostProcess(source, downscale1.RenderTarget, scalingEffect);

            IntermediateTexture downscale2 = GetIntermediateTexture(source.Width / 2, source.Height / 2, source.Format);

            scalingEffect.CurrentTechnique = scalingEffect.Techniques["ScaleHW"];
            PostProcess(downscale1.RenderTarget, downscale2.RenderTarget, scalingEffect);
            downscale1.InUse = false;

            IntermediateTexture downscale3 = GetIntermediateTexture(source.Width / 2, source.Height / 2, source.Format);

            scalingEffect.CurrentTechnique = scalingEffect.Techniques["ScaleHW"];
            PostProcess(downscale2.RenderTarget, downscale3.RenderTarget, scalingEffect);
            downscale2.InUse = false;

            scalingEffect.CurrentTechnique = scalingEffect.Techniques["ScaleHW"];
            PostProcess(downscale3.RenderTarget, result, scalingEffect);
            downscale3.InUse = false;
        }
Example #6
0
        private IntermediateTexture GetIntermediateTexture(int width, int height, SurfaceFormat format, int msQuality)
        {
            // Look for a matching rendertarget in the cache
            for (int i = 0; i < intermediateTextures.Count; i++)
            {
                if (intermediateTextures[i].InUse == false &&
                    height == intermediateTextures[i].RenderTarget.Height &&
                    format == intermediateTextures[i].RenderTarget.Format &&
                    width == intermediateTextures[i].RenderTarget.Width &&
                    msQuality == intermediateTextures[i].RenderTarget.MultiSampleCount)
                {
                    intermediateTextures[i].InUse = true;
                    return(intermediateTextures[i]);
                }
            }

            // We didn't find one, let's make one
            IntermediateTexture newTexture = new IntermediateTexture();

            newTexture.RenderTarget = new RenderTarget2D(device, width, height, false, format, DepthFormat.None, msQuality, RenderTargetUsage.DiscardContents);
            intermediateTextures.Add(newTexture);
            newTexture.InUse = true;
            return(newTexture);
        }
Example #7
0
        private IntermediateTexture GetIntermediateTexture(int width, int height, SurfaceFormat format, int msQuality)
        {
            // Look for a matching rendertarget in the cache
            for (int i = 0; i < intermediateTextures.Count; i++)
            {
                if (intermediateTextures[i].InUse == false
                    && height == intermediateTextures[i].RenderTarget.Height
                    && format == intermediateTextures[i].RenderTarget.Format
                    && width == intermediateTextures[i].RenderTarget.Width
                    && msQuality == intermediateTextures[i].RenderTarget.MultiSampleCount)
                {
                    intermediateTextures[i].InUse = true;
                    return intermediateTextures[i];
                }
            }

            // We didn't find one, let's make one
            IntermediateTexture newTexture = new IntermediateTexture();
            newTexture.RenderTarget = new RenderTarget2D(device, width, height, false, format, DepthFormat.None, msQuality, RenderTargetUsage.DiscardContents);
            intermediateTextures.Add(newTexture);
            newTexture.InUse = true;
            return newTexture;
        }
Example #8
0
        /// <summary>
        /// Performs tone mapping on the specified render target
        /// </summary>
        /// <param name="source">The source render target</param>
        /// <param name="result">The render target to which the result will be output</param>
        /// <param name="depthTexture">The render target containing scene depth</param>
        /// <param name="camera">The camera used to render the scene</param>
        /// <param name="dofType">The type of DOF effect to apply</param>
        /// <param name="focalDistance">The distance to the camera focal point</param>
        /// <param name="focalWidth">The width of the camera focal point</param>
        public void DepthOfField(RenderTarget2D source, RenderTarget2D result, RenderTarget2D depthTexture, Camera camera, DepthOfFieldType dofType, float focalDistance, float focalWidth, float time)
        {
            if (dofType == DepthOfFieldType.DiscBlur)
            {
                // Scale tap offsets based on render target size
                float dx = 0.5f / (float)source.Width;
                float dy = 0.5f / (float)source.Height;

                // Generate the texture coordinate offsets for our disc
                Vector2[] discOffsets = new Vector2[12];
                discOffsets[0]  = new Vector2(-0.326212f * dx, -0.40581f * dy);
                discOffsets[1]  = new Vector2(-0.840144f * dx, -0.07358f * dy);
                discOffsets[2]  = new Vector2(-0.840144f * dx, 0.457137f * dy);
                discOffsets[3]  = new Vector2(-0.203345f * dx, 0.620716f * dy);
                discOffsets[4]  = new Vector2(0.96234f * dx, -0.194983f * dy);
                discOffsets[5]  = new Vector2(0.473434f * dx, -0.480026f * dy);
                discOffsets[6]  = new Vector2(0.519456f * dx, 0.767022f * dy);
                discOffsets[7]  = new Vector2(0.185461f * dx, -0.893124f * dy);
                discOffsets[8]  = new Vector2(0.507431f * dx, 0.064425f * dy);
                discOffsets[9]  = new Vector2(0.89642f * dx, 0.412458f * dy);
                discOffsets[10] = new Vector2(-0.32194f * dx, -0.932615f * dy);
                discOffsets[11] = new Vector2(-0.791559f * dx, -0.59771f * dy);

                // Set array of offsets
                dofEffect.Parameters["g_vFilterTaps"].SetValue(discOffsets);

                dofEffect.CurrentTechnique = dofEffect.Techniques["DOFDiscBlur"];

                dofEffect.Parameters["g_fFocalDistance"].SetValue(focalDistance);
                dofEffect.Parameters["g_fFocalWidth"].SetValue(focalWidth / 2.0f);
                dofEffect.Parameters["g_fFarClip"].SetValue(camera.far);
                dofEffect.Parameters["g_fAttenuation"].SetValue(1);
                dofEffect.Parameters["time"].SetValue(time); //wave effect

                RenderTarget2D[] sources = doubleSourceArray;
                sources[0] = source;
                sources[1] = depthTexture;

                PostProcess(sources, result, dofEffect);
            }
            else
            {
                // Downscale to 1/16th size and blur
                IntermediateTexture downscaleTexture = GetIntermediateTexture(source.Width / 4, source.Height / 4, SurfaceFormat.Color);
                GenerateDownscaleTargetSW(source, downscaleTexture.RenderTarget);

                // For the "dumb" DOF type just do a blur, otherwise use a special blur
                // that takes depth into account
                if (dofType == DepthOfFieldType.BlurBuffer)
                {
                    Blur(downscaleTexture.RenderTarget, downscaleTexture.RenderTarget, 2.5f);
                }
                else if (dofType == DepthOfFieldType.BlurBufferDepthCorrection)
                {
                    DepthBlur(downscaleTexture.RenderTarget, downscaleTexture.RenderTarget, depthTexture, 2.5f);
                }


                dofEffect.CurrentTechnique = dofEffect.Techniques["DOFBlurBuffer"];

                dofEffect.Parameters["g_fFocalDistance"].SetValue(focalDistance);
                dofEffect.Parameters["g_fFocalWidth"].SetValue(focalWidth / 2.0f);
                dofEffect.Parameters["g_fFarClip"].SetValue(camera.far);
                dofEffect.Parameters["g_fAttenuation"].SetValue(1.0f);

                RenderTarget2D[] sources = tripleSourceArray;
                sources[0] = source;
                sources[1] = downscaleTexture.RenderTarget;
                sources[2] = depthTexture;

                PostProcess(sources, result, dofEffect);

                downscaleTexture.InUse = false;
            }
        }