コード例 #1
0
        /// <summary>
        /// 添加字符图
        /// </summary>
        /// <param name="key">字符</param>
        /// <param name="sprite">精灵</param>
        ///     /// <param name="fontSize">此精灵的参考尺寸</param>
        public void AddCharMap(char key, Sprite sprite, float fontSize)
        {
            var    rect = sprite.rect;
            float  x0   = rect.x / width;
            float  y0   = rect.y / height;
            float  x1   = (rect.x + rect.width) / width;
            float  y1   = (rect.y + rect.height) / height;
            var    t    = sprite.uv;
            UVRect uv   = new UVRect();

            uv.cha     = key;
            uv.uv0.x   = x0;
            uv.uv0.y   = y0;
            uv.uv1.x   = x0;
            uv.uv1.y   = y1;
            uv.uv2.x   = x1;
            uv.uv2.y   = y1;
            uv.uv3.x   = x1;
            uv.uv3.y   = y0;
            uv.Scale.x = rect.width / fontSize;
            uv.Scale.y = rect.height / fontSize;
            uv.Pivot.x = sprite.pivot.x / rect.width;
            uv.Pivot.y = sprite.pivot.y / rect.height;
            cash.Add(uv);
        }
コード例 #2
0
        public void AddCharMap(char key, Sprite sprite)
        {
            var    rect = sprite.rect;
            var    t    = sprite.uv;
            UVRect uv   = new UVRect();

            uv.uv0     = t[3];
            uv.uv1     = t[0];
            uv.uv2     = t[2];
            uv.uv3     = t[1];
            uv.Scale.x = rect.width / NormalSize;
            uv.Scale.y = rect.height / NormalSize;
            buffer.Add(key, uv);
        }
コード例 #3
0
        /// <summary>
        /// 添加字符图
        /// </summary>
        /// <param name="key">字符</param>
        /// <param name="spi">精灵矩形</param>
        /// <param name="fontSize">此精灵的参考尺寸</param>
        public void AddCharMap(char key, ref SpriteInfo spi, float fontSize)
        {
            UVRect uv = new UVRect();

            uv.cha     = key;
            uv.uv0     = spi.uv[0];
            uv.uv1     = spi.uv[1];
            uv.uv2     = spi.uv[2];
            uv.uv3     = spi.uv[3];
            uv.Scale.x = spi.rect.width / fontSize;
            uv.Scale.y = spi.rect.height / fontSize;
            uv.Pivot   = spi.pivot;
            cash.Add(uv);
        }
コード例 #4
0
        public void QuadTree_FindPointsInRectangle()
        {
            var uvs = new List <UV>();

            uvs.Add(UV.ByCoordinates(0.1, 0.1));
            uvs.Add(UV.ByCoordinates(0.3, 0.03));
            uvs.Add(UV.ByCoordinates(0.7, 0.7));
            var qt = Quadtree.ByUVs(uvs);

            UVRect uvRect = new UVRect(UV.ByCoordinates(0, 0), UV.ByCoordinates(0.5, 0.5));
            var    points = qt.FindPointsInRectangle(uvRect);

            Assert.AreEqual(points.Count, 2);
        }
コード例 #5
0
        public void AddCharMap(char key, Rect rect)
        {
            float  x0 = rect.x / width;
            float  y0 = rect.y / height;
            float  x1 = (rect.x + rect.width) / width;
            float  y1 = (rect.y + rect.height) / height;
            UVRect uv = new UVRect();

            uv.uv0.x   = x0;
            uv.uv0.y   = y0;
            uv.uv1.x   = x0;
            uv.uv1.y   = y1;
            uv.uv2.x   = x1;
            uv.uv2.y   = y0;
            uv.uv3.x   = x1;
            uv.uv3.y   = y1;
            uv.Scale.x = rect.width / NormalSize;
            uv.Scale.y = rect.height / NormalSize;
            buffer.Add(key, uv);
        }
コード例 #6
0
        /// <summary>
        /// 添加字符图
        /// </summary>
        /// <param name="key">字符</param>
        /// <param name="rect">精灵矩形</param>
        public void AddCharMap(char key, Rect rect, float fontSize)
        {
            float  x0 = rect.x / width;
            float  y0 = rect.y / height;
            float  x1 = (rect.x + rect.width) / width;
            float  y1 = (rect.y + rect.height) / height;
            UVRect uv = new UVRect();

            uv.cha     = key;
            uv.uv0.x   = x0;
            uv.uv0.y   = y0;
            uv.uv1.x   = x0;
            uv.uv1.y   = y1;
            uv.uv2.x   = x1;
            uv.uv2.y   = y1;
            uv.uv3.x   = x1;
            uv.uv3.y   = y0;
            uv.Scale.x = rect.width / fontSize;
            uv.Scale.y = rect.height / fontSize;
            uv.Pivot.x = 0.5f;
            uv.Pivot.y = 0.5f;
            cash.Add(uv);
        }
コード例 #7
0
        public void Refresh()
        {
            if (FontSize <= 0)
            {
                return;
            }
            if (text == null)
            {
                return;
            }
            float line   = FontSize * 1.25f;
            var   size   = SizeDelta;
            float endx   = size.x * 0.5f;
            float startx = -endx;
            float starty = size.y * 0.5f;
            float endy   = -starty;

            char[] tmp = text.ToArray();
            vert = new List <UIVertex>();
            tri  = new List <int>();
            float dx = GetLineStart(tmp, 0, size.x);
            float dy = starty;

            for (int i = 0; i < tmp.Length; i++)
            {
                var c = tmp[i];
                if (buffer.ContainsKey(c))
                {
                    UVRect uv = buffer[c];
                    float  w  = uv.Scale.x * FontSize;
                    float  h  = uv.Scale.y * FontSize;
                    label :;
                    float x0 = dx;
                    float y0 = dy - h;
                    float x1 = dx + w;
                    float y1 = dy;
                    if (y0 < endy)
                    {
                        break;
                    }
                    if (x1 > endx)
                    {
                        dy -= line;
                        dx  = GetLineStart(tmp, i, size.x);
                        goto label;
                    }
                    int start = vert.Count;
                    var v     = new UIVertex();
                    v.position.x = x0;
                    v.position.y = y0;
                    v.uv0        = uv.uv0;
                    vert.Add(v);
                    v.position.x = x0;
                    v.position.y = y1;
                    v.uv0        = uv.uv1;
                    vert.Add(v);
                    v.position.x = x1;
                    v.position.y = y0;
                    v.uv0        = uv.uv2;
                    vert.Add(v);
                    v.position.x = x1;
                    v.position.y = y1;
                    v.uv0        = uv.uv3;
                    vert.Add(v);
                    tri.Add(start);
                    tri.Add(start + 1);
                    tri.Add(start + 2);
                    tri.Add(start + 2);
                    tri.Add(start + 1);
                    tri.Add(start + 3);
                    dx += w;
                }
            }
        }
コード例 #8
0
        public static void Draw(Light2D light, float z)
        {
            UVRect penumbraRect = ShadowEngine.Penumbra.uvRect;
            UVRect fillRect     = ShadowEngine.FillBlack.uvRect;

            GL.Color(Color.white);

            float size = light.size;

            float squaredSize = Mathf.Sqrt((float)((size * size) + (size * size)));
            float shadowAngle = 360 - light.spotAngle;
            int   step        = 5;

            for (int i = 0; i < shadowAngle; i += step)
            {
                float rotation = i - shadowAngle / 2 - 90;

                if (light.applyRotation)
                {
                    rotation += light.transform2D.rotation;
                }
                float angle1 = Mathf.Deg2Rad * (rotation);
                float angle2 = Mathf.Deg2Rad * (rotation + step);

                Vector2 pos0 = Vector2.zero;
                Vector2 pos1 = new Vector2(Mathf.Cos(angle1) * squaredSize, Mathf.Sin(angle1) * squaredSize);
                Vector2 pos2 = new Vector2(Mathf.Cos(angle2) * squaredSize, Mathf.Sin(angle2) * squaredSize);

                GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                GL.Vertex3(pos0.x, pos0.y, z);

                GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                GL.Vertex3(pos1.x, pos1.y, z);

                GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                GL.Vertex3(pos2.x, pos2.y, z);

                if (i == 0)
                {
                    float penumbra = -light.outerAngle;
                    angle1 = Mathf.Deg2Rad * (rotation);
                    angle2 = Mathf.Deg2Rad * (rotation + penumbra);

                    pos0 = Vector2.zero;
                    pos1 = new Vector2(Mathf.Cos(angle1) * squaredSize, Mathf.Sin(angle1) * squaredSize);
                    pos2 = new Vector2(Mathf.Cos(angle2) * squaredSize, Mathf.Sin(angle2) * squaredSize);

                    GL.TexCoord3(penumbraRect.x0, penumbraRect.y0, 0);
                    GL.Vertex3(pos0.x, pos0.y, z);

                    GL.TexCoord3(penumbraRect.x1, penumbraRect.y0, 0);
                    GL.Vertex3(pos2.x, pos2.y, z);

                    GL.TexCoord3(penumbraRect.x0, penumbraRect.y1, 0);
                    GL.Vertex3(pos1.x, pos1.y, z);
                }
                else if (i + step >= shadowAngle)
                {
                    float penumbra = light.outerAngle;
                    angle1 = Mathf.Deg2Rad * (rotation + 5);
                    angle2 = Mathf.Deg2Rad * (rotation + penumbra + 5);

                    pos0 = Vector2.zero;
                    pos1 = new Vector2(Mathf.Cos(angle1) * squaredSize, Mathf.Sin(angle1) * squaredSize);
                    pos2 = new Vector2(Mathf.Cos(angle2) * squaredSize, Mathf.Sin(angle2) * squaredSize);

                    GL.TexCoord3(penumbraRect.x0, penumbraRect.y0, 0);
                    GL.Vertex3(pos0.x, pos0.y, z);

                    GL.TexCoord3(penumbraRect.x1, penumbraRect.y0, 0);
                    GL.Vertex3(pos2.x, pos2.y, z);

                    GL.TexCoord3(penumbraRect.x0, penumbraRect.y1, 0);
                    GL.Vertex3(pos1.x, pos1.y, z);
                }
            }
        }
コード例 #9
0
ファイル: Legacy.cs プロジェクト: takdw00/Project_Empty
        public static void Draw(List <Polygon2> polygons, float distance, float translucency)
        {
            if (polygons == null)
            {
                return;
            }

            Light2D light    = ShadowEngine.light;
            Vector2 position = ShadowEngine.lightOffset + ShadowEngine.objectOffset;

            float shadowDistance = ShadowEngine.lightSize;

            float outerAngle = light.outerAngle;
            bool  drawInside = (ShadowEngine.lightDrawAbove == false);
            bool  culling    = true;

            UVRect penumbraRect = ShadowEngine.Penumbra.uvRect;
            UVRect fillRect     = ShadowEngine.FillBlack.uvRect;

            float angleA, angleB;
            float rotA, rotB, rotM;

            Vector2 middle = Vector2.zero;

            int PolygonCount = polygons.Count;

            Vector2 draw = ShadowEngine.drawOffset;

            if (translucency > 0)
            {
                GL.Color(new Color(0, 0, 0, 1 - translucency));

                fillRect   = ShadowEngine.FillWhite.uvRect;
                outerAngle = 0;
            }

            if (distance > 0)
            {
                shadowDistance = distance;
                outerAngle     = 0;
                culling        = false;
            }

            for (int i = 0; i < PolygonCount; i++)
            {
                Vector2[] pointsList  = polygons[i].points;
                int       pointsCount = pointsList.Length;

                for (int x = 0; x < pointsCount; x++)
                {
                    int next = (x + 1) % pointsCount;

                    pair.A = pointsList[x];
                    pair.B = pointsList[next];

                    edgeALocal.x = pair.A.x;
                    edgeALocal.y = pair.A.y;

                    edgeBLocal.x = pair.B.x;
                    edgeBLocal.y = pair.B.y;

                    edgeAWorld.x = edgeALocal.x + position.x;
                    edgeAWorld.y = edgeALocal.y + position.y;

                    edgeBWorld.x = edgeBLocal.x + position.x;
                    edgeBWorld.y = edgeBLocal.y + position.y;

                    closestPoint = Math2D.ClosestPointOnLine(middle, edgeAWorld, edgeBWorld);
                    if (Vector2.Distance(middle, closestPoint) > light.size)
                    {
                        continue;
                    }

                    float lightDirection = (float)Math.Atan2((edgeAWorld.y + edgeBWorld.y) / 2, (edgeAWorld.x + edgeBWorld.x) / 2) * Mathf.Rad2Deg;
                    float EdgeDirection  = (float)Math.Atan2(edgeALocal.y - edgeBLocal.y, edgeALocal.x - edgeBLocal.x) * Mathf.Rad2Deg - 180;

                    lightDirection -= EdgeDirection;
                    lightDirection  = (lightDirection + 720) % 360;

                    if (culling && drawInside == false)
                    {
                        if (lightDirection < 180)
                        {
                            continue;
                        }
                    }

                    angleA = (float)System.Math.Atan2(edgeAWorld.y, edgeAWorld.x);
                    angleB = (float)System.Math.Atan2(edgeBWorld.y, edgeBWorld.x);

                    projectedRight.x = edgeAWorld.x + Mathf.Cos(angleA) * shadowDistance;
                    projectedRight.y = edgeAWorld.y + Mathf.Sin(angleA) * shadowDistance;

                    projectedLeft.x = edgeBWorld.x + Mathf.Cos(angleB) * shadowDistance;
                    projectedLeft.y = edgeBWorld.y + Mathf.Sin(angleB) * shadowDistance;

                    if (outerAngle > 0)
                    {
                        rotA = angleA - Mathf.Deg2Rad * light.outerAngle;
                        rotB = angleB + Mathf.Deg2Rad * light.outerAngle;

                        outerRight.x = edgeAWorld.x + Mathf.Cos(rotA) * shadowDistance;
                        outerRight.y = edgeAWorld.y + Mathf.Sin(rotA) * shadowDistance;

                        outerLeft.x = edgeBWorld.x + Mathf.Cos(rotB) * shadowDistance;
                        outerLeft.y = edgeBWorld.y + Mathf.Sin(rotB) * shadowDistance;

                        // Right Penumbra
                        GL.TexCoord3(penumbraRect.x0, penumbraRect.y0, 0);
                        GL.Vertex3(draw.x + edgeAWorld.x, draw.y + edgeAWorld.y, 0);

                        GL.TexCoord3(penumbraRect.x1, penumbraRect.y0, 0);
                        GL.Vertex3(draw.x + outerRight.x, draw.y + outerRight.y, 0);

                        GL.TexCoord3(penumbraRect.x0, penumbraRect.y1, 0);
                        GL.Vertex3(draw.x + projectedRight.x, draw.y + projectedRight.y, 0);

                        // Left Penumbra
                        GL.TexCoord3(penumbraRect.x0, penumbraRect.y0, 0);
                        GL.Vertex3(draw.x + edgeBWorld.x, draw.y + edgeBWorld.y, 0);

                        GL.TexCoord3(penumbraRect.x1, penumbraRect.y0, 0);
                        GL.Vertex3(draw.x + outerLeft.x, draw.y + outerLeft.y, 0);

                        GL.TexCoord3(penumbraRect.x0, penumbraRect.y1, 0);
                        GL.Vertex3(draw.x + projectedLeft.x, draw.y + projectedLeft.y, 0);
                    }

                    // Right Fin
                    GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                    GL.Vertex3(draw.x + projectedLeft.x, draw.y + projectedLeft.y, 0);
                    GL.Vertex3(draw.x + projectedRight.x, draw.y + projectedRight.y, 0);
                    GL.Vertex3(draw.x + edgeAWorld.x, draw.y + edgeAWorld.y, 0);

                    // Left Fin
                    GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                    GL.Vertex3(draw.x + edgeAWorld.x, draw.y + edgeAWorld.y, 0);
                    GL.Vertex3(draw.x + edgeBWorld.x, draw.y + edgeBWorld.y, 0);
                    GL.Vertex3(draw.x + projectedLeft.x, draw.y + projectedLeft.y, 0);

                    closestPoint = Math2D.ClosestPointOnLine(middle, projectedLeft, projectedRight);
                    rotM         = (float)System.Math.Atan2(closestPoint.y, closestPoint.x);

                    // Detailed Shadow
                    projectedMiddle.x = (edgeAWorld.x + edgeBWorld.x) / 2 + Mathf.Cos(rotM) * shadowDistance;
                    projectedMiddle.y = (edgeAWorld.y + edgeBWorld.y) / 2 + Mathf.Sin(rotM) * shadowDistance;

                    // Middle Fin
                    GL.TexCoord3(fillRect.x0, fillRect.y0, 0);
                    GL.Vertex3(draw.x + projectedLeft.x, draw.y + projectedLeft.y, 0);
                    GL.Vertex3(draw.x + projectedRight.x, draw.y + projectedRight.y, 0);
                    GL.Vertex3(draw.x + projectedMiddle.x, draw.y + projectedMiddle.y, 0);
                }
            }

            if (translucency > 0)
            {
                GL.Color(Color.white);
            }
        }
コード例 #10
0
        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();
        }
コード例 #11
0
        public static void Draw(List <Polygon2> polygons, float shadowDistance)
        {
            if (polygons == null)
            {
                return;
            }

            UVRect fill = ShadowEngine.FillBlack.uvRect;

            Light2D light            = ShadowEngine.light;
            Vector2 offset           = ShadowEngine.lightOffset + ShadowEngine.objectOffset;
            float   lightSizeSquared = ShadowEngine.lightSize * 2;
            float   z = ShadowEngine.shadowZ;

            if (shadowDistance == 0)
            {
                shadowDistance = lightSizeSquared;
            }

            float outerAngle = light.outerAngle;
            bool  drawInside = false;
            bool  culling    = true;

            Vector2 vA, pA, vB, pB, vC, vD;
            float   angleA, angleB, rotA, rotB;

            int PolygonCount = polygons.Count;

            Vector2?intersectionLeft;
            Vector2?intersectionRight;

            Vector2 intersectionLeftOffset  = Vector2.zero;
            Vector2 intersectionRightOffset = Vector2.zero;

            GL.Color(Color.white);

            for (int i = 0; i < PolygonCount; i++)
            {
                if (ShadowEngine.lightDrawAbove == false && polygons[i].PointInPoly(-offset))
                {
                    drawInside = true;
                }
                else
                {
                    drawInside = false;
                }

                Vector2[] pointsList  = polygons[i].points;
                int       pointsCount = pointsList.Length;

                for (int x = 0; x < pointsCount; x++)
                {
                    int next = (x + 1) % pointsCount;

                    pair.A = pointsList[x];
                    pair.B = pointsList[next];

                    float edgeALocalX = (float)pair.A.x;
                    float edgeALocalY = (float)pair.A.y;

                    float edgeBLocalX = (float)pair.B.x;
                    float edgeBLocalY = (float)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 (culling)
                    {
                        if (drawInside)
                        {
                            if (lightDirection > 180)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (lightDirection < 180)
                            {
                                continue;
                            }
                        }
                    }

                    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) * lightSizeSquared;
                    vA.y += Mathf.Sin(angleA) * lightSizeSquared;

                    // Left Inner
                    vB.x  = edgeBWorldX;
                    vB.y  = edgeBWorldY;
                    vB.x += Mathf.Cos(angleB) * lightSizeSquared;
                    vB.y += Mathf.Sin(angleB) * lightSizeSquared;

                    // Outer Right
                    pA.x  = edgeAWorldX;
                    pA.y  = edgeAWorldY;
                    pA.x += Mathf.Cos(rotA) * lightSizeSquared;
                    pA.y += Mathf.Sin(rotA) * lightSizeSquared;

                    // Outer Left
                    pB.x  = edgeBWorldX;
                    pB.y  = edgeBWorldY;
                    pB.x += Mathf.Cos(rotB) * lightSizeSquared;
                    pB.y += Mathf.Sin(rotB) * lightSizeSquared;



                    // Right Intersection
                    intersectionRight = LineIntersectPolygons(vC - offset, vA - offset, polygons);

                    if (intersectionRight != null)
                    {
                        if (intersectionRight.Value.y < 0)
                        {
                            intersectionRight = null;
                        }
                        else
                        {
                            intersectionRight = intersectionRight + offset;

                            vA.x = (float)intersectionRight.Value.x;
                            vA.y = (float)intersectionRight.Value.y;

                            intersectionRightOffset    = intersectionRight.Value;
                            intersectionRightOffset.y += shadowDistance;
                        }
                    }

                    // Left Intersection
                    intersectionLeft = LineIntersectPolygons(vD - offset, vB - offset, polygons);

                    if (intersectionLeft != null)
                    {
                        if (intersectionLeft.Value.y < 0)
                        {
                            intersectionLeft = null;
                        }
                        else
                        {
                            intersectionLeft = intersectionLeft + offset;

                            vB.x = (float)intersectionLeft.Value.x;
                            vB.y = (float)intersectionLeft.Value.y;

                            intersectionLeftOffset    = intersectionLeft.Value;
                            intersectionLeftOffset.y += shadowDistance;
                        }
                    }

                    if (intersectionLeft != null && intersectionRight != null)
                    {
                        // Right
                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(vA.x, vA.y, z);

                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(intersectionLeftOffset.x, intersectionLeftOffset.y, z);

                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(intersectionRightOffset.x, intersectionRightOffset.y, z);

                        //Left
                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(vB.x, vB.y, z);

                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(vA.x, vA.y, z);

                        GL.TexCoord3(fill.x0, fill.y0, 0);
                        GL.Vertex3(intersectionLeftOffset.x, intersectionLeftOffset.y, z);
                    }
                    else
                    {
                        if (intersectionRight != null)
                        {
                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(vA.x, vA.y, z);

                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(vB.x, vB.y, z);

                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(intersectionRightOffset.x, intersectionRightOffset.y, z);
                        }

                        if (intersectionLeft != null)
                        {
                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(vB.x, vB.y, z);

                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(vA.x, vA.y, z);

                            GL.TexCoord3(fill.x0, fill.y0, 0);
                            GL.Vertex3(intersectionLeftOffset.x, intersectionLeftOffset.y, z);
                        }
                    }

                    // Right Fin
                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vA.x, vA.y, z);

                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vB.x, vB.y, z);

                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vC.x, vC.y, z);


                    // Left Fin
                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vB.x, vB.y, z);

                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vD.x, vD.y, z);

                    GL.TexCoord3(fill.x0, fill.y0, 0);
                    GL.Vertex3(vC.x, vC.y, z);
                }
            }
        }