public override void CalculateShadow(SgtLight light) { if (Texture != null) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(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 = Matrix4x4.Translate(-transform.position); var shadowR = Matrix4x4.Rotate(spin * rotation); // Spin the shadow so lines up with its tilt var shadowS = Matrix4x4.Scale(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 cachedActive = true; cachedMatrix = shadowS * shadowK * shadowR * shadowT; cachedRatio = SgtHelper.Divide(RadiusMax, RadiusMax - RadiusMin); cachedRadius = SgtHelper.UniformScale(transform.lossyScale) * RadiusMax; cachedTexture = Texture; } else { cachedActive = false; } }
public override bool CalculateShadow(ref Matrix4x4 matrix, ref float ratio) { var light = default(SgtLight); if (Texture != null && SgtLight.Find(ref light) == true) { var direction = default(Vector3); var position = default(Vector3); var color = default(Color); SgtLight.Calculate(light.CachedLight, 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); }