SpriteBatch 绘制调用是否被 XNA 剔除?
我对 XNA 有一个非常微妙的问题,特别是 SpriteBatch。 在我的游戏中,我有一个相机类。它可以平移视图(显然),也可以放大和缩小。 当我调用 spritebatch 实例的“Begin”函数(最后一个参数)时,我将相机应用于场景。
问题:当相机 Zoomfactor 大于 1.0f 时,spritebatch 停止绘制。 我尝试调试我的场景,但找不到出错的地方。
我尝试使用“Matrix.CreateScale(2.0f);”进行渲染作为“开始”的最后一个参数。 所有其他参数均为 null,第一个参数为“SpriteSortMode.Immediate”,因此没有自定义着色器或其他参数。 但SpriteBatch还是不想画。
然后我尝试只调用“DrawString”,而 DrawString 在提供的比例(2.0f)下完美地工作。
然而,通过大量的试验和错误,我发现将 ScaleMatrix 与“Matrix.CreateTranslation(0, 0, -1)”相乘会以某种方式将“安全”值更改为 1.1f。 因此所有 1.1f 以下的 Scale 值都有效。对于上述所有内容,SpriteBatch 在正常的“Draw”调用中不会渲染单个像素。 (DrawString 仍然不受影响并且工作)。
为什么会发生这种情况? 我没有设置任何视口或其他矩阵。 在我看来,这可能是某种奇怪的近/远剪切。 但我通常只知道 3D 东西中的那些参数。
有什么不清楚的请追问!
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 "Matrix.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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是近/远剪裁。
您绘制的所有内容都会转换为投影空间,然后在投影空间中进行光栅化。该空间从屏幕左下角的 (-1,-1) 到右上角的 (1,1)。但这只是 (X,Y) 坐标。在 Z 坐标中,它从 0 到 1(从前到后)。该体积之外的任何内容都会被剪掉。 (参考文献:1,2,3。)
当您在 3D 中工作时,您使用的投影矩阵将压缩 Z 坐标,以便近平面在投影空间中落在 0 处,而远平面在投影空间中落在 1 处。
在 2D 中工作时,您通常会使用
Matrix.CreateOrthographic
,它具有执行完全相同操作的近平面和远平面参数。只是SpriteBatch
指定了自己的矩阵,并将近平面和远平面保留为 0 和 1。事实上,
SpriteBatch
中精灵的顶点确实有一个 Z-坐标,尽管通常不使用它。它由layerDepth
参数指定。因此,如果您设置的图层深度大于 0.5,然后放大 2,Z 坐标将超出 0 到 1 的有效范围,并且不会被渲染。(文档说 0 到 1 是有效范围,但没有指定应用变换矩阵时会发生什么。)
解决方案非常简单:不要缩放 Z 坐标。使用如下缩放矩阵:
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 thatSpriteBatch
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 thelayerDepth
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: