Are SpriteBatch drawcalls culled by XNA?
I have a very subtle problem with XNA, specifically the SpriteBatch. In my game I have a Camera class. It can Translate the view (obviously) and also zoom in and out. I apply the Camera to the scene when I call the "Begin" function of my spritebatch instance (the last parameter).
The Problem: When the cameras Zoomfactor is bigger than 1.0f, the spritebatch stops drawing. I tried to debug my scene but I couldn't find the point where it goes wrong.
I tried to just render with "Matrix.CreateScale(2.0f);" as the last parameter for "Begin". All other parameters were null and the first "SpriteSortMode.Immediate", so no custom shader or something. But SpriteBatch still didn't want to draw.
Then I tried to only call "DrawString" and DrawString worked flawlessly with the provided scale (2.0f).
However, through a lot of trial and error, I found out that also multiplying the ScaleMatrix with "Matr开发者_StackOverflowix.CreateTranslation(0, 0, -1)" somehow changed the "safe" value to 1.1f. So all Scale values up to 1.1f worked. For everything above SpriteBatch does not render a single pixel in normal "Draw" calls. (DrawString still unaffected and working).
Why is this happening? I did not setup any viewport or other matrices. It appears to me that this could be some kind of strange Near/Farclipping. But I usually only know those parameters from 3d stuff.
If anything is unclear please ask!
It is near/far clipping.
Everything you draw is transformed into and then rasterised in projection space. That space runs from (-1,-1) at the bottom left of the screen, to (1,1) at the top right. But that's just the (X,Y) coordinates. In Z coordinates it goes from 0 to 1 (front to back). Anything outside this volume is clipped. (References: 1, 2, 3.)
When you're working in 3D, the projection matrix you use will compress the Z coordinates down so that the near plane lands at 0 in projection space, and the far plane lands at 1.
When working in 2D you'd normally use Matrix.CreateOrthographic
, which has near and far plane parameters that do exactly the same thing. It's just that SpriteBatch
specifies its own matrix and leaves the near and far planes at 0 and 1.
The vertices of sprites in a SpriteBatch
do, in fact, have a Z-coordinate, even though it's not normally used. It is specified by the layerDepth
parameter. So if you set a layer depth greater than 0.5, and then scale up by 2, the Z-coordinate will be outside the valid range of 0 to 1 and won't get rendered.
(The documentation says that 0 to 1 is the valid range, but does not specify what happens when you apply a transformation matrix.)
The solution is pretty simple: Don't scale your Z-coordinate. Use a scaling matrix like:
Matrix.CreateScale(2f, 2f, 1f)
精彩评论