static private void ShadowForObject(Polygon2 polygon, Vector2 position) { Vector2[] pointsList = polygon.points; int pointsCount = pointsList.Length; Light2D light = ShadowEngine.light; SoftShadowSorter.Set(polygon, light); pair.A.x = SoftShadowSorter.minPoint.x + position.x; pair.A.y = SoftShadowSorter.minPoint.y + position.y; pair.B.x = SoftShadowSorter.maxPoint.x + position.x; pair.B.y = SoftShadowSorter.maxPoint.y + position.y; Pair2D edge_world = pair; Vector2 edgePosition; edgePosition.x = (float)(pair.A.x + pair.B.x) / 2; edgePosition.y = (float)(pair.A.y + pair.B.y) / 2; float edgeRotation = (float)Math.Atan2(pair.B.y - pair.A.y, pair.B.x - pair.A.x); float edgeSize = (float)Vector2D.Distance(pair.A, pair.B) / 2; pass.edgePosition = edgePosition; pass.edgeRotation = edgeRotation; pass.edgeSize = edgeSize; pass.coreSize = light.coreSize; pass.Generate(); pass.SetVars(); pass.Draw(); pass.edgePosition = edgePosition; pass.edgeRotation = edgeRotation + Mathf.PI; pass.edgeSize = edgeSize; pass.coreSize = light.coreSize; pass.Generate(); pass.SetVars(); pass.Draw(); }
public static void Draw(List <Polygon2> polygons, float shadowDistance, float translucency) { if (polygons == null) { return; } Vector2[] uv = new Vector2[4]; Vector2[] vertices = new Vector2[4]; Material mat = Lighting2D.materials.GetSpriteProjectionMaterial(); if (ShadowEngine.spriteProjection == null) { return; } mat.mainTexture = ShadowEngine.spriteProjection.texture; mat.SetPass(0); GL.Begin(GL.QUADS); GL.Color(new Color(translucency, 0, 0, 0)); UVRect fill = ShadowEngine.FillBlack.uvRect; Light2D light = ShadowEngine.light; Vector2 offset = ShadowEngine.lightOffset + ShadowEngine.objectOffset; float lightSize = ShadowEngine.lightSize; float pivotY = (float)ShadowEngine.spriteProjection.pivot.y / ShadowEngine.spriteProjection.texture.height; VirtualSpriteRenderer virtualSpriteRenderer = new VirtualSpriteRenderer(); virtualSpriteRenderer.sprite = ShadowEngine.spriteProjection; // virtualSpriteRenderer.flipX = spriteRenderer.flipX; // virtualSpriteRenderer.flipY = spriteRenderer.flipY; SpriteTransform spriteTransform = new SpriteTransform(virtualSpriteRenderer, Vector2.zero, Vector2.one, 0); Rect uvRect = spriteTransform.uv; pivotY = uvRect.y + pivotY; if (shadowDistance == 0) { shadowDistance = lightSize; } float outerAngle = light.outerAngle; Vector2 vA, vB, vC, vD; float angleA, angleB, rotA, rotB; int PolygonCount = polygons.Count; for (int i = 0; i < PolygonCount; i++) { Vector2[] pointsList = polygons[i].points; int pointsCount = pointsList.Length; SoftShadowSorter.Set(polygons[i], light); pair.A.x = SoftShadowSorter.minPoint.x; pair.A.y = SoftShadowSorter.minPoint.y; pair.B.x = SoftShadowSorter.maxPoint.x; pair.B.y = SoftShadowSorter.maxPoint.y; float edgeALocalX = pair.A.x; float edgeALocalY = pair.A.y; float edgeBLocalX = pair.B.x; float edgeBLocalY = pair.B.y; float edgeAWorldX = edgeALocalX + offset.x; float edgeAWorldY = edgeALocalY + offset.y; float edgeBWorldX = edgeBLocalX + offset.x; float edgeBWorldY = edgeBLocalY + offset.y; float lightDirection = Mathf.Atan2((edgeAWorldY + edgeBWorldY) / 2, (edgeAWorldX + edgeBWorldX) / 2) * Mathf.Rad2Deg; float EdgeDirection = (Mathf.Atan2(edgeALocalY - edgeBLocalY, edgeALocalX - edgeBLocalX) * Mathf.Rad2Deg - 180 + 720) % 360; lightDirection -= EdgeDirection; lightDirection = (lightDirection + 720) % 360; if (lightDirection > 180) { // continue; } for (float s = 0; s <= 1; s += 0.1f) { float step0 = s; float step1 = s + 0.1f; float dir = SoftShadowSorter.minPoint.Atan2(SoftShadowSorter.maxPoint) - Mathf.PI; float distance = Vector2.Distance(SoftShadowSorter.minPoint, SoftShadowSorter.maxPoint); pair.A.x = SoftShadowSorter.minPoint.x + Mathf.Cos(dir) * distance * step0; pair.A.y = SoftShadowSorter.minPoint.y + Mathf.Sin(dir) * distance * step0; pair.B.x = SoftShadowSorter.minPoint.x + Mathf.Cos(dir) * distance * step1; pair.B.y = SoftShadowSorter.minPoint.y + Mathf.Sin(dir) * distance * step1; edgeALocalX = pair.A.x; edgeALocalY = pair.A.y; edgeBLocalX = pair.B.x; edgeBLocalY = pair.B.y; edgeAWorldX = edgeALocalX + offset.x; edgeAWorldY = edgeALocalY + offset.y; edgeBWorldX = edgeBLocalX + offset.x; edgeBWorldY = edgeBLocalY + offset.y; angleA = (float)System.Math.Atan2(edgeAWorldY, edgeAWorldX); angleB = (float)System.Math.Atan2(edgeBWorldY, edgeBWorldX); rotA = angleA - Mathf.Deg2Rad * light.outerAngle; rotB = angleB + Mathf.Deg2Rad * light.outerAngle; // Right Collision vC.x = edgeAWorldX; vC.y = edgeAWorldY; // Left Collision vD.x = edgeBWorldX; vD.y = edgeBWorldY; // Right Inner vA.x = edgeAWorldX; vA.y = edgeAWorldY; vA.x += Mathf.Cos(angleA) * shadowDistance; vA.y += Mathf.Sin(angleA) * shadowDistance; // Left Inner vB.x = edgeBWorldX; vB.y = edgeBWorldY; vB.x += Mathf.Cos(angleB) * shadowDistance; vB.y += Mathf.Sin(angleB) * shadowDistance; vertices[0] = new Vector2(vD.x, vD.y); vertices[1] = new Vector2(vC.x, vC.y); vertices[2] = new Vector2(vA.x, vA.y); vertices[3] = new Vector2(vB.x, vB.y); float x0; float x1; if (edgeAWorldY < 0) { x0 = Mathf.Lerp(uvRect.width, uvRect.x, step0); x1 = Mathf.Lerp(uvRect.width, uvRect.x, step1); } else { x0 = Mathf.Lerp(uvRect.x, uvRect.width, step0); x1 = Mathf.Lerp(uvRect.x, uvRect.width, step1); } float y0 = Mathf.Lerp(uvRect.y, uvRect.height, pivotY); float y1 = Mathf.Lerp(uvRect.y, uvRect.height, 1); uv[0] = new Vector2(x1, y0); uv[1] = new Vector2(x0, y0); uv[2] = new Vector2(x0, y1); uv[3] = new Vector2(x1, y1); // Right Fin GL.MultiTexCoord3(0, uv[2].x, uv[2].y, 0); GL.Vertex3(vertices[2].x, vertices[2].y, 0); GL.MultiTexCoord3(0, uv[3].x, uv[3].y, 0); GL.Vertex3(vertices[3].x, vertices[3].y, 0); GL.MultiTexCoord3(0, uv[0].x, uv[0].y, 0); GL.Vertex3(vertices[0].x, vertices[0].y, 0); GL.MultiTexCoord3(0, uv[1].x, uv[1].y, 0); GL.Vertex3(vertices[1].x, vertices[1].y, 0); } } GL.End(); }