diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs index e94fbda3f..5ac2760eb 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs @@ -34,7 +34,7 @@ namespace Barotrauma { healthBar.Flash(); - damageOverlayTimer = MathHelper.Clamp(amount * 0.1f, 0.2f, 5.0f); + damageOverlayTimer = MathHelper.Clamp(amount * 0.1f, 0.2f, 1.0f); } public static void AddToGUIUpdateList(Character character) diff --git a/Barotrauma/BarotraumaClient/Source/Map/Lights/ConvexHull.cs b/Barotrauma/BarotraumaClient/Source/Map/Lights/ConvexHull.cs index 8c282c1e4..ca33df0bd 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Lights/ConvexHull.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Lights/ConvexHull.cs @@ -6,41 +6,6 @@ using System.Diagnostics; namespace Barotrauma.Lights { - /*class CachedShadow : IDisposable - { - public VertexBuffer ShadowBuffer; - - public Vector2 LightPos; - - public int ShadowVertexCount, PenumbraVertexCount; - - public CachedShadow(VertexPositionColor[] shadowVertices, Vector2 lightPos, int shadowVertexCount, int penumbraVertexCount) - { - //var ShadowVertices = new VertexPositionColor [shadowVertices.Count()]; - //shadowVertices.CopyTo(ShadowVertices, 0); - - ShadowBuffer = new VertexBuffer(GameMain.CurrGraphicsDevice, VertexPositionColor.VertexDeclaration, 6*2, BufferUsage.None); - ShadowBuffer.SetData(shadowVertices, 0, shadowVertices.Length); - - ShadowVertexCount = shadowVertexCount; - PenumbraVertexCount = penumbraVertexCount; - - LightPos = lightPos; - } - - public void Dispose() - { - Dispose(true); - - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - ShadowBuffer.Dispose(); - } - }*/ - class ConvexHullList { private List list; @@ -107,27 +72,30 @@ namespace Barotrauma.Lights class ConvexHull { public static List HullLists = new List(); - static BasicEffect shadowEffect; - static BasicEffect penumbraEffect; - - //private Dictionary cachedShadows; - - public VertexBuffer ShadowBuffer; - + public static BasicEffect shadowEffect; + public static BasicEffect penumbraEffect; + Segment[] segments = new Segment[4]; SegmentPoint[] vertices = new SegmentPoint[4]; SegmentPoint[] losVertices = new SegmentPoint[4]; - - //private Vector2[] vertices; - //private Vector2[] losVertices; - + private bool[] backFacing; private bool[] ignoreEdge; private VertexPositionColor[] shadowVertices; private VertexPositionTexture[] penumbraVertices; - - int shadowVertexCount; + + public VertexPositionColor[] ShadowVertices + { + get { return shadowVertices; } + } + + public VertexPositionTexture[] PenumbraVertices + { + get { return penumbraVertices; } + } + + public int shadowVertexCount; private Entity parentEntity; @@ -399,8 +367,14 @@ namespace Barotrauma.Lights } } - private void CalculateShadowVertices(Vector2 lightSourcePos, bool los = true) + public void CalculateShadowVertices(Vector2 lightSourcePos, bool los = true) { + Vector3 offset = Vector3.Zero; + if (parentEntity != null && parentEntity.Submarine != null) + { + offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); + } + shadowVertexCount = 0; var vertices = los ? losVertices : this.vertices; @@ -463,7 +437,7 @@ namespace Barotrauma.Lights //one vertex on the hull shadowVertices[i] = new VertexPositionColor(); shadowVertices[i].Color = los ? Color.Black : Color.Transparent; - shadowVertices[i].Position = vertexPos; + shadowVertices[i].Position = vertexPos+ offset; //one extruded by the light direction shadowVertices[j] = new VertexPositionColor(); @@ -472,7 +446,7 @@ namespace Barotrauma.Lights Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0); L2P.Normalize(); - shadowVertices[j].Position = new Vector3(lightSourcePos, 0) + L2P * 9000; + shadowVertices[j].Position = new Vector3(lightSourcePos, 0) + L2P * 9000 + offset; svCount += 2; currentIndex = (currentIndex + 1) % 4; @@ -486,12 +460,18 @@ namespace Barotrauma.Lights private void CalculatePenumbraVertices(int startingIndex, int endingIndex, Vector2 lightSourcePos, bool los) { + Vector3 offset = Vector3.Zero; + if (parentEntity != null && parentEntity.Submarine != null) + { + offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); + } + for (int n = 0; n < 4; n += 3) { Vector3 penumbraStart = new Vector3((n == 0) ? vertices[startingIndex].Pos : vertices[endingIndex].Pos, 0.0f); penumbraVertices[n] = new VertexPositionTexture(); - penumbraVertices[n].Position = penumbraStart; + penumbraVertices[n].Position = penumbraStart + offset; penumbraVertices[n].TextureCoordinate = new Vector2(0.0f, 1.0f); //penumbraVertices[0].te = fow ? Color.Black : Color.Transparent; @@ -506,7 +486,7 @@ namespace Barotrauma.Lights vertexDir = penumbraStart - (new Vector3(lightSourcePos, 0) - normal * 20.0f); vertexDir.Normalize(); - penumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000; + penumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000 + offset; if (los) { @@ -531,7 +511,7 @@ namespace Barotrauma.Lights { List list = new List(); - foreach (ConvexHullList chList in ConvexHull.HullLists) + foreach (ConvexHullList chList in HullLists) { Vector2 lightPos = position; if (ParentSub == null) @@ -581,85 +561,7 @@ namespace Barotrauma.Lights return list; } - - public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, LightSource light, Matrix transform, bool los = true) - { - if (!Enabled) return; - - Vector2 lightSourcePos = light.Position; - - if (parentEntity != null && parentEntity.Submarine != null) - { - if (light.ParentSub == null) - { - lightSourcePos -= parentEntity.Submarine.Position; - } - else if (light.ParentSub != parentEntity.Submarine) - { - lightSourcePos += (light.ParentSub.Position-parentEntity.Submarine.Position); - } - - } - - CalculateShadowVertices(lightSourcePos, los); - ShadowBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColor.VertexDeclaration, 6 * 2, BufferUsage.None); - ShadowBuffer.SetData(shadowVertices, 0, shadowVertices.Length); - - graphicsDevice.SetVertexBuffer(ShadowBuffer); - shadowVertexCount = shadowVertices.Length; - - DrawShadows(graphicsDevice, cam, transform, los); - } - - public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, Vector2 lightSourcePos, Matrix transform, bool los = true) - { - if (!Enabled) return; - - if (parentEntity != null && parentEntity.Submarine != null) lightSourcePos -= parentEntity.Submarine.Position; - - CalculateShadowVertices(lightSourcePos, los); - - DrawShadows(graphicsDevice, cam, transform, los); - } - - private void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, Matrix transform, bool los = true) - { - Vector3 offset = Vector3.Zero; - if (parentEntity != null && parentEntity.Submarine != null) - { - offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); - } - - if (shadowVertexCount>0) - { - shadowEffect.World = Matrix.CreateTranslation(offset) * transform; - - if (los) - { - shadowEffect.CurrentTechnique.Passes[0].Apply(); - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, shadowVertices, 0, shadowVertexCount * 2 - 2, VertexPositionColor.VertexDeclaration); - } - else - { - shadowEffect.CurrentTechnique.Passes[0].Apply(); - graphicsDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, shadowVertexCount * 2 - 2); - } - - } - - - if (los) - { - penumbraEffect.World = shadowEffect.World; - penumbraEffect.CurrentTechnique.Passes[0].Apply(); - -#if WINDOWS - graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, penumbraVertices, 0, 2, VertexPositionTexture.VertexDeclaration); -#endif - } - - } - + public void Remove() { var chList = HullLists.Find(x => x.Submarine == parentEntity.Submarine); diff --git a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs index eabdc3de3..017d7755b 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Lights/LightManager.cs @@ -38,7 +38,7 @@ namespace Barotrauma.Lights BasicEffect lightEffect; - public Effect losEffect + public Effect LosEffect { get; private set; } @@ -52,9 +52,8 @@ namespace Barotrauma.Lights public bool LightingEnabled = true; public bool ObstructVision; - LightSource losSource; - private Sprite visionCircle; + private Texture2D visionCircle; private Dictionary hullAmbientLights; private Dictionary smoothedHullAmbientLights; @@ -67,8 +66,8 @@ namespace Barotrauma.Lights AmbientLight = new Color(20, 20, 20, 255); - //visionCircle = Sprite.LoadTexture("Content/Lights/visioncircle.png"); - visionCircle = new Sprite("Content/Lights/visioncircle.png", new Vector2(0.2f, 0.5f)); + visionCircle = Sprite.LoadTexture("Content/Lights/visioncircle.png"); + //visionCircle = new Sprite("Content/Lights/visioncircle.png", new Vector2(0.2f, 0.5f)); var pp = graphics.PresentationParameters; @@ -78,13 +77,10 @@ namespace Barotrauma.Lights RenderTargetUsage.DiscardContents); losTexture = new RenderTarget2D(graphics, (int)(GameMain.GraphicsWidth*lightmapScale), (int)(GameMain.GraphicsHeight*lightmapScale), false, SurfaceFormat.Color, DepthFormat.None); - - losSource = new LightSource(Vector2.Zero, GameMain.GraphicsWidth, Color.White, null, false); - losSource.texture = new Texture2D(graphics, 1, 1); - losSource.texture.SetData(new Color[] { Color.White });// fill the texture with white + #if WINDOWS - losEffect = content.Load("losshader"); + LosEffect = content.Load("losshader"); #else losEffect = content.Load("losshader_opengl"); #endif @@ -241,43 +237,88 @@ namespace Barotrauma.Lights public void UpdateObstructVision(GraphicsDevice graphics, SpriteBatch spriteBatch, Camera cam, Vector2 lookAtPosition) { - if (!LosEnabled || ViewTarget == null) return; + if (!LosEnabled && !ObstructVision) return; graphics.SetRenderTarget(losTexture); - //-------------------------------------- + spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, cam.Transform * Matrix.CreateScale(new Vector3(lightmapScale, lightmapScale, 1.0f))); + - graphics.Clear(Color.Black); if (ObstructVision) { + graphics.Clear(Color.Black); Vector2 diff = lookAtPosition - ViewTarget.WorldPosition; + diff.Y = -diff.Y; float rotation = MathUtils.VectorToAngle(diff); - Vector2 scale = new Vector2(MathHelper.Clamp(diff.Length() / 256.0f, 2.0f, 5.0f), 2.0f) * 0.3f; + Vector2 scale = new Vector2( + MathHelper.Clamp(diff.Length() / 256.0f, 2.0f, 5.0f), 2.0f); - visionCircle.size = new Vector2(visionCircle.SourceRect.Width * scale.X, visionCircle.SourceRect.Height * scale.Y); - losSource.overrideLightTexture = visionCircle; - losSource.Rotation = rotation; + spriteBatch.Draw(visionCircle, new Vector2(ViewTarget.WorldPosition.X, -ViewTarget.WorldPosition.Y), null, Color.White, rotation, + new Vector2(LightSource.LightTexture.Width * 0.2f, LightSource.LightTexture.Height / 2), scale, SpriteEffects.None, 0.0f); } else { - losSource.overrideLightTexture = null; + graphics.Clear(Color.White); } - - graphics.BlendState = BlendState.Additive; - - Vector2 pos = ViewTarget.Position; - losSource.Position = pos; - losSource.NeedsRecalculation = true; - losSource.ParentSub = ViewTarget.Submarine; - - Matrix transform = cam.ShaderTransform - * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; + spriteBatch.End(); - losSource.Draw(spriteBatch, lightEffect, transform); - graphics.BlendState = BlendState.AlphaBlend; + //-------------------------------------- + if (LosEnabled && ViewTarget != null) + { + Vector2 pos = ViewTarget.WorldPosition; + + Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height); + + Matrix shadowTransform = cam.ShaderTransform + * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f; + + var convexHulls = ConvexHull.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine); + if (convexHulls != null) + { + List shadowVerts = new List(); + List penumbraVerts = new List(); + foreach (ConvexHull convexHull in convexHulls) + { + if (!convexHull.Enabled || !convexHull.Intersects(camView)) continue; + + Vector2 relativeLightPos = pos; + if (convexHull.ParentEntity?.Submarine != null) relativeLightPos -= convexHull.ParentEntity.Submarine.Position; + + convexHull.CalculateShadowVertices(relativeLightPos, true); + + //convert triangle strips to a triangle list + for (int i = 0; i < convexHull.shadowVertexCount * 2 - 2; i++) + { + if (i % 2 == 0) + { + shadowVerts.Add(convexHull.ShadowVertices[i]); + shadowVerts.Add(convexHull.ShadowVertices[i + 1]); + shadowVerts.Add(convexHull.ShadowVertices[i + 2]); + } + else + { + shadowVerts.Add(convexHull.ShadowVertices[i]); + shadowVerts.Add(convexHull.ShadowVertices[i + 2]); + shadowVerts.Add(convexHull.ShadowVertices[i + 1]); + } + } + + penumbraVerts.AddRange(convexHull.PenumbraVertices); + } + + ConvexHull.shadowEffect.World = shadowTransform; + ConvexHull.shadowEffect.CurrentTechnique.Passes[0].Apply(); + graphics.DrawUserPrimitives(PrimitiveType.TriangleList, shadowVerts.ToArray(), 0, shadowVerts.Count / 3, VertexPositionColor.VertexDeclaration); + + ConvexHull.penumbraEffect.World = shadowTransform; + ConvexHull.penumbraEffect.CurrentTechnique.Passes[0].Apply(); + graphics.DrawUserPrimitives(PrimitiveType.TriangleList, penumbraVerts.ToArray(), 0, penumbraVerts.Count / 3, VertexPositionTexture.VertexDeclaration); + + } + } graphics.SetRenderTarget(null); } @@ -361,19 +402,9 @@ namespace Barotrauma.Lights return hullAmbientLight; } - public void DrawLightMap(SpriteBatch spriteBatch, Effect effect) - { - if (!LightingEnabled) return; - - spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.Multiplicative, null, null, null, null); - spriteBatch.Draw(lightMap, new Rectangle(0,0,GameMain.GraphicsWidth,GameMain.GraphicsHeight), Color.White); - spriteBatch.End(); - } - public void ClearLights() { lights.Clear(); - losSource.Reset(); } } @@ -393,10 +424,16 @@ namespace Barotrauma.Lights MultiplyWithAlpha = new BlendState(); MultiplyWithAlpha.ColorDestinationBlend = MultiplyWithAlpha.AlphaDestinationBlend = Blend.One; MultiplyWithAlpha.ColorSourceBlend = MultiplyWithAlpha.AlphaSourceBlend = Blend.DestinationAlpha; + + LOS = new BlendState(); + LOS.ColorSourceBlend = LOS.AlphaSourceBlend = Blend.Zero; + LOS.ColorDestinationBlend = LOS.AlphaDestinationBlend = Blend.InverseSourceColor; + LOS.ColorBlendFunction = LOS.AlphaBlendFunction = BlendFunction.Add; } public static BlendState Multiplicative { get; private set; } public static BlendState WriteToAlpha { get; private set; } public static BlendState MultiplyWithAlpha { get; private set; } + public static BlendState LOS { get; private set; } } } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs index 954e9b58a..3c66a302b 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/GameScreen.cs @@ -231,19 +231,26 @@ namespace Barotrauma graphics.SetRenderTarget(null); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, null, null, null); - if (GameMain.LightManager.LosEnabled && Character.Controlled!=null) - { - float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f); - spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), - Color.Lerp(GameMain.LightManager.AmbientLight * 0.5f, Color.Red, r)); - spriteBatch.End(); - GameMain.LightManager.losEffect.CurrentTechnique = GameMain.LightManager.losEffect.Techniques["LosShader"]; - GameMain.LightManager.losEffect.Parameters["xTexture"].SetValue(renderTargetFinal); - GameMain.LightManager.losEffect.Parameters["xLosTexture"].SetValue(GameMain.LightManager.losTexture); - spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, null, GameMain.LightManager.losEffect, null); - } spriteBatch.Draw(renderTargetFinal, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); spriteBatch.End(); + + if (GameMain.LightManager.LosEnabled && Character.Controlled!=null) + { + GameMain.LightManager.LosEffect.CurrentTechnique = GameMain.LightManager.LosEffect.Techniques["LosShader"]; + GameMain.LightManager.LosEffect.Parameters["xTexture"].SetValue(renderTargetBackground); + GameMain.LightManager.LosEffect.Parameters["xLosTexture"].SetValue(GameMain.LightManager.losTexture); + + //convert the los color to HLS and make sure the luminance of the color is always the same regardless + //of the ambient light color and the luminance of the damage overlight color + float r = Math.Min(CharacterHUD.damageOverlayTimer * 0.5f, 0.5f); + Vector3 losColorHls = Color.Lerp(GameMain.LightManager.AmbientLight, Color.Red, r).RgbToHLS(); + losColorHls.Y = 0.1f; + Color losColor = ToolBox.HLSToRGB(losColorHls); + + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.PointClamp, null, null, GameMain.LightManager.LosEffect, null); + spriteBatch.Draw(renderTargetBackground, new Rectangle(0, 0, spriteBatch.GraphicsDevice.Viewport.Width, spriteBatch.GraphicsDevice.Viewport.Height), losColor); + spriteBatch.End(); + } } } } diff --git a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs index d2699c66e..6942c23ea 100644 --- a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs +++ b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs @@ -6,6 +6,91 @@ namespace Barotrauma { public static partial class ToolBox { + // Convert an RGB value into an HLS value. + public static Vector3 RgbToHLS(this Color color) + { + double h, l, s; + + // Convert RGB to a 0.0 to 1.0 range. + double double_r = color.R / 255.0; + double double_g = color.G / 255.0; + double double_b = color.B / 255.0; + + // Get the maximum and minimum RGB components. + double max = double_r; + if (max < double_g) max = double_g; + if (max < double_b) max = double_b; + + double min = double_r; + if (min > double_g) min = double_g; + if (min > double_b) min = double_b; + + double diff = max - min; + l = (max + min) / 2; + if (Math.Abs(diff) < 0.00001) + { + s = 0; + h = 0; // H is really undefined. + } + else + { + if (l <= 0.5) s = diff / (max + min); + else s = diff / (2 - max - min); + + double r_dist = (max - double_r) / diff; + double g_dist = (max - double_g) / diff; + double b_dist = (max - double_b) / diff; + + if (double_r == max) h = b_dist - g_dist; + else if (double_g == max) h = 2 + r_dist - b_dist; + else h = 4 + g_dist - r_dist; + + h = h * 60; + if (h < 0) h += 360; + } + + return new Vector3((float)h, (float)l, (float)s); + } + + // Convert an HLS value into an RGB value. + public static Color HLSToRGB(Vector3 hls) + { + double h = hls.X, l = hls.Y, s = hls.Z; + + double p2; + if (l <= 0.5) p2 = l * (1 + s); + else p2 = l + s - l * s; + + double p1 = 2 * l - p2; + double double_r, double_g, double_b; + if (s == 0) + { + double_r = l; + double_g = l; + double_b = l; + } + else + { + double_r = QqhToRgb(p1, p2, h + 120); + double_g = QqhToRgb(p1, p2, h); + double_b = QqhToRgb(p1, p2, h - 120); + } + + // Convert RGB to the 0 to 255 range. + return new Color((byte)(double_r * 255.0), (byte)(double_g * 255.0), (byte)(double_b * 255.0)); + } + + private static double QqhToRgb(double q1, double q2, double hue) + { + if (hue > 360) hue -= 360; + else if (hue < 0) hue += 360; + + if (hue < 60) return q1 + (q2 - q1) * hue / 60; + if (hue < 180) return q2; + if (hue < 240) return q1 + (q2 - q1) * (240 - hue) / 60; + return q1; + } + public static string LimitString(string str, ScalableFont font, int maxWidth) { if (maxWidth <= 0 || string.IsNullOrWhiteSpace(str)) return ""; diff --git a/Barotrauma/BarotraumaShared/Content/losshader.fx b/Barotrauma/BarotraumaShared/Content/losshader.fx index f2804689e..357e2bad9 100644 --- a/Barotrauma/BarotraumaShared/Content/losshader.fx +++ b/Barotrauma/BarotraumaShared/Content/losshader.fx @@ -7,10 +7,16 @@ sampler LosSampler = sampler_state { Texture = ; }; float4 main(float4 position : SV_Position, float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0 { + float4 sampleColor = xTexture.Sample(TextureSampler, texCoord); float4 losColor = xLosTexture.Sample(LosSampler, texCoord); - float4 sample = xTexture.Sample(TextureSampler, texCoord); - float4 outColor = float4(sample.x*losColor.x, sample.y*losColor.x, sample.z*losColor.x, losColor.x); + float obscureAmount = 1.0f - losColor.r; + + float4 outColor = float4( + sampleColor.r * color.r, + sampleColor.g * color.g, + sampleColor.b * color.b, + obscureAmount); return outColor; } diff --git a/Barotrauma/BarotraumaShared/Content/losshader.xnb b/Barotrauma/BarotraumaShared/Content/losshader.xnb index 47593ed70..a1898ad6d 100644 Binary files a/Barotrauma/BarotraumaShared/Content/losshader.xnb and b/Barotrauma/BarotraumaShared/Content/losshader.xnb differ