in

This site is all about the amazingly cool stuff you can do with VB.NET.

The VB.NET XNA Project

December 2007 - Posts

  • Heightmap Collision Sample posted

    This one was a real pain, but it's the second sample I've done with a custom ContentProcessor. Grab the vb.net code here.

    Heightmap Collision

    This sample demonstrates how to move objects along a heightmap. It is based on the Generated Geometry sample, which creates a landscape from a bitmap. We build upon that sample, showing how to quickly calculate the height of any point on that heightmap.

    Sample Overview

    The Generated Geometry sample introduced the concept of a heightmap. In that sample, a content processor reads a bitmap and uses the intensity of its pixels as height values on a terrain. A logical next step to this technique is to place objects on the terrain. This sample demonstrates that technique by placing a ball on the generated terrain.

    Minimum Shader Profile

    Vertex Shader Model 1.1 Pixel Shader Model 1.1

    Sample Controls

    This sample uses the following keyboard and gamepad controls.

    Action Keyboard Control Gamepad Control
    Move the ball.

    UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW

    or W, A, S, and D

    Left thumb stick or D-Pad
    Exit the sample. ESC or ALT+F4 BACK

    How the Sample Works

    This sample is based on the Generated Geometry sample. To support the added functionality, the original sample has been modified in several ways. For clarity, the sky has also been removed.

    Changes to the Terrain Processor

    The TerrainProcessor has been modified slightly for this new sample. First, the algorithm that gives the vertices their XZ position has been modified slightly from the generated geometry sample. In the new version, the positions are calculated so that the heightmap is always centered around the origin. This change simplifies the math at run time.

    In addition, the processor is responsible for creating a class called HeightMapInfoContent, which contains data about the height of the points of the heightmap, as well as the distance between them. This information is attached to the finished terrain model's .Tag property, and will be read when the game loads.

    Finally, the SkyProcessor and SkyContent classes have been removed from the pipeline assembly.

    Rolling Around on the Terrain

    The user is now given direct control over a small sphere, which can roll over the terrain. The camera, which used to move in a fixed circular pattern around the terrain, is now tied to follow the sphere. To make it more obvious which code is new, we removed the Sky class from the sample.

    To keep both the sphere and the camera on top of the terrain, we use the GetHeight function on HeightMapInfo. GetHeight is the most complicated part of this sample. This function accepts a position as an argument and returns the height of the heightmap at that position.

    In this diagram, we are trying to calculate the height of the red circle. The grid represents our heightmap. In this example, our heightmap is 4×4. Note that this means that the heightmap's width and height are only 3 * TerrainScale. We'll call the white space between gridlines "cells."

    To calculate the red circle's height at any point on a cell, we use bilinear interpolation. This is a lot simpler than it sounds. To understand how it works, let's first examine the simpler case, linear interpolation.

    In this diagram, we know the (x,y) coordinates of two points on the red line: (2,1) and (8,4). We want to find out the y-coordinate at x = 4. (The diagram isn't to scale at all, so don't get out your rulers; you'll be disappointed.) To find the missing value, we can use linear interpolation. There are several different ways to do this. We'll use a method that, when ported to C# code, lets us make use of MathHelper.Lerp (linear interpolate) and will be fairly efficient.

    The process is relatively straightforward. We know the x-coordinates of all three points, and we can see that the x-coordinate of the center point, which we are trying to find, is 1/3 of the way between the x-coordinate of the other two points. (In other words, the distance from x = 2 to x = 4 is 1/3 of the distance from x = 2 to x = 8.) Since the points are all on a straight line, the y-coordinate must also be 1/3 of the way.

    The distance between the two y-coordinates, y = 1 and y = 4, is 3. So, if the y-coordinate at (4,?) is 1/3 of that distance away from the point on the left, our missing value is:

    1 + (1/3) × 3 = 2

    Simple enough. Bilinear interpolation will extend that principle further.

    In this diagram, we are again on a heightmap, trying to calculate the height of our red circle. We know all of the heights at the corners of the cell, since we read those in from the bitmap, remember? We also know the x- and z-coordinates of the red circle. What we don't know is the height, y.

    So first, we do a linear interpolation on the top edge of the cell. We go from the (left,top) corner to the (left+1,top) corner, and find the height at point A. Then, we do the same thing on the bottom edge of the cell, calculating the height at point B. Now we know the heights at A and B, both of which are on a straight line with the circle! To find the height of the circle, we do one more linear interpolation between A and B, and we've got our height.

    Note that this technique is not perfect: on steep hills, it is still possible that parts of the sphere may clip through the terrain. To avoid this, we would have to perform a much more expensive collision check. Our technique, although imperfect, is inexpensive, and yields results that will suffice for many games.

    Extending the Sample

    • The camera in this sample is fairly simple. Try taking the camera from the Chase Camera sample, and putting it into this one.
    • When moving objects over a heightmap, you may also want to align them to the slope of the terrain. To do this, you'll need to calculate the heightmap's normal vectors in the TerrainProcessor. A GetNormal function would work similarly to GetHeight, except all three components of the vector would have to be interpolated separately and then renormalized. Using this normal vector, you can calculate an orientation matrix for your object.
  • nothing like vacation time to really get some work done.

    The last few days have been incredibly productive for me, in terms of cranking out conversions.

    Not only did I post several new conversions, but I also managed to wrap up two that had been giving me trouble since day one.  The Bloom PostProcess sample and the Billboard sample have both been a real pain to convert, and I had pretty much given up on both of them until just recently.

    I've learned a lot from converting some of the recent samples (I've learned something from all of them really) and something in my brain clicked just enough to make me want to revisit those two samples mentioned above and wouldn't you know it... I was able to find the problems and get them working.

    I hope to knock out the rest of the samples pretty soon so I can get started on converting the starter kits and the rest of the tutorials.

    Posted Dec 27 2007, 02:57 AM by admin with no comments
    Filed under: ,
  • Billboard Sample posted

    This is the vb.net version of the Billboard sample as seen on Creators.XNA.com.  Grab the source code here. This was another one of the more difficult samples to get working. I spent a few weeks on this one, scratching my head trying to figure out why it didnt work. I was initially worried that custom content processors couldnt be done in vb.net, but this sample proves that theory wrong.

    Billboard Sample

    This sample shows how to efficiently render large numbers of billboard sprites, using a vertex shader to perform the billboard computations entirely on the GPU.

    Sample Overview

    A billboard is a way of faking complex objects without bothering to render a full 3D model. The idea is that where the 3D object would have been, you simply render a 2D sprite with a picture of the object textured onto it. If the player moves around to look at the object from a different direction, you rotate the sprite so that it will always face toward the camera, thus preventing them from ever seeing it "edge on" and being able to tell that it is just a 2D image.

    This technique is obviously not as convincing as rendering a true 3D model would be, but it can be much faster, especially for large numbers of objects such as the field of grass shown in this sample. By moving the camera around, you can get an idea of what situations the billboards look good in, and also where the illusion starts to break down.

    Because this billboard implementation runs entirely in the vertex shader, there is no additional CPU load from rendering billboards compared to normal static geometry. This makes it feasible to render very large numbers of billboards at a good framerate.

    Minimum Shader Profile

    Vertex Shader Model 1.1 Pixel Shader Model 1.1

    Sample Controls

    Keyboard:

    • UP ARROW, DOWN ARROW, LEFT ARROW, and RIGHT ARROW = rotate camera
    • W = forward, S = backward
    • A and D = strafe
    • R = reset
    • ESC or ALT+F4 = exit

    Gamepad:

    • Right thumb stick = rotate camera
    • Left thumb stick = move camera
    • Right thumb stick press = reset camera
    • BACK = exit

    How the Sample Works

    The VegetationProcessor takes in a simple landscape mesh and randomly creates billboard polygons scattered across it. These new polygons are set to render using the Billboard.fx effect, and a number of different billboard textures and sizes are randomly selected.

    In the vertex shader, the billboard effect calculates vertex positions by examining the view matrix to make sure the billboard sprite will always face toward the camera. It also uses a per-billboard random number to make each billboard a slightly different shape, and to randomly mirror the textures on half of the billboards, adding variety to the results. Finally, it uses a sine wave pattern to make the top two vertices of each billboard sway back and forth, simulating the effect of wind on the vegetation. The amount of this swaying is controlled by an effect parameter, so some types of billboard can be set to sway more than others, or to remain entirely still.

    Billboard lighting is calculated using the normal of the underlying landscape geometry. This means that vegetation will be lighter or darker depending on the angle of the hill that it is growing on, and will always be lit consistently with the underlying surface. In a more sophisticated landscape engine, it would be possible to make each billboard sample into the landscape texture to automatically pick up an appropriate color from the ground below it.

    The billboards are rendered in two passes, using different alpha test and depth buffer settings to achieve almost correct depth sorting of alpha blended sprites without requiring them to be depth sorted on the CPU first. The comments at the end of the Billboard.fx file explain this technique in detail.

    Note that although the billboard effect is included as part of the Game Studio project file, its XNA Framework Content property has been set to false. This effect will be built automatically because it is referenced by the VegetationProcessor, so there is no need for it to be duplicated in the project. It was only included here so you can easily locate the file for viewing or editing the effect code.

  • Bloom PostProcess Sample posted

    This one took me a while to convert. There were a few hard to track down issues, but I eventually got it working. Grab the code here.

    BloomPostprocess Sample

    This sample shows how to use bloom post-processing filters to add a glow effect over the top of an existing scene.

    Sample Overview

    Bloom post-processing emulates the visual effect of bright lights and glowing objects. It does this by extracting the brightest parts of an image to a custom render target, blurring these bright areas, and then adding the blurred result back into the original image.

    Because bloom is implemented entirely as a post-process, it can easily be used over the top of any other 2D or 3D rendering techniques. In addition to the more extreme glowing effects, when used subtly it provides a useful softening that can make computer graphics look more organic and help to hide artifacts from elsewhere in your rendering. Particle systems, for example, often look better with a subtle bloom applied over the top.

    Minimum Shader Profile

    Vertex Shader Model 1.1 Pixel Shader Model 2.0

    Sample Controls

    This sample uses the following keyboard and gamepad controls.

    Action Keyboard Control Gamepad Control
    Change the bloom settings. A A
    Toggle bloom on or off. B B
    Show intermediate render target contents. X X
    Exit. ESC or ALT+F4 BACK

    How the Sample Works

    There are three stages to applying a bloom post-process.

    Pass 1 Extract the brightest parts of the scene. This uses the BloomExtract.fx pixel shader, which removes any areas darker than the specified threshold parameter value. Modifying the threshold changes the look of the bloom: higher values produce smaller and better defined glows, while smaller ones produce a softer end result. To see just the result of this first pass, press X until the overlay display shows "PreBloom". Passes 2 and 3 Blur the bright areas. This is done using the GaussianBlur.fx pixel shader—first, to blur the image horizontally, and then again to blur it vertically. The shader does multiple lookups into different parts of the source texture, and then averages the results using a Gaussian curve to weight the importance of each sample. The work is split over two passes because Shader Model 2.0 is not capable of doing enough texture lookups to give a high-quality blur along both the horizontal and vertical axis in a single pass. To see the result of these blur passes, press X until the overlay display shows "BlurredHorizontally" or "BlurredBothWays." Pass 4 Combine the blurred result with the original image. This uses the BloomCombine.fx pixel shader, which has parameters to control how much bloom to include, how much of the original image to retain, and for adjusting the color saturation of both the bloom and original base images. Tweaking these settings can produce a wide range of visual effects.

    Extending the Sample

    Rather than just choosing a fixed set of bloom settings, you could adjust these on the fly depending on what is happening in your game. Perhaps you could make the world go greyer and more blurry when the player has low health, or increase the amount of glow for a second or two when the player gets a power-up.

    You can also adjust bloom settings to mimic how the human eye responds to changing light levels. If the player is in a long tunnel, turn the bloom up very high so any areas of the outside world that are visible past the end of the tunnel will burn-out to white and have a huge glow around them. After they leave the tunnel, gradually fade the bloom down to a level where they will be able to see normally again.

    For a higher-quality bloom, you can render your world using high-dynamic-range (HDR) lighting information, using a floating-point back buffer format to store pixels even brighter than 1.0.

    The Gaussian blur used in this sample could be replaced with any other kind of filter. For example, you could use a blur pass with large sample offsets to create various kinds of lens-flare effects.

    The blur-and-combine pass is a great place to include other kinds of image manipulation. In addition to using the saturation adjustment used in this sample, you could do tone mapping here, or tint the image, or blend in a layer of noise or film grain. This infrastructure is a good starting place for other kinds of post-processing, too, opening up the non-photorealistic world of edge detection, embossing, pencil sketch rendering, and other such techniques.

    Converting to XNA Game Studio 2.0

    The most substantial changes are in the BloomComponent. Here, we must update the sample to use XNA Game Studio 2.0 revised render target APIs. First up, we need to change the type of the field resolveTarget. In version 1.0 when resolving a render target or back buffer, the destination of the resolve had to be a Texture created with the special flag ResourceUsage.ResolveTarget. Many found this pattern confusing, and in XNA Game Studio 2.0 this flag has been removed. Instead, we simply create an instance of the type ResolveTexture2D with no flags at all.

    The next change comes in BloomComponent.Draw. In this function, we used to temporarily disable the depth stencil buffer to avoid writing to it, and then would set it back when finished. This is actually not necessary. The draw function uses SpriteBatch, which draws with the depth buffer disabled. So, we do not need to do anything to "protect" the buffer: it could not have been modified anyway! In the new version of the sample, we avoid changing the depth stencil buffer because doing so leaves the current render target in an undefined state.

    Finally, we must update DrawFullscreenQuad. In the first version of this sample, the function ResolveRenderTarget was used to explicitly resolve the current renderTarget. This method is now considered obsolete and causes a compilation error if used in your code. The actual resolve operation occurs automatically when a new render target is set (for example, a call to SetRenderTarget). So, we replace the call to ResolveRenderTarget(0) with SetRenderTarget(0,nothing). This resolves renderTarget and sets the current render target back to the back buffer.

  • Color Replacement Sample posted

    Grab the vb.net code sample here.

    Color Replacement Sample

    This sample demonstrates how to render parts of an object with a user-defined color.

    Sample Overview

    When it is the Red Team versus the Blue Team or when you want to drive a car painted with your favorite color, you either need to create a texture for each color or perform color replacement programmatically. This sample implements color replacement using an artist-defined alpha map that acts similar to a spray paint stencil. The stencil enables you to have soldiers with any color armor you choose without tinting their faces the same color.

    Minimum Shader Profile

    Vertex Shader Model 1.1 Pixel Shader Model 1.1

    Sample Controls

    This sample uses the following keyboard and gamepad controls.

    Action Keyboard Control Gamepad Control
    Select the red channel (hold). R B
    Select the green channel (hold). G A
    Select the blue channel (hold). B X
    Exit the sample. ESC or Alt+F4 BACK

    How the Sample Works

    The color replacement is performed by the simple high-level shader language (HLSL) effect defined in ReplaceColor.fx. The model's diffuse texture contains the typical red, green, and blue channels for the base color, but also contains an alpha channel. The alpha channel defines which parts of the texture should be color replaced and by how much. The final color before lighting is calculated using a linear interpolation between the base diffuse color and the target color. An alpha value of zero indicates that the base color should be unchanged, while an alpha value of one indicates that the target color should completely replace the base color.

    Posted Dec 24 2007, 07:56 PM by admin with no comments
    Filed under: , , ,
  • 2D Collision Sample #3 (Transformed) posted

    Sample code for part three in the Collision Series (Transformed Collisions) has been posted here. Original tutorial posted at http://creators.xna.com

    Collision Series 3: 2D Collision with Transformed Objects

    This article explains how to perform per-pixel collision detection on sprites by using linear transformations such as rotation or scale.

    Introduction

    In the previous sample, you enhanced your simple obstacle avoidance game by adding per-pixel collisions, which are more accurate than the previously existing bounding rectangle test. The per-pixel technique presented in tutorial 2 accommodates only positioned sprites, without any other transformations. For many games, this is completely sufficient. However, if your game requires objects that are rotated, scaled, or otherwise linearly transformed, you are going to need a more sophisticated per-pixel collision test.

  • 2D Collision Sample #2 (per pixel) posted

    The VB.NET version of the per pixel collision sample. Grab it from the files section here!


    2D Collision Sample 2: Per-Pixel

    This sample demonstrates per-pixel collision detection.

    Introduction

    In the previous example, you created a simple object avoidance game using rectangle collision detection. The rectangles used were only an approximation of the blocks and person drawn into the textures. You may have noticed the exclusive use of rectangles resulted in imprecise behavior for nonrectangular objects.

    In order to achieve the desired behavior, the code must examine every overlapping pixel to determine if there is a collision. This is called per-pixel collision.

  • 2D Collision Sample #1 (Rectangle) posted

    The VB.NET version of the Rectangle Collision Sample.  Grab it from the files section here!


    2D Collision Sample 1: Rectangle

    This sample shows a simple technique for constraining motion and collision detection in 2D.

    Introduction

    Games do not need to be complex to be fun and interesting. Obstacle avoidance games consist of a character and some objects that are on a crash course towards each other. The player must avoid the oncoming objects.

  • Chase and Evade sample posted

    Another VB.NET XNA sample. You can grab it here.  This one is archived in RAR format. See here for explanation.

    Chasing and Evading Sample

    This sample shows how to implement several simple behaviors for AI, including chasing, evading, and wandering.

    Sample Overview

    This sample demonstrates chasing and evading behaviors by using three actors—a cat, a mouse, and a tank. The tank and the mouse are controlled by AI, and the cat is controlled by the player. The tank chases the cat, and the mouse runs from the cat. The tank and the mouse wander around the screen when the cat is not nearby. The "turn toward" functionality from the aiming sample makes it very simple to create these behaviors: chase, evade, and wander.

Copyright 2008 - ILoveVB.NET
Powered by Community Server (Commercial Edition), by Telligent Systems