示例#1
0
    public override bool CalculateShadow(ref Matrix4x4 matrix, ref float ratio)
    {
        if (base.CalculateShadow(ref matrix, ref ratio) == true)
        {
            if (Texture != null)
            {
                if (SgtHelper.Enabled(RingMesh) == true)
                {
                    RadiusMin = RingMesh.RadiusMin;
                    RadiusMax = RingMesh.RadiusMax;
                }

                var direction = default(Vector3);
                var position  = default(Vector3);
                var color     = default(Color);

                SgtHelper.CalculateLight(Light, transform.position, null, null, ref position, ref direction, ref color);

                var rotation = Quaternion.FromToRotation(direction, Vector3.back);
                var squash   = Vector3.Dot(direction, transform.up);                 // Find how squashed the ellipse is based on light direction
                var width    = transform.lossyScale.x * RadiusMax;
                var length   = transform.lossyScale.z * RadiusMax;
                var axis     = rotation * transform.up;                                                // Find the transformed up axis
                var spin     = Quaternion.LookRotation(Vector3.forward, new Vector2(-axis.x, axis.y)); // Orient the shadow ellipse
                var scale    = SgtHelper.Reciprocal3(new Vector3(width, length * Mathf.Abs(squash), 1.0f));
                var skew     = Mathf.Tan(SgtHelper.Acos(-squash));

                var shadowT = SgtHelper.Translation(-transform.position);
                var shadowR = SgtHelper.Rotation(spin * rotation);          // Spin the shadow so lines up with its tilt
                var shadowS = SgtHelper.Scaling(scale);                     // Scale the ring into an oval
                var shadowK = SgtHelper.ShearingZ(new Vector2(0.0f, skew)); // Skew the shadow so it aligns with the ring plane

                matrix = shadowS * shadowK * shadowR * shadowT;
                ratio  = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin);

                return(true);
            }
        }

        return(false);
    }