public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight) { GD.SetRenderTarget(ShadowTarg); var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight); DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS)?2:0, pointLight); }
public void DrawShadows(Tuple <GradVertex[], int[]> geom, int pass, LightData light) { var pointLight = light.LightPos; var effect = this.GradEffect; effect.Parameters["Projection"].SetValue(Projection); GD.ScissorRectangle = DrawRect; GD.Clear(Color.Black); /*GD.SetRenderTarget(ShadowTarg); * if (!cleared) * { * cleared = true; * //GD.RasterizerState = new RasterizerState() { ScissorTestEnable = true, CullMode = CullMode.None }; * //GD.ScissorRectangle = new Rectangle((int)pointLight.X / 2 - 100, (int)pointLight.Y / 2 - 100, 200, 200); * GD.Clear(Color.Black); * }*/ effect.CurrentTechnique = effect.Techniques[0]; EffectPassCollection passes = effect.Techniques[0].Passes; passes[pass].Apply(); if (geom.Item1.Length > 0) { GD.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, geom.Item1, 0, geom.Item1.Length, geom.Item2, 0, geom.Item2.Length / 3); } //GD.SetRenderTarget(null); }
public Matrix GetSunlightMat(LightData pointLight) { var mat = Matrix.Identity; //we have to build our own matrix here, which is weird //the y axis has to contribute to the other two axis, using the light direction. mat.M11 = 1; mat.M12 = 0; mat.M31 = pointLight.LightDir.X; //; //x axis. mat.M21 = 0; mat.M22 = 1; mat.M32 = pointLight.LightDir.Y; //light.LightDir.Y; //y axis. mat.M33 = 0; mat = Matrix.CreateScale(16, 16, 32 * pointLight.FalloffMultiplier) * mat; return(mat); }
public void DrawObjShadows(List <Rectangle> objects, LightData pointLight) { GD.SetRenderTarget(ObjShadowTarg); Tuple <GradVertex[], int[]> geom; if (pointLight.LightType == LightType.ROOM) { geom = ShadowGeometry.GenerateObjShadows(objects.Where(x => x.Intersects(pointLight.LightBounds)).ToList(), pointLight); } else { geom = ShadowGeometry.GenerateObjShadows(objects, pointLight); } DrawShadows(geom, 1, pointLight); }
public Matrix GetLightMat(LightData pointLight) { //point light projection onto a floor surface. //this can get a bit weird! //we need to create a frustrum that starts at the light's position, and with all edges on the edge of the lightmap var height = pointLight.Height; //lights are assumed to be in the middle var tan = ((Blueprint.Width - borderSize) / 2f) / height; var fov = (float)Math.Atan(tan); var lpos = new Vector2(pointLight.LightPos.X / 16f, pointLight.LightPos.Y / 16f); //return Matrix.CreateTranslation(-lpos.X, -lpos.Y, height) * Matrix.CreatePerspectiveFieldOfView(fov, 1, 0.01f, 3f) * Matrix.CreateTranslation(lpos.X, lpos.Y, 0); var mat = Matrix.CreateTranslation(-(lpos.X), -(lpos.Y), -height) * ProjFromTan(tan, 1, 0.01f, height) * Matrix.CreateScale(1, -1f, 1) * Matrix.CreateTranslation(lpos.X / (Blueprint.Width - borderSize) * 2 - 1f, -(lpos.Y / ((Blueprint.Height - borderSize) / 2f) - 1f), 0); return(mat); }
public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight) { if (pointLight.LightType == LightType.OUTDOORS && WallComp != null) { CreateOutsideIfMissing(); LightEffect.Parameters["shadowMap"].SetValue(OutsideShadowTarg); if (OutShadowFloor == pointLight.Level) { return; } OutShadowFloor = pointLight.Level; GD.SetRenderTarget(OutsideShadowTarg); var rect = new Rectangle(DrawRect.X * 2, DrawRect.Y * 2, DrawRect.Width * 2, DrawRect.Height * 2); GD.ScissorRectangle = rect; GD.Clear(Color.Black); var effect = this.GradEffect; effect.Parameters["Projection"].SetValue(Projection); var mat = GetSunlightMat(pointLight); GD.BlendState = MaxBlendRed; WallComp.DrawLMap(GD, pointLight, Projection, mat); Blueprint.Terrain.DrawLMap(GD, pointLight, Projection, mat); Blueprint.RoofComp.DrawLMap(GD, pointLight, Projection, mat); effect.CurrentTechnique = effect.Techniques[0]; EffectPassCollection passes = effect.Techniques[0].Passes; passes[2].Apply(); if (WorldConfig.Current.UltraLighting) { Draw3DObjShadows(pointLight, false); } } else { GD.SetRenderTarget(ShadowTarg); var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight); GD.BlendState = AddBlendRed; DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS) ? 2 : 0, pointLight); } }
public void DrawShadows(Tuple <GradVertex[], int[]> geom, int pass, LightData light) { var pointLight = light.LightPos; var effect = this.GradEffect; effect.Projection = Projection; GD.ScissorRectangle = DrawRect; GD.Clear(Color.Black); effect.CurrentTechnique = effect.Techniques[0]; EffectPassCollection passes = effect.Techniques[0].Passes; passes[pass].Apply(); if (geom.Item1.Length > 0) { GD.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, geom.Item1, 0, geom.Item1.Length, geom.Item2, 0, geom.Item2.Length / 3); } }
public void DrawObjShadows(List <Rectangle> objects, LightData pointLight) { GD.SetRenderTarget(ObjShadowTarg); if (WorldConfig.Current.UltraLighting) { Draw3DObjShadows(pointLight, true); } else { Tuple <GradVertex[], int[]> geom; if (pointLight.LightType == LightType.ROOM) { geom = ShadowGeometry.GenerateObjShadows(objects.Where(x => x.Intersects(pointLight.LightBounds)).ToList(), pointLight); } else { geom = ShadowGeometry.GenerateObjShadows(objects, pointLight); } GD.BlendState = MaxBlendGreen; DrawShadows(geom, 1, pointLight); } }
public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight) { if (pointLight.LightType == LightType.OUTDOORS && WallComp != null) { CreateOutsideIfMissing(); LightEffect.shadowMap = OutsideShadowTarg; if (OutShadowFloor == pointLight.Level) { return; } OutShadowFloor = pointLight.Level; GD.SetRenderTarget(OutsideShadowTarg); var rect = new Rectangle(DrawRect.X * 2, DrawRect.Y * 2, DrawRect.Width * 2, DrawRect.Height * 2); GD.ScissorRectangle = rect; GD.Clear(Color.Black); var effect = this.GradEffect; effect.Projection = Projection; var mat = GetSunlightMat(pointLight); GD.BlendState = MaxBlendRed; WallComp.DrawLMap(GD, pointLight, Projection, mat); GD.BlendState = MaxBlendRed; Blueprint.Terrain.DrawLMap(GD, pointLight, Projection, mat); Blueprint.RoofComp.DrawLMap(GD, pointLight, Projection, mat); effect.CurrentTechnique = effect.Techniques[0]; EffectPassCollection passes = effect.Techniques[0].Passes; passes[2].Apply(); if (WorldConfig.Current.UltraLighting) { Draw3DObjShadows(pointLight, false); } //blit outside shadows onto post target (for blur) if (OutsideShadowTargPost != null) { var blend = GD.BlendState; var rast = GD.RasterizerState; var seffect = WorldContent.SpriteEffect; //seffect.blurAmount = 0.7f / Blueprint.Width); //seffect.blurAmount = 0.4f / Blueprint.Width); //seffect.heightMultiplier = pointLight.FalloffMultiplier); var blur = (0.2f / Blueprint.Width) * (float)Math.Pow(pointLight.FalloffMultiplier, 0.8f); var height = Math.Max(pointLight.FalloffMultiplier / 1.5f, 1); var harden = 0.03f * (float)Math.Sqrt(pointLight.FalloffMultiplier); //lower shadow target quality as blur size increases (to save on memory bandwidth) if (pointLight.FalloffMultiplier > 6) { ShadowTargQualityDivider = 4; } if (pointLight.FalloffMultiplier > 3) { ShadowTargQualityDivider = 2; } else { ShadowTargQualityDivider = 1; } seffect.blurAmount = new Vector2(blur, blur * 2 / 5f); seffect.heightMultiplier = new Vector2(height, height * 5 / 2f); seffect.hardenBias = new Vector2(harden, harden * 0.5f); seffect.noiseTexture = TextureGenerator.GetUniformNoise(GD); for (int i = 0; i < 4; i++) { seffect.SetTechnique((int)SpriteEffectTechniques.ShadowSeparableBlit1 + i); RenderTarget2D tex; if (i % 2 == 0) { GD.SetRenderTarget(OutsideShadowTargPost); tex = OutsideShadowTarg; } else { GD.SetRenderTarget(OutsideShadowTarg); tex = OutsideShadowTargPost; } ShadowTargBlit.Begin(blendState: (i == 1)? OpaqueBA : BlendState.Opaque, effect: seffect, samplerState: SamplerState.PointClamp); ShadowTargBlit.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White); ShadowTargBlit.End(); } /* * ShadowTargBlit.Begin(blendState: BlendState.Opaque, effect: seffect); * seffect.CurrentTechnique = seffect.Techniques["ShadowBlurBlit"]; * seffect.blurAmount = 0.7f / Blueprint.Width); * seffect.heightMultiplier = pointLight.FalloffMultiplier); * seffect.noiseTexture"]?.SetValue(TextureGenerator.GetUniformNoise(GD)); * ShadowTargBlit.Draw(OutsideShadowTarg, new Rectangle(0, 0, OutsideShadowTarg.Width, OutsideShadowTarg.Height), Color.White); * ShadowTargBlit.End(); */ GD.SetRenderTarget(OutsideShadowTarg); GD.RasterizerState = rast; GD.BlendState = blend; } } else { GD.SetRenderTarget(ShadowTarg); var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight); GD.BlendState = AddBlendRed; DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS) ? 2 : 0, pointLight); } }
public LightData BuildOutdoorsLight(double tod) { DayOffset = 0.25f; DayDuration = 0.60f; bool night = false; double modTime; var offStart = 1 - (DayOffset + DayDuration); if (tod < DayOffset) { modTime = (offStart + tod) * 0.5 / (1 - DayDuration); night = true; } else if (tod > DayOffset + DayDuration) { modTime = (tod - (1 - offStart)) * 0.5 / (1 - DayDuration); night = true; } else { modTime = (tod - DayOffset) * 0.5 / DayDuration; } var light = new LightData() { //LightPos = tilePos * 16, LightPos = new Vector2(-1000, -1000), LightType = LightType.OUTDOORS }; Matrix Transform = Matrix.Identity; Transform *= Matrix.CreateRotationY((float)((modTime + 0.5) * Math.PI * 2.0)); //Controls the rotation of the sun/moon around the city. Transform *= Matrix.CreateRotationZ((float)(Math.PI * (45.0 / 180.0))); //Sun is at an angle of 45 degrees to horizon at it's peak. idk why, it's winter maybe? looks nice either way Transform *= Matrix.CreateRotationY((float)(Math.PI * 0.3)); //Offset from front-back a little. This might need some adjusting for the nicest sunset/sunrise locations. var lightPos = new Vector3(0, 0, -3000); lightPos = Vector3.Transform(lightPos, Transform); var z = lightPos.Z; if (lightPos.Y < 0) { lightPos.Y *= -1; } SunVector = lightPos; SunVector.Normalize(); Night = night; light.LightPos = new Vector2(lightPos.Z, -lightPos.X); light.LightDir = -light.LightPos; light.LightDir.Normalize(); lightPos.Normalize(); LightVec = new Vector3(lightPos.Z, 1f, -lightPos.X); Blueprint.Terrain.LightVec = LightVec; light.FalloffMultiplier = (float)Math.Sqrt(lightPos.X * lightPos.X + lightPos.Z * lightPos.Z) / lightPos.Y; if (modTime > 0.25) { modTime = 0.5 - modTime; } if (Math.Abs(modTime) < 0.05) //Near the horizon, shadows should gracefully fade out into the opposite shadows (moonlight/sunlight) { light.ShadowMultiplier = (float)((Math.Abs(modTime) * 20)) * 1f; } else { light.ShadowMultiplier = 1; //Shadow strength. Remember to change the above if you alter this. } if (night) { light.ShadowMultiplier *= 1.33f; } OutdoorsLight = light; Blueprint.OutdoorsLight = light; return(light); }
public RenderTarget2D DebugShadows(List <Rectangle> objects, LightData pointLight) { DrawObjShadows(objects, pointLight); return(ShadowTarg); }
public RenderTarget2D DebugShadows(List <Vector2[]> walls, LightData pointLight) { DrawWallShadows(walls, pointLight); return(ShadowTarg); }
public void Draw3DObjShadows(LightData pointLight, bool clear) { var effect = WorldContent.RCObject; //we doubled the shadow resolution, so this is different. var dr = DrawRect; GD.ScissorRectangle = new Rectangle(dr.X * 2, dr.Y * 2, dr.Width * 2, dr.Height * 2); GD.BlendState = MaxBlendGreen; if (clear) { GD.Clear(Color.Black); } effect.SetTechnique(RCObjectTechniques.LMapDraw); EffectPassCollection passes = effect.Techniques[0].Passes; passes[0].Apply(); var outside = pointLight.LightType == LightType.OUTDOORS; if (outside) { effect.ViewProjection = Matrix.CreateScale(1 / 3f, -1 / 9f, 1 / 3f) * Matrix.CreateRotationX((float)Math.PI / -2) * GetSunlightMat(pointLight) * Projection; } else { effect.ViewProjection = Matrix.CreateScale(1 / 3f, -1 / 3f, 1 / 3f) * Matrix.CreateRotationX((float)Math.PI / -2) * GetLightMat(pointLight); } var lp16 = pointLight.LightPos / 16f; var li16 = pointLight.LightSize / 16f; List <ObjectComponent> objs; if (outside) { objs = new List <ObjectComponent>(); for (int i = 0; i < Blueprint.Rooms.Count; i++) { var room = Blueprint.Rooms[i]; if (room.IsOutside && room.Base == i) { //add components from this room to obj list objs.AddRange(Blueprint.Light[i].Components); } } } else { objs = Blueprint.Light[pointLight.Room].Components; } foreach (var obj in objs) { if ((outside && obj.Level > pointLight.Level) || (Math.Abs(obj.Position.X - lp16.X) + Math.Abs(obj.Position.Y - lp16.Y) < li16)) { obj.DrawLMap(GD, pointLight.Level); } } }
public static Tuple <GradVertex[], int[]> GenerateShadows(IEnumerable <Vector2[]> volumes, LightData light, List <Vector3> ctrWidths, List <Rectangle> rectGeom) { DistanceMult = 5000f; var pointLight = light.LightPos; var mat_cw = Matrix.CreateRotationZ(WallPenumbra); var mat_ccw = Matrix.CreateRotationZ(-WallPenumbra); var vertices = new List <GradVertex>(); var indices = new List <int>(); var j = 0; var basicDesc = new EllipseDesc(); var hc = Color.White * 0.5f; var p = WallPenumbra * 2; foreach (var pts in volumes) { //find sides closest to point float distM; if (light.LightType == LightType.OUTDOORS && ctrWidths == null) { distM = 32f * light.FalloffMultiplier; } else { distM = DistanceMult; } var baseIdx = vertices.Count; //var pts = ClockwiseLine(wall, pointLight); //var pts = ClosestPtsClockwise(wall, pointLight); //through project the points on each side with angle offsets. var mid = (pts[0] + pts[2]) / 2; Vector2 leftNorm, midNorm, rightNorm, leftFac, midFac, rightFac; if (light.LightType == LightType.OUTDOORS) { leftNorm = midNorm = rightNorm = light.LightDir; } else { leftNorm = pts[0] - pointLight; leftNorm.Normalize(); midNorm = mid - pointLight; midNorm.Normalize(); rightNorm = pts[2] - pointLight; rightNorm.Normalize(); } leftFac = leftNorm * distM; rightFac = rightNorm * distM; midFac = midNorm * distM; EllipseDesc ellipse; if (ctrWidths != null) { //distance * obj2height / (lightheight - obj2height) var ctW = ctrWidths[j++]; var mid2 = new Vector2(ctW.X, ctW.Y); float height; if (light.LightType == LightType.OUTDOORS) { height = 16 * light.FalloffMultiplier; } else { height = (mid2 - pointLight).Length() * 16 / ((16 * 3) - 16); } var midNorm2 = mid2 - pointLight; midNorm2.Normalize(); var largeDim = (ctW.Z + height) * midNorm2; var smallDim = new Vector2(largeDim.Y, -largeDim.X); smallDim.Normalize(); smallDim *= ctW.Z; ellipse = new EllipseDesc { pos = mid2, dimensions = new Vector4(smallDim, largeDim.X, largeDim.Y) }; } else if (light.LightType == LightType.OUTDOORS) { //wall linear falloff var perp = (pts[2] - pts[0]); var px = perp.Y; perp.Y = -perp.X; perp.X = px; perp.Normalize(); var midN2 = light.LightDir; var dot = Vector2.Dot(perp, midN2); //if (Math.Abs(dot) < 0.35) continue; var length = distM * (dot); var spos = pts[0];// - ((dot>0)?perp:(-perp))*2; perp *= length; ellipse = new EllipseDesc { pos = spos, dimensions = new Vector4(length * length, 0, perp.X, perp.Y) }; } else { ellipse = basicDesc; } //rotate the left and right norms to make the new penumbras var leftpen1 = pts[0] + Vector2.Transform(leftFac, mat_ccw); var leftpen2 = pts[0] + Vector2.Transform(leftFac, mat_cw); var rightpen1 = pts[2] + Vector2.Transform(rightFac, mat_ccw); var rightpen2 = pts[2] + Vector2.Transform(rightFac, mat_cw); //------ filled points ------ //three cases. left and right penubras intersect at some point, in which case we make 2 triangles. //if they diverge, make 4 triangles. //penumbras contain each other. use one and center at half the target color. //y = mx + c var dist1 = (pts[0] - pointLight).LengthSquared(); var dist2 = (pts[2] - pointLight).LengthSquared(); if (dist1 > dist2) { //is penumbra 1 inside 2? if (Vector2.Dot(Vector2.Normalize(pts[0] - pts[2]), rightNorm) > PenCos) { //yes //continue; var conectr = pts[2] + rightNorm; vertices.Add(GradVertex.ConeVert(pts[2], pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse)); vertices.Add(GradVertex.ConeVert(rightpen1, pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse)); vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse)); for (int i = 0; i < 3; i++) { indices.Add(baseIdx + i); } continue; } } else { //is penumbra 2 inside 1? if (Vector2.Dot(Vector2.Normalize(pts[2] - pts[0]), leftNorm) > PenCos) { //yes //continue; var conectr = pts[0] + leftNorm; vertices.Add(GradVertex.ConeVert(pts[0], pts[0], conectr, Color.TransparentBlack, hc, p, ellipse)); vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], conectr, Color.TransparentBlack, hc, p, ellipse)); vertices.Add(GradVertex.ConeVert(leftpen2, pts[0], conectr, Color.TransparentBlack, hc, p, ellipse)); for (int i = 0; i < 3; i++) { indices.Add(baseIdx + i); } continue; } } var midBack = pts[1] + midFac; //continue; var a = leftpen2 - pts[0]; var b = (rightpen1 - pts[2]); var negX = -b.X; b.X = b.Y; b.Y = negX; var c = pts[2] - pts[0]; var t = Vector2.Dot(c, b) / Vector2.Dot(a, b); if (t < 0) { vertices.Add(GradVertex.SolidVert(pts[0], Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(pts[1], Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(pts[2], Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(leftpen2, Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(midBack, Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(rightpen1, Color.White, ellipse)); indices.Add(baseIdx); indices.Add(baseIdx + 2); indices.Add(baseIdx + 1); //half of rectangle indices.Add(baseIdx); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2); //extension 1 indices.Add(baseIdx + 3); indices.Add(baseIdx + 4); indices.Add(baseIdx + 2); //extension 2 indices.Add(baseIdx + 4); indices.Add(baseIdx + 5); indices.Add(baseIdx + 2); //extension 3 baseIdx += 6; //penumbras vertices.Add(GradVertex.ConeVert(pts[0], pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(leftpen2, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(pts[2], pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(rightpen1, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); for (int i = 0; i < 6; i++) { indices.Add(baseIdx + i); } } else { var inter = pts[0] + a * t; var distant = mid + Vector2.Normalize(inter - pointLight) * distM; vertices.Add(GradVertex.SolidVert(pts[0], Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(pts[0] + a * t, Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(pts[2], Color.White, ellipse)); vertices.Add(GradVertex.SolidVert(pts[1], Color.White, ellipse)); indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2); indices.Add(baseIdx); indices.Add(baseIdx + 2); indices.Add(baseIdx + 3); //half of rectangle baseIdx += 4; //penumbras: each penumbra becomes two tris as they intersect vertices.Add(GradVertex.ConeVert(pts[0], pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(inter, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(distant, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(pts[2], pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(inter, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); vertices.Add(GradVertex.ConeVert(distant, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse)); indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2); indices.Add(baseIdx + 1); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2); baseIdx += 4; indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2); indices.Add(baseIdx + 1); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2); } } return(new Tuple <GradVertex[], int[]>(vertices.ToArray(), indices.ToArray())); }
public static Tuple <GradVertex[], int[]> GenerateWallShadows(List <Vector2[]> walls, LightData pointLight) { var projWalls = walls.Select(x => ClockwiseLine(x, pointLight.LightPos)); return(GenerateShadows(projWalls, pointLight, null, null)); }
public static Tuple <GradVertex[], int[]> GenerateObjShadows(List <Rectangle> walls, LightData pointLight) { List <Rectangle> topDown = new List <Rectangle>(); List <Vector2[]> projWalls = new List <Vector2[]>(); List <Vector3> ctrWidths = new List <Vector3>(); foreach (var i in walls) { if (i.Contains(pointLight.LightPos)) { topDown.Add(i); } else { projWalls.Add(ClosestPtsClockwise(i, pointLight.LightPos)); var ctr = i.Center; ctrWidths.Add(new Vector3(ctr.X, ctr.Y, (float)Math.Sqrt(i.Width * i.Width + i.Height * i.Height) / 2.5f)); } } return(GenerateShadows(projWalls, pointLight, ctrWidths.ToList(), topDown)); }