Ray tracing with XNA

XNA Lesson 2 -- Difficulty: Easy - Moderate

June 28th, 2007 -- Ray tracing with XNA

Ray tracing is basically using or following a vector to check what it intersects. The benefits to this are numerous. For instance, the view frustum culling from Lesson 1 could be improved to check only things that are actually in view. For instance, if a hill were between the player and another object, that object would still get processed for rendering, which would waste time, which games do not have an abundance of.

Ray tracing could also be used to determine if a bullet fired from a gun hits something, or what is hits. For instance you could try something like this:

// This would be located in the player class
public bool CastBulletRay( Entity targetEntity )
{
    // Using the player's position and the forward vector of the player as
    // the direction of the bullet, create a ray

    Ray bulletRay = new Ray(Player.position, Player.forwardVector);

    // If you do not have a forward vector for the player, or simply want to cast the ray from
    // the player to another object, you can create the ray like this:

    Ray bulletRay = new Ray(Player.position, (targetPosition - Player.position) );

    // Meshes[0] works in the case where a model has only a single mesh. For objects with multiple
    // you must create a bounding sphere that encompasses the entire model.

    if ( bulletRay.Intersects(targetEntity.Model.Meshes[0].BoundingSphere) )
        return true;


    return false;
}

This would suffice to check if a bullet would hit a target entity, however, you must check all the entities in your field of view, and what if there were two entities in the path of this bullet? You need the bullet to recognize which entity is closest and only damage one of them. You could simply keep track of the distance between the target entity and the player, and each time an entity is hit, check that distance against any previous distances. Keeping only the shortest distance as the entity the bullet will ultimately hit.

Ray tracing is especially important for fast moving projectiles. Some bullets in real life can travel up to 1200+ meters per second, or a 1/3rd of a mile in 1 second! If we split that into 1/60th of a second, which is the target frame time for most games, that is 20 meters per frame. Now imagine in a game your enemy is 100 meters away (about the length of a football field). Even for a game this is pretty far away. Now imagine you fire the bullet on frame 1 of a game running 60 frames per second, during the first frame the bullet has just been fired an it's position is in the gun barrel still. Now on frame 2 the bullet is at the 20 yard line, frame 3 - 40 yd line, frame 4 - 60 yd line, frame 5 - 80 yd line, and finally frame 6 it will be on the 100 yd line and hit your enemy. Hmmm, seems ok so far right? Well what if the enemy had been on the 90 yd line? The bullet on frame 5 was at 80 yds, and then the next frame it was at 100 yds. The bullet would not have passed through your enemy, it would have skipped right over him.

In real life there are no "frames", and bullets don't skip about. But games have to simulate life, and so moving a bullet through your game world each frame just doesn't work, unless you got your game up to rediculous framerates like 1000 or higher. That is why ray tracing is essencial, the instant you shoot the bullet, you place a ray in the path the bullet would be headed and ask the computer "What would this bullet be hitting if the game stopped and the bullet continued on?". And in fact, the ray simulates the game stopping, and see what would happen had the bullet traveled its entire path in an instant. This is acceptable in a game because bullets seem to travel instantaneously to the human eye.

Next