如何将广告牌精灵转换为 y 轴对齐的广告牌精灵?

问题描述 投票:0回答:1

我正在查看 Shawn Hargreave 的关于广告牌 2D 精灵的旧 xna 教程,在最后一个示例中,他展示了如何使用 spritebatch 在单个 SpriteBatch.Begin 和 End 中绘制所有广告牌精灵。

然而,他提出的方法会导致广告牌精灵面对相机,无论相机在哪里。例如,如果相机位于精灵的正上方,则精灵看起来就像仰卧着一样。这也是角度较小的问题,可能导致精灵夹入 3D 对象。

以下是博客中的相关代码:

`矩阵 invertY = Matrix.CreateScale(1, -1, 1);

basicEffect.World = invertY;
basicEffect.View = Matrix.Identity;
basicEffect.Projection = projection;

spriteBatch.Begin(0, null, null, DepthStencilState.DepthRead, RasterizerState.CullNone, basicEffect);

for each billboard sprite
{
    Vector3 textPosition = new Vector3(0, 45, 0);

    Vector3 viewSpaceTextPosition = Vector3.Transform(textPosition, view * invertY);

    const string message = "hello, world!";
    Vector2 textOrigin = spriteFont.MeasureString(message) / 2;
    const float textSize = 0.25f;

    spriteBatch.DrawString(spriteFont, message, new Vector2(viewSpaceTextPosition.X, viewSpaceTextPosition.Y), Color.White, 0, textOrigin, textSize, 0, viewSpaceTextPosition.Z);
}

spriteBatch.End(); `

它是轻微的伪代码,但我认为这可能只是他的一个拼写错误。请注意,他不需要多次更改基本效果。

我不是矩阵数学方面的专家,我希望有某种简单的解决方案来强制精灵仅绕其 Y(向上)轴旋转(删除间距)。

我可以使用自定义着色器获得所需的效果,但这排除了 spritebatch 及其内置的良好排序系统。

c# opengl xna monogame
1个回答
0
投票

如果您将相机(视图)角度控制为欧拉角(例如围绕 X 轴的 XRot 和围绕 Y 轴的 YRot,例如圆顶式相机),您可以执行类似的操作(假设您的 XRot 和 YRot 角度以度为单位) ):

...
var invertY = Matrix.CreateScale(1, -1, 1);
var invertXAngle = Matrix.CreateFromAxisAngle(new(1, 0, 0), (-XRot + 90) * MathF.PI / 180f);
var world = invertY * invertXAngle;
basicEffect.World = world;
basicEffect.View = Matrix.Identity;
basicEffect.Projection = Projection;
...

这个:

...
Vector3 viewSpaceTextPosition = Vector3.Transform(textPosition, View * invertY)
...

...然后变成:

...
Vector3 viewSpaceTextPosition = Vector3.Transform(textPosition, View * world);
...

这会在精灵局部基础上从相机视图矩阵中“删除”X 旋转。根据您对相机旋转的解释,(-XRot + 90) 也可以是 (-XRot - 90)。

为了提高速度,您还可以缓存“View * world”,因为它不会针对每个精灵而改变。让我知道这是否有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.