Example #1
0
        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();
        }
Example #2
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();
        }