BlurEffect refactoring: separate class for setting up the effect instead of methods in GameScreen

This commit is contained in:
Regalis
2016-05-11 20:17:34 +03:00
parent 6537751961
commit 5e951bc225
3 changed files with 107 additions and 81 deletions

View File

@@ -155,6 +155,7 @@
<Compile Include="Source\Networking\ServerLog.cs" />
<Compile Include="Source\Particles\ParticleEmitter.cs" />
<Compile Include="Source\Networking\GameServerSettings.cs" />
<Compile Include="Source\Screens\BlurEffect.cs" />
<Compile Include="Source\Screens\NetLobbyVoting.cs" />
<Compile Include="Source\Screens\ServerListScreen.cs" />
<Compile Include="Source\Utils\MTRandom.cs" />

View File

@@ -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);
}
/// <summary>
/// Computes sample weightings and texture coordinate offsets
/// for one pass of a separable gaussian blur filter.
/// </summary>
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);
}
/// <summary>
/// Evaluates a single point on the gaussian falloff curve.
/// Used for setting up the blur filter weightings.
/// </summary>
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)));
}
}
}

View File

@@ -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<Effect>("blurshader");
SetBlurEffectParameters(0.001f, 0.001f);
var blurEffect = content.Load<Effect>("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
}
}
/// <summary>
/// Computes sample weightings and texture coordinate offsets
/// for one pass of a separable gaussian blur filter.
/// </summary>
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);
}
/// <summary>
/// Evaluates a single point on the gaussian falloff curve.
/// Used for setting up the blur filter weightings.
/// </summary>
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)));
}
}
}