0
\$\begingroup\$

So, we have implemented Krypton shadows into our code for our 2D game, and it's working beautifully. Only issue is that we're running into a bizarre graphical bug when rotating the shadows with the world on the Z axis.

As of right now, the shadows are perfect, until we get to a 45 + 90n degree (45, 135, 225, ... etc, all the "diagonal" angles). At this diagonal angle, the shadow's collapse on the X or Y axis, causing a "blink" effect. We are unsure if this is something inherent with rotating matrices (which Krypton uses) that needs to be worked around, or if this is a bug related to Krypton (and whether or not it can be worked around).

Video Example Of Bug on Youtube

You can find our draw code below. The bool "useFakeFPSPerspective" is used to display this rotating perspective, which has the graphical bug. Our normal perspective does not come across this issue, as it has a fixed angle.

protected override void Draw(GameTime gameTime) {
        //Create a world view projection matrix to use with krypton.
        var world = Matrix.Identity;
        var viewVector = new Vector3(graphics.PreferredBackBufferWidth / 2, -graphics.PreferredBackBufferHeight / 2, 0f) * -1f;
        viewVector.X = -player.LevelPosition.X;
        viewVector.Y = player.LevelPosition.Y;
        var view = Matrix.CreateTranslation(viewVector);

        Matrix? rotateZ = null, shift = null;
        if (useFakeFPSPerspective) {
            var pos = player.Size / 2f;
            viewVector.X -= pos.X;
            viewVector.Y += pos.Y;
            view = Matrix.CreateTranslation(viewVector);

            viewVector.X = pos.X;
            viewVector.Y = -pos.Y;
            shift = Matrix.CreateTranslation(viewVector);

            var mouseState = Mouse.GetState();
            rotateZ = Matrix.CreateRotationZ((float) mouseState.X / -90); //rotates on Z axis (which points "outward", instead of up/down or left/right)
        }

        var projection = Matrix.CreateOrthographic(graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight, 0f, 1f);

        //Assign the matrix and pre-render the lightmap.
        //Make sure not to change the position of any lights or shadow hulls after this call, as it won't take effect till the next frame!

        var shadowMatrix = view;
        if (useFakeFPSPerspective) shadowMatrix *= (Matrix) rotateZ * (Matrix) shift;
        Krypton.Matrix = shadowMatrix * world * projection;
        Krypton.Bluriness = 3;
        Krypton.LightMapPrepare();

        GraphicsDevice.Clear(ClearColor);

        SpriteBatch.Begin();

        level.draw();
\$\endgroup\$
  • \$\begingroup\$ My first idea is that you are doing the matrix multiplication wrong. its not supposed to be. shadowMatrix * world * projection, which seems to be = view * world * projection. but rather = world * shadowMatrix * projection. which relates to = world * view * projection; \$\endgroup\$ – Tordin Feb 11 '14 at 11:41
  • \$\begingroup\$ Thanks for the input! We switched it so that it was: world * view * rotateZ * shift * projection, and that worked! \$\endgroup\$ – MrMusAddict Feb 12 '14 at 0:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.