Initial steps in making the light rendering use light volumes instead of shadow volumes to allow rendering the lights in one batch.

So far just disabled shadow rendering and cleaned up some unnecessary stuff
This commit is contained in:
Regalis
2017-02-25 21:24:38 +02:00
parent c9f09031de
commit 844097b132
3 changed files with 70 additions and 91 deletions
@@ -397,6 +397,59 @@ namespace Barotrauma.Lights
}
}
public static List<ConvexHull> GetHullsInRange(Vector2 position, float range, Submarine ParentSub)
{
List<ConvexHull> list = new List<ConvexHull>();
foreach (ConvexHullList chList in ConvexHull.HullLists)
{
Vector2 lightPos = position;
if (ParentSub == null)
{
//light and the convexhull are both outside
if (chList.Submarine == null)
{
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
//light is outside, convexhull inside a sub
else
{
if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, chList.Submarine.Borders)) continue;
lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition);
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
}
else
{
//light is inside, convexhull outside
if (chList.Submarine == null) continue;
//light and convexhull are both inside the same sub
if (chList.Submarine == ParentSub)
{
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
//light and convexhull are inside different subs
else
{
lightPos -= (chList.Submarine.Position - ParentSub.Position);
Rectangle subBorders = chList.Submarine.Borders;
subBorders.Location += chList.Submarine.HiddenSubPosition.ToPoint() - new Point(0, chList.Submarine.Borders.Height);
if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) continue;
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
}
}
return list;
}
public void DrawShadows(GraphicsDevice graphicsDevice, Camera cam, LightSource light, Matrix transform, bool los = true)
{
if (!Enabled) return;
+3 -34
View File
@@ -133,45 +133,19 @@ namespace Barotrauma.Lights
//clear to some small ambient light
graphics.Clear(AmbientLight);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, cam.Transform);
foreach (LightSource light in lights)
{
if (light.Color.A < 1 || light.Range < 1.0f || !light.CastShadows) continue;
if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue;
//clear alpha to 1
ClearAlphaToOne(graphics, spriteBatch);
//draw all shadows
//write only to the alpha channel, which sets alpha to 0
graphics.RasterizerState = RasterizerState.CullNone;
graphics.BlendState = CustomBlendStates.WriteToAlpha;
light.DrawShadows(graphics, cam, shadowTransform);
//draw the light shape
//where Alpha is 0, nothing will be written
spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform);
light.Draw(spriteBatch);
spriteBatch.End();
}
ClearAlphaToOne(graphics, spriteBatch);
spriteBatch.Begin(SpriteSortMode.Deferred, CustomBlendStates.MultiplyWithAlpha, null, null, null, null, cam.Transform);
GameMain.ParticleManager.Draw(spriteBatch, false, Particles.ParticleBlendState.Additive);
foreach (LightSource light in lights)
{
if (light.Color.A < 1 || light.Range < 1.0f || light.CastShadows) continue;
//if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, light.Range, viewRect)) continue;
light.Draw(spriteBatch);
}
if (Character.Controlled != null)
{
if (Character.Controlled.ClosestItem != null)
@@ -185,10 +159,6 @@ namespace Barotrauma.Lights
Character.Controlled.ClosestCharacter.Draw(spriteBatch);
}
}
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, null, null, null, null, cam.Transform);
foreach (Hull hull in smoothedHullAmbientLights.Keys)
{
@@ -207,7 +177,6 @@ namespace Barotrauma.Lights
spriteBatch.End();
//clear alpha, to avoid messing stuff up later
ClearAlphaToOne(graphics, spriteBatch);
@@ -253,7 +222,7 @@ namespace Barotrauma.Lights
Matrix shadowTransform = cam.ShaderTransform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
var convexHulls = LightSource.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine);
var convexHulls = ConvexHull.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine);
if (convexHulls != null)
{
+14 -57
View File
@@ -136,7 +136,7 @@ namespace Barotrauma.Lights
GameMain.LightManager.AddLight(this);
}
public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform)
/*public void DrawShadows(GraphicsDevice graphics, Camera cam, Matrix shadowTransform)
{
if (!CastShadows) return;
if (range < 1.0f || color.A < 0.01f) return;
@@ -161,9 +161,9 @@ namespace Barotrauma.Lights
foreach (ConvexHull ch in outsideHulls)
{
ch.DrawShadows(graphics, cam, this, shadowTransform, false);
}
}
}
}
private List<ConvexHull> GetHullsInRange(Submarine sub)
{
//find the current list of hulls in range
@@ -237,62 +237,20 @@ namespace Barotrauma.Lights
}
return chList.List;
}
}*/
public static List<ConvexHull> GetHullsInRange(Vector2 position, float range, Submarine ParentSub)
private void CalculateFanVertices()
{
List<ConvexHull> list = new List<ConvexHull>();
if (!CastShadows) return;
if (range < 1.0f || color.A < 0.01f) return;
foreach (ConvexHullList chList in ConvexHull.HullLists)
{
Vector2 lightPos = position;
if (ParentSub == null)
{
//light and the convexhull are both outside
if (chList.Submarine == null)
{
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
//light is outside, convexhull inside a sub
else
{
if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, chList.Submarine.Borders)) continue;
lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition);
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
}
else
{
//light is inside, convexhull outside
if (chList.Submarine == null) continue;
//light and convexhull are both inside the same sub
if (chList.Submarine == ParentSub)
{
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
//light and convexhull are inside different subs
else
{
lightPos -= (chList.Submarine.Position - ParentSub.Position);
Rectangle subBorders = chList.Submarine.Borders;
subBorders.Location += chList.Submarine.HiddenSubPosition.ToPoint() - new Point(0, chList.Submarine.Borders.Height);
if (!MathUtils.CircleIntersectsRectangle(lightPos, range, subBorders)) continue;
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
}
}
}
return list;
var hulls = ConvexHull.GetHullsInRange(position, range, ParentSub);
//TODO: calculate fan based on hulls
//http://www.redblobgames.com/articles/visibility/
//http://roy-t.nl/index.php/2014/02/27/2d-lighting-and-shadows-preview/
}
public void Draw(SpriteBatch spriteBatch)
{
@@ -323,7 +281,6 @@ namespace Barotrauma.Lights
if (LightSprite != null)
{
LightSprite.Draw(spriteBatch, drawPos, Color, LightSprite.Origin, -Rotation, 1, SpriteEffect);
}
}