1
Vote

lights get cutted while rotated with

description

There is a bug in the KryptonEngine.ScissorRectCreateForLight method.
If you apply a matrix rotation around Z to the light draw matrix, the ScissorRectCreateForLight cuts the light. Thats because it checks only 2 corners.

bug: https://www.dropbox.com/s/xmon0rrh15kc766/krypton_bug.png
fix: https://www.dropbox.com/s/f0rrla2x8f75inz/krypton_fix.png

my fix:
private static Rectangle ScissorRectCreateForLight(ILight2D light, Microsoft.Xna.Framework.Matrix matrix, Vector2 targetSize) {
            // This needs refining, but it works as is (I believe)
            var lightBounds = light.Bounds;

            // top left corner
            var tlc = KryptonEngine.VectorToPixel(lightBounds.Min, matrix, targetSize);
            // bottom right corner
            var brc = KryptonEngine.VectorToPixel(lightBounds.Max, matrix, targetSize);
            // bottom left corner
            var blc = KryptonEngine.VectorToPixel(new Vector2(lightBounds.Min.X, lightBounds.Max.Y), matrix, targetSize);
            // top right corner
            var trc = KryptonEngine.VectorToPixel(new Vector2(lightBounds.Max.X, lightBounds.Min.Y), matrix, targetSize);


            var min1 = Vector2.Min(brc, blc);
            var min2 = Vector2.Min(trc, tlc);

            var max1 = Vector2.Max(brc, blc);
            var max2 = Vector2.Max(trc, tlc);

            var min = Vector2.Min(min1, min2);
            var max = Vector2.Max(max1, max2);


            min = Vector2.Clamp(min, Vector2.Zero, targetSize);
            max = Vector2.Clamp(max, Vector2.Zero, targetSize);


            return new Rectangle((int)(min.X), (int)(min.Y), (int)(max.X - min.X), (int)(max.Y - min.Y));
        }
original code:
        /// <summary>
        /// Gets a pixel-space rectangle which contains the light passed in
        /// </summary>
        /// <param name="light">The light used to create the rectangle</param>
        /// <param name="matrix">the WorldViewProjection matrix being used to render</param>
        /// <param name="targetSize">The rendertarget's size</param>
        /// <returns></returns>
        private static Rectangle ScissorRectCreateForLight(ILight2D light, Microsoft.Xna.Framework.Matrix matrix, Vector2 targetSize)
        {
            // This needs refining, but it works as is (I believe)
            var lightBounds = light.Bounds;

            var min = KryptonEngine.VectorToPixel(lightBounds.Min, matrix, targetSize);
            var max = KryptonEngine.VectorToPixel(lightBounds.Max, matrix, targetSize);

            var min2 = Vector2.Min(min, max);
            var max2 = Vector2.Max(min, max);

            min = Vector2.Clamp(min2, Vector2.Zero, targetSize);
            max = Vector2.Clamp(max2, Vector2.Zero, targetSize);

            return new Rectangle((int)(min.X), (int)(min.Y), (int)(max.X - min.X), (int)(max.Y - min.Y));
        }

comments

Amnesys wrote Jun 12, 2016 at 5:03 AM

This bug was driving me mad. And here it is. A fix. Just sitting there...

Thank you for finding and fixing this you magnificent person!