From 5e951bc225baa1149a84b6f6d80deb2ca3979891 Mon Sep 17 00:00:00 2001 From: Regalis Date: Wed, 11 May 2016 20:17:34 +0300 Subject: [PATCH] BlurEffect refactoring: separate class for setting up the effect instead of methods in GameScreen --- Subsurface/Barotrauma.csproj | 1 + Subsurface/Source/Screens/BlurEffect.cs | 97 +++++++++++++++++++++++++ Subsurface/Source/Screens/GameScreen.cs | 90 +++-------------------- 3 files changed, 107 insertions(+), 81 deletions(-) create mode 100644 Subsurface/Source/Screens/BlurEffect.cs diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index a5b098ca6..972088085 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -155,6 +155,7 @@ + diff --git a/Subsurface/Source/Screens/BlurEffect.cs b/Subsurface/Source/Screens/BlurEffect.cs new file mode 100644 index 000000000..132931ab7 --- /dev/null +++ b/Subsurface/Source/Screens/BlurEffect.cs @@ -0,0 +1,97 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Barotrauma +{ + class BlurEffect + { + public readonly Effect Effect; + + public BlurEffect(Effect effect, float dx, float dy) + { + Effect = effect; + + SetParameters(dx, dy); + } + + + /// + /// Computes sample weightings and texture coordinate offsets + /// for one pass of a separable gaussian blur filter. + /// + public void SetParameters(float dx, float dy) + { + EffectParameter weightsParameter = Effect.Parameters["SampleWeights"]; + EffectParameter offsetsParameter = Effect.Parameters["SampleOffsets"]; + + // Look up how many samples our gaussian blur effect supports. + int sampleCount = weightsParameter.Elements.Count; + + // Create temporary arrays for computing our filter settings. + float[] sampleWeights = new float[sampleCount]; + Vector2[] sampleOffsets = new Vector2[sampleCount]; + + sampleWeights[0] = ComputeGaussian(0); + sampleOffsets[0] = new Vector2(0); + + float totalWeights = sampleWeights[0]; + + // Add pairs of additional sample taps, positioned + // along a line in both directions from the center. + for (int i = 0; i < sampleCount / 2; i++) + { + // Store weights for the positive and negative taps. + float weight = ComputeGaussian(i + 1); + + sampleWeights[i * 2 + 1] = weight; + sampleWeights[i * 2 + 2] = weight; + + totalWeights += weight * 2; + + // To get the maximum amount of blurring from a limited number of + // pixel shader samples, we take advantage of the bilinear filtering + // hardware inside the texture fetch unit. If we position our texture + // coordinates exactly halfway between two texels, the filtering unit + // will average them for us, giving two samples for the price of one. + // This allows us to step in units of two texels per sample, rather + // than just one at a time. The 1.5 offset kicks things off by + // positioning us nicely in between two texels. + float sampleOffset = i * 2 + 1.5f; + + Vector2 delta = new Vector2(dx, dy) * sampleOffset; + + // Store texture coordinate offsets for the positive and negative taps. + sampleOffsets[i * 2 + 1] = delta; + sampleOffsets[i * 2 + 2] = -delta; + } + + // Normalize the list of sample weightings, so they will always sum to one. + for (int i = 0; i < sampleWeights.Length; i++) + { + sampleWeights[i] /= totalWeights; + } + + weightsParameter.SetValue(sampleWeights); + offsetsParameter.SetValue(sampleOffsets); + } + + + /// + /// Evaluates a single point on the gaussian falloff curve. + /// Used for setting up the blur filter weightings. + /// + float ComputeGaussian(float n) + { + float theta = 4.0f; + + return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) * + Math.Exp(-(n * n) / (2 * theta * theta))); + } + + } +} diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 7b535ff04..b045ef892 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -16,7 +16,7 @@ namespace Barotrauma readonly RenderTarget2D renderTargetWater; readonly RenderTarget2D renderTargetAir; - Effect blurEffect; + private BlurEffect lightBlur; public BackgroundCreatureManager BackgroundCreatureManager; @@ -36,8 +36,11 @@ namespace Barotrauma BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml"); - blurEffect = content.Load("blurshader"); - SetBlurEffectParameters(0.001f, 0.001f); + var blurEffect = content.Load("blurshader"); + + lightBlur = new BlurEffect(blurEffect, 0.001f, 0.001f); + + } public override void Select() @@ -306,19 +309,16 @@ namespace Barotrauma foreach (Character c in Character.CharacterList) c.DrawFront(spriteBatch); Submarine.DrawFront(spriteBatch); - - - + if (Level.Loaded!=null) Level.Loaded.DrawFront(spriteBatch); spriteBatch.End(); - - GameMain.LightManager.DrawLightMap(spriteBatch, cam, blurEffect); + GameMain.LightManager.DrawLightMap(spriteBatch, cam, lightBlur.Effect); if (Character.Controlled != null) { - GameMain.LightManager.DrawLOS(graphics, spriteBatch, cam, blurEffect); + GameMain.LightManager.DrawLOS(graphics, spriteBatch, cam, lightBlur.Effect); } } @@ -343,77 +343,5 @@ namespace Barotrauma } } - /// - /// Computes sample weightings and texture coordinate offsets - /// for one pass of a separable gaussian blur filter. - /// - void SetBlurEffectParameters(float dx, float dy) - { - EffectParameter weightsParameter = blurEffect.Parameters["SampleWeights"]; - EffectParameter offsetsParameter = blurEffect.Parameters["SampleOffsets"]; - - // Look up how many samples our gaussian blur effect supports. - int sampleCount = weightsParameter.Elements.Count; - - // Create temporary arrays for computing our filter settings. - float[] sampleWeights = new float[sampleCount]; - Vector2[] sampleOffsets = new Vector2[sampleCount]; - - sampleWeights[0] = ComputeGaussian(0); - sampleOffsets[0] = new Vector2(0); - - float totalWeights = sampleWeights[0]; - - // Add pairs of additional sample taps, positioned - // along a line in both directions from the center. - for (int i = 0; i < sampleCount / 2; i++) - { - // Store weights for the positive and negative taps. - float weight = ComputeGaussian(i + 1); - - sampleWeights[i * 2 + 1] = weight; - sampleWeights[i * 2 + 2] = weight; - - totalWeights += weight * 2; - - // To get the maximum amount of blurring from a limited number of - // pixel shader samples, we take advantage of the bilinear filtering - // hardware inside the texture fetch unit. If we position our texture - // coordinates exactly halfway between two texels, the filtering unit - // will average them for us, giving two samples for the price of one. - // This allows us to step in units of two texels per sample, rather - // than just one at a time. The 1.5 offset kicks things off by - // positioning us nicely in between two texels. - float sampleOffset = i * 2 + 1.5f; - - Vector2 delta = new Vector2(dx, dy) * sampleOffset; - - // Store texture coordinate offsets for the positive and negative taps. - sampleOffsets[i * 2 + 1] = delta; - sampleOffsets[i * 2 + 2] = -delta; - } - - // Normalize the list of sample weightings, so they will always sum to one. - for (int i = 0; i < sampleWeights.Length; i++) - { - sampleWeights[i] /= totalWeights; - } - - weightsParameter.SetValue(sampleWeights); - offsetsParameter.SetValue(sampleOffsets); - } - - - /// - /// Evaluates a single point on the gaussian falloff curve. - /// Used for setting up the blur filter weightings. - /// - float ComputeGaussian(float n) - { - float theta = 4.0f; - - return (float)((1.0 / Math.Sqrt(2 * Math.PI * theta)) * - Math.Exp(-(n * n) / (2 * theta * theta))); - } } }