7

我想渲染一个模型,然后,如果特定的顶点(我将如何标记它们?)是可见的,我想在它们所在的地方渲染一些 2D 的东西。

我该怎么做呢?

4

3 回答 3

7

首先,您需要将顶点位置作为一个Vector4(透视投影需要使用齐次坐标;设置W = 1)。我假设你知道你想要哪个顶点以及如何获得它的位置。它的位置将在模型空间中。

现在只需将该点转换为投影空间。也就是说 - 将它乘以您的 World-View-Projection 矩阵。那是:

Vector4 position = new Vector4(/* your position as a Vector3 */, 1);
IEffectMatrices e = /* a BasicEffect or whatever you are using to render with */
Matrix worldViewProjection = e.World * e.View * e.Projection;
Vector4 result = Vector4.Transform(position, worldViewProjection);
result /= result.W;

现在您的结果将在投影空间中,即屏幕左下角的 (-1,-1) 和右上角的 (1,1)。如果您想在客户空间中获得您的位置(这是SpriteBatch使用的),那么只需使用与SpriteBatch.

Viewport vp = GraphicsDevice.Viewport;
Matrix invClient = Matrix.Invert(Matrix.CreateOrthographicOffCenter(0, vp.Width, vp.Height, 0, -1, 1));
Vector2 clientResult = Vector2.Transform(new Vector2(result.X, result.Y), invClient);

免责声明:我没有测试过任何这段代码。

(显然,要检查特定顶点是否可见,只需检查它是否在投影空间中的 (-1,-1) 到 (1,1) 范围内。)

于 2011-05-26T13:20:09.960 回答
1

可能最好的方法是使用BoundingFrustrum. 它基本上就像一个向某个方向扩展的矩形,类似于玩家相机的工作方式。然后,您可以检查您想要的给定点是否包含在 BoundingFrustrum 中,如果是,则渲染您的对象。

基本上,它的形状如下所示: BoundingFrustrum 的形状

例子:

// A view frustum almost always is initialized with the ViewMatrix * ProjectionMatrix
BoundingFrustum viewFrustum = new BoundingFrustum(ActivePlayer.ViewMatrix * ProjectionMatrix);

// Check every entity in the game to see if it collides with the frustum.
foreach (Entity sourceEntity in entityList)
{
    // Create a collision sphere at the entities location. Collision spheres have a
    // relative location to their entity and this translates them to a world location.
    BoundingSphere sourceSphere = new BoundingSphere(sourceEntity.Position,
                                  sourceEntity.Model.Meshes[0].BoundingSphere.Radius);

    // Checks if entity is in viewing range, if not it is not drawn
    if (viewFrustum.Intersects(sourceSphere))
        sourceEntity.Draw(gameTime);
}

该示例实际上是用于剔除游戏中的所有对象,但可以很容易地对其进行修改以处理您想要做的事情。

示例来源: http: //nfostergames.com/Lessons/SimpleViewCulling.htm

要将您的世界坐标放入屏幕空间,请查看Viewport.Project

于 2011-05-26T13:19:43.653 回答
1

看看你的引擎的遮挡剔除功能。对于 XNA,您可以在此处查阅框架指南(带有示例)。

http://roecode.wordpress.com/2008/02/18/xna-framework-gameengine-development-part-13-occlusion-culling-and-frustum-culling/

于 2011-05-26T13:25:47.940 回答