Camera Matrix Integration Issue

Jan 24, 2011 at 9:55 PM

I'm having trouble getting any Krypton stuff other than a screen full of shadow to appear using my game's camera matrix. I should mention that I made a few alterations to Krypton; I changed Int32 stuff to Int16, and I also made it a Component of my own instead of a DrawableGameComponent, but given the results I'm getting I don't think I broke anything.

If I use this line to define my matrix, disregarding my camera...

krypton.Matrix = Matrix.CreateOrthographic(Video.GraphicsDevice.Viewport.Width / 10, Video.GraphicsDevice.Viewport.Height / 10, 0, 1);

Then I get the following output, just a light over my game with an arbitrary shadow hull. Sorry about the very simple graphics, and also I grabbed the Krypton background just to see exactly what was going on.

Now, if I don't change anything but the matrix line and add the krypton.SpriteBatchCompatablityEnabled = true; line, I just get the following, the same image without any light.

The code I'm using to set up this little test is nearly the same as the testbed stuff:

 

krypton = new KryptonEngine(this, @"Lighting\KryptonEffect");
krypton.AmbientColor = new Color(65, 65, 65);
krypton.Matrix = Camera.CameraMatrix;
krypton.SpriteBatchCompatablityEnabled = true;
//krypton.Matrix = Matrix.CreateOrthographic(Video.GraphicsDevice.Viewport.Width / 10, Video.GraphicsDevice.Viewport.Height / 10, 0, 1);
krypton.Initialize();
krypton.LoadContent();
light.Range = 40;
light.Texture = LightTextureBuilder.CreatePointLight(Video.GraphicsDevice, 512);
light.Position = new Vector2(0, 0);
light.Color = Color.White;
krypton.Lights.Add(light);
shadowHull.Position = new Vector2(10, 10);
krypton.Hulls.Add(shadowHull);

 

And my camera code is located at http://pastebin.com/QkhHwgeS. I ripped out my camera and replaced it with a simpler one in hopes that it was the problem, but that didn't really get me anywhere.

The camera's matrix code looks like this:

public Matrix CameraMatrix
{
    get
    {
        Vector3 matrixRotOrigin = new Vector3(Position + Offset, 0);
        Vector3 matrixScreenPos = new Vector3(ScreenPosition, 0.0f);

        // Translate back to the origin based on the camera's offset position, since we're rotating around the camera
        // Then, we scale and rotate around the origin
        // Finally, we translate to SCREEN coordinates, so translation is based on the ScreenCenter
        return Matrix.CreateTranslation(-matrixRotOrigin) *
            Matrix.CreateScale(Zoom.X, Zoom.Y, 1.0f) *
            Matrix.CreateRotationZ(Rotation) *
            Matrix.CreateTranslation(matrixScreenPos);
    }
}

Here is most of my engine's draw function:

krypton.LightMapPrepare();

Video.GraphicsDevice.Clear(Color.CornflowerBlue);

SpriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null, Camera.CameraMatrix);
SpriteBatch.Draw(background, new Vector2(0, 0), Color.White);
SpriteBatch.End();

foreach (Component c in components)
    c.Draw(gameTime);

krypton.Draw(gameTime);

And I promise that the few calls to SpriteBatch in my components look exactly like the ones above.

I opted to have all the Krypton calls be explicit for the moment, rather than have it be in the collection of components, just to make sure that I understand what order everything should happen in.

I'm just really at a loss. Any help would be absolutely amazing, and I can definitely provide more information if needed.

Coordinator
Jan 25, 2011 at 1:58 AM

Phoenix,

Theres a couple of things I can see here that might be going wrong...

First, I can't tell where your camera is located in world space. It could be that the camera is just not pointing at the area of the world where the light is.

Second, I can't tell what your pixel/unit ratio is, and thus the light's size (radius = 40) could just be too small to show up, or make it much more likely to be off screen.

I would suggest centering both the camera and the light, to make sure that we're drawing anything at all. If we're not, we need to make sure that the CullMode is set appropriately. I don't actually set raster state inside of Krypton, so this can be override just before calling LightmapPrepare.

If none of that seems to help, I'd be happy to take a look at the source and see what I can do. I'd much appreciate getting to take a look at how other's are implementing krypton in their games.

Coordinator
Jan 25, 2011 at 2:57 AM

This is the matrix I'm using:

            matrix =
                Matrix.CreateTranslation(cameraPosition) *
                Matrix.CreateScale(cameraZoom) *
                Matrix.CreateRotationZ(cameraRotation) *
                Matrix.CreateTranslation(halfTargetWidth, halfTargetHeight, 0);

The variables are pretty self explanatory, but here goes:

camera position is the world-coordinates of the camera, in relation to the origin (about which is the center of the screen, as denoted by the halfTargetWidth and halfTargetHeight variables)

camera zoom is the camera's zoom (in my case I use a cubic zoom, as I think it looks smoother. ie: cubicZoom = zoom * zoom * zoom), 

camera rotation is the camera's rotation from the origin. The world appears to be rotated in an opposite angle.

halfTargetWidth and halfTargetHeight are set to be equal to half of the current render targets width and height, respectively. I use GraphicsDevice.ScissorRectangle.Width and GraphicsDevice.ScissorRectangle.Height (respectively)

Coordinator
Jan 25, 2011 at 2:58 AM

for reference, in case anyone else who sees this thread is wondering. I'm using that matrix in association with krypton.SpriteBatchCompatabilityEnabled = true, and using a spritebatch to draw (to which I send the exact same matrix).

Jan 25, 2011 at 10:39 AM

First thing I'd check is that you're re-setting the krypton.matrix every tick, in Update? It'll need constant updating because the camera's moving.

 

This is the bit of my Camera class that handles the View and Transform Matrices. I can then just pull out which bits I need, depending. Hopefully this helps, as I mentioned in the other thread my camera works fine with Krypton...

 

 

private void updateView()
        {
            Projection =
                Matrix.CreateOrthographic(zoom * Viewport.AspectRatio,
                                          zoom,
                              0, 1);
            View =
              Matrix.CreateTranslation(-currentPosition.X, -currentPosition.Y, 0)
              * Matrix.CreateRotationZ(rotation);

            Transform =
                  View
                * Matrix.CreateScale(Viewport.Height / zoom )
                * Matrix.CreateScale(1, -1, 1)
                * Matrix.CreateTranslation(Viewport.Width * 0.5f, Viewport.Height * 0.5f, 0f);

        }

Then with Krypton I'm doing this:

krypton.Matrix = _camera.Transform;
krypton.SpriteBatchCompatablityEnabled = true;

Importantly, that's happening every tick, in Update();

Hopefully that helps, somehow :)

Jan 25, 2011 at 3:15 PM
Edited Jan 25, 2011 at 3:16 PM

I've been taking the things you guys mentioned into account and I'm really not seeing what my issue is. It could be the pixel/unit ratio mentioned, but I've tried a bunch of different values for the light position and range and texture size without any luck. xixonia, if you wouldn't mind taking a look at my project, I think I've got a portable version here: http://dl.dropbox.com/u/4030409/NePlus.zip. There are a lot of dependencies because I'm using a lot of different technologies, so let me know if any present issues. The place in the code with the code I posted is in the Engine class in the root of the project. Controls for the camera are in Config.ini in the root of the content project. I hope that you can find my issue! It must be pretty silly based on the fact that you both have it working with no issues. I do wish I had more of a game to show, but I kind of ripped out the only gameplay logic because it's directly related to the lighting, and I was just using placeholder sprites before this.

Coordinator
Jan 25, 2011 at 9:59 PM

Phoenix,

I'll take a look at the source as soon as I'm available.

Coordinator
Jan 26, 2011 at 5:03 AM

Phoenix,

It was a culling problem -.-

Please add this line of code before preparing the light map:

            Video.GraphicsDevice.RasterizerState = RasterizerState.CullNone;

Jan 26, 2011 at 6:00 AM

xixonia,

I just added the line, and now I can see the beautiful little test light I've been dreaming of! I truly cannot thank you enough! Throw up a donation button or something, because you have truly been an absolute lifesaver. I owe you quite a few pints.

Jan 26, 2011 at 8:18 AM

Thanks xixonia! Hope you like beer, because I also owe you a couple.

Coordinator
Jan 26, 2011 at 7:27 PM

lol... I hope this continues.

Feb 11, 2011 at 12:47 PM

Hi there! I downloaded the latest changeset (2981) and... again my camera matrix is not working with the shadows again :(

Coordinator
Feb 11, 2011 at 4:37 PM

Weird, Sorry.

Is SpriteBatchCompatibilityModeEnabled still set to true?

I think the only logic I changed with that was some matrix multiplication syntax, but I could be dreadfully wrong.

Feb 11, 2011 at 11:45 PM

Using the previous build set, I got everything working with my camera on the first try.

When I overwrote Krypton using the latest build set, I got errors:  PointLight seems to have disappeared, as well as CullMode?!

Coordinator
Feb 11, 2011 at 11:56 PM

I've been adding and removing classes, types, etc until the actual release of v2.0, at which point everything will be stable, and only additions will be made (unless otherwise noted, in very few cases).

PointLight should be Light2D, now, and should function identically (if not very close) to the original point light.

CullMode was basically a duplicate of XNA's Microsoft.Xna.Framework.Graphics.CullMode, so I replaced it with that.

Come monday/tuesday, Krypton v2.0 will be released, and you should no longer need to change how you interact with Krypton. Sorry :/

Coordinator
Feb 11, 2011 at 11:59 PM

In reality, It was probably a bad idea to rename PointLight to Light2D, and I'll probably change it back for the release.

However, I guarantee this kind of thing won't go un-noted in the future. I was very tired at the time of submission, and failed to adequately comment the change set :(

In addition, there will be far less changes to the user-oriented code after the official release of v2.0.

Feb 12, 2011 at 12:03 AM

No worries...  It's perfectly reasonable to expect that new build sets break previous code.  :)

Coordinator
Feb 12, 2011 at 2:43 AM

phoenix, were you able to get this working?

Feb 12, 2011 at 3:09 AM

I will update and get back to you in a few minutes!

Feb 12, 2011 at 3:47 AM
Edited Feb 12, 2011 at 3:48 AM

Okay, so I just updated and I too am now getting the screen of darkness like I was at the beginning of this thread. I only changed the code in my project that was necessary to work with the new Krypton structure.

Coordinator
Feb 12, 2011 at 4:02 AM

booooo.....

looking in to this now.

Coordinator
Feb 12, 2011 at 4:11 AM

question... are you assigning krypton's matrix once and only once, per chance?

Feb 12, 2011 at 4:17 AM

I assign it when I first instantiate, as well as once every time I update.

Coordinator
Feb 12, 2011 at 6:47 AM

Pretty sure this has to do with the new off-screen light culling optimizations. Looks like I forgot to compensate for the sprite batch matrix when doing the view frustum culling. I'm fixing and testing now.

Coordinator
Feb 12, 2011 at 8:15 AM

No, this is weirder... I haven't figure out how to fix it yet, even with looking at older code.

Coordinator
Feb 12, 2011 at 8:29 AM

I have some bad logic for the scissor rectangles. I'll work on fixing this asap.

As a quick fix simply remove the following line (line 283) from KryptonEngine.cs:

this.GraphicsDevice.ScissorRectangle = KryptonEngine.ScissorRectCreateForLight(light, this.mWVP, targetSize);

Feb 12, 2011 at 11:28 AM

If this can help you to know where could be the issue, the latest changeset I was using before was the 2464.

Coordinator
Feb 12, 2011 at 11:22 PM

Figured it out! :)

I've got some other responsibilities to tend to right now, but I'll fix it and upload the changeset tonight. until then, my quick fix ^^above^^ will work :)

Coordinator
Feb 13, 2011 at 2:40 AM

Fixed in changeset 3032. If you experience any more problems with krypton, please open a ticket on the Issues page so I can keep track of them better. :)

Coordinator
Feb 13, 2011 at 8:31 AM

Darn it. I had the scissor rectangle line still commented, which caused a major performance decrease :(. I need to retest the fix and get back with you...

Coordinator
Feb 13, 2011 at 9:00 AM

fixed. uploaded. sorry.

Feb 14, 2011 at 2:17 PM

Hi xixonia, I still have problems with the camera matrix :(

Neither the fix you posted above or the last build works as before. Something I'm missing? Do I need additional transformations?

Coordinator
Feb 14, 2011 at 3:30 PM

You shouldn't need anything additional.

{
    this.krypton.Matrix = final;
    this.krypton.Cullmode = CullMode.None;
    this.krypton.SpriteBatchCompatibilityEnabled = true;

    this.krypton.PrepareLightMap();

    this.spriteBatch.Begin(..., final);
    this.spriteBatch.Draw(...);
    this.spriteBatch.End(...);

    base.Draw(gameTime);
}

The above pseudo should be everything you need to get started. I would make sure you're using the correct cull mode... I think those settings changed for some reason when I switched to using the XNA framework cullmode.

Please let me know if this works., and if not, I'll look into it further.

Feb 14, 2011 at 4:54 PM

Thanks! Works flawlessly :) , I missed the line:

this.krypton.Cullmode = CullMode.None;
Coordinator
Feb 14, 2011 at 8:34 PM

If it makes a difference, you can play around with the cull mode. try not to use None as a general rule. just for testing :)