在 XNA/WP7 中在精灵前/后绘制 3D?

发布于 2024-10-07 18:02:27 字数 407 浏览 5 评论 0原文

这让我有点沮丧,因为我已经为此烦恼了几个小时。

基本上我是通过 spritebatch 绘制 2D 精灵,并使用 BasicEffect 类绘制 3D 正交投影几何图形。

我的问题是控制在什么之上渲染什么。起初我认为这只是简单地控制渲染顺序,即如果我这样做:

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

这将意味着 2D 内容将在 3D 内容上呈现,但是由于我不控制设备何时开始/结束渲染,这不是结果。 3D 始终在 2D 元素之上渲染,无论投影设置、世界平移、3D 几何顶点定义的 z 分量以及 2D 元素的图层深度如何。

这里有什么我没有调查的吗? 这里处理深度的正确方法是什么?

This is kind of frustrating me as I've been grizzling over it for a couple of hours now.

Basically I'm drawing 2D sprites through spritebatch and 3D orthographically projected geometry using the BasicEffect class.

My problem is controlling what gets rendered on top of what. At first I thought it would be simply controlling the render order, i.e. if I do:

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

It would mean the 2D stuff would render over the 3D stuff, however since I don't control when the device begins/ends renders this isn't the result. The 3D always renders on top of the 2D elements, no matter the projection settings,world translation, the z components of the 3D geometries vertex definitions and the layer depth of the 2D elements.

Is there something I'm not looking into here?
What's the correct way to handle the depth here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江湖彼岸 2024-10-14 18:02:27

好吧,我在发布这个问题后两秒钟就想通了。我不知道这是否是巧合,或者 StackOverflow 是否有一项新功能,可以让我们看到未来的答案。

spritebatch 元素的 Z 位置介于 0 和 1 之间,因此它们不能直接与正在渲染的正交几何体的 z 位置进行比较。

然而,当您创建正交矩阵时,您定义了近剪裁平面和远剪裁平面。您设置的 Z 位置应在此剪辑平面内。我有一种预感,spritebatch 类可以有效地正交绘制四边形,因此通过扩展,0 到 1 意味着 0 代表近剪辑,1 代表远剪辑,并且深度可能被渲染到 3D 几何深度所在的同一位置被渲染到。

Soooo,为了使它工作,我只是想,我为正交渲染定义的近/远剪辑将根据正在渲染的精灵的近/远剪辑进行测量,所以这只是设置正确的 z 值的问题,例如:

如果我有一个 0 的近剪辑和 10000 的远剪辑,并且我想绘制它,以便它对应于 0.5f 图层深度,并在以 0.6 绘制的精灵前面和以 0.6 绘制的精灵后面渲染0.4 我做:

   float zpos = 0.5f;
   float orthoGraphicZPos = LinearInterpolate(0, 10000, zpos);

或者只是 zpos * 10000 :D

我想让你的正交渲染器近/远剪辑为 0 和 1 来直接与精灵层深度进行比较会更有意义。

希望我对这个解决方案的推理是正确的(或多或少)。

OK I figured it out 2 seconds after posting this question. I don't know if it was coincidence or if StackOverflow has a new feature granting the ability to see future answers.

The Z position of spritebatch elements are between 0 and 1 so they're not directly comparable to the z positions of orthographic geometry being rendered.

When you create an orthographic matrix however you define a near and far clip plane. The Z pos you set should be within this clip plane. I had a hunch that the spritebatch class is effectively drawing quads orthographically so by extension that 0 to 1 would mean 0 was representing a near clip and 1 a far clip, and the depth was probably being rendered into the same place the 3D geometry depth is being rendered to.

Soooo, to make it work I just figured that the near/far clips I was defining for the orthographic render will be measured against the near/far clips of the sprites being rendered, so it was simply a matter of setting the right z value, so for example:

If I have a near clip of 0 and a far clip of 10000 and I wanted to draw it so that it would correspond to 0.5f layer depth and render in front of sprites being drawn at 0.6 and behind sprites being drawn at 0.4 I do:

   float zpos = 0.5f;
   float orthoGraphicZPos = LinearInterpolate(0, 10000, zpos);

Or just zpos * 10000 :D

I guess it would make more sense to have your orthographic renderers near/far clip to be 0 and 1 to directly compare with the sprites layer depths.

Hopefully my reasoning for this solution was correct (more or less).

执妄 2024-10-14 18:02:27

顺便说一句,既然您提到您对精灵批次如何绘制四边形有一种预感。如果您好奇,或者需要帮助解决这样的问题,您可以查看所有默认/包含的着色器和 spritebatch 类的源代码:
http://create.msdn.com/en-US/education/catalog /样本/stock_effects

As an aside, since you mentioned you had a hunch on how the sprite batch was drawing quads. You can see the source code for all the default/included shaders and the spritebatch class if you are curious, or need help solving a problem like this:
http://create.msdn.com/en-US/education/catalog/sample/stock_effects

烟若柳尘 2024-10-14 18:02:27

问题在于 spritebatch 会与绘制 3D 对象时使用的一些渲染状态混淆。要解决此问题,您只需在渲染 3D 对象之前重置它们,如下所示。

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; 

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

请注意,这是针对 xna 4.0 的,我很确定您无论如何都在使用它。更多信息可以在 这里是肖恩·哈格里夫斯博客。这将绘制重置渲染状态,绘制 3D 对象,然后在其上绘制 2D 对象。如果不重置渲染状态,您会得到像您所看到的奇怪效果。

The problem is that the spritebatch messes with some of the renderstates that are used when you draw your 3d objects. To fix this you just have to reset them before rendering your 3d objects like so.

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; 

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

Note that this is for xna 4.0 which I am pretty sure your using anyway. More info can be found on shawn hargreaves blog here. This will draw the reset the render states, draw the 3d objects, then the 2d objects over them. Without resetting the render states you get weird effects like your seeing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文