TSE/Atlas/MathOverview

From TDN

This page is a Work In Progress.

Introduction

In order to properly create Atlas terrains, a certain level of math is useful. This guide provides an overview of the issues involved in creating an Atlas terrain using the current tools.

Contents


Heightfields

Until a more intuitive tool comes along, you will work with the generateChunkFileFromRaw16 script function to create chunk files for Atlas. These are the arguments that it uses:

  • srcFile
    Filename of the source raw 16 bit heightfield we wish to generate data for. Example: "demo/data/terrains/test_16_4097.raw".
  • size
    Size of the heightfield, which is assumed to be square. The heightfield will be expected to be ONE MORE THAN THIS. Integer. Size must be a power of 2. Example: 4096.
  • squareSize
    Spacing between sample points, in meters. The default in legacy was 8 meters. This is a floating point number. There are no limitations on this value, although high polygon density may result in reduced frame rates. Example: 2.0. In L3DT terms this is the heightfield resolution.
  • vertScale
    Vertical scale factor. Incoming raw data comes in as a whole number between -32,765 and +32,765, and is scaled by this factor to convert to meters. Factors are commonly of the form 1.0 / 2.0n, n often being between 1 and 8. 1.0 / 256.0 gives you a workable range of about 256 meters in the vertical range. To get an accurate size find the highest point of your terrain and the lowest point. If the lowest is negative add them together. If the lowest is positive then subtract. With your total divide by 65535. Take the first 4 decimal places over and you have your vertical scale. Example: 0.02098
  • destFile
    File to which generated data is written. This file should end in .chu for TGEA's resource manager to properly load it. Example: "demo/data/terrains/large.chu".
  • error
    Floating point number indicating the acceptable amount of error for each LOD to possess compared to the previous. This directly and dramatically impacts the number of polygons that will be rendered. Example: 2.0.
  • treeDepth
    Integer indicating how deep the quadtree of chunks is to be. Example: 6.

Working With Ranges

Now, for an overview of how you get from your heightfield editing program, to a raw 16 bit heightfield, back to the geometry which is chunked for rendering.

Your heightfield editing program may use one of several different internal representations - 8 bit integers, 16 bit integers, 32 bit floating point numbers, or some odd hybrid. Eventually, you get it to export to a raw 16 bit heightfield file. This is done by taking its internal representation and scaling, biasing, or rounding it to be represented by 16 bit integers. These integers range from 0 to 65535, stepping by whole numbers. This has some significant implications in terms of signal processing - for instance, if you take a smooth, curving landscape (say, that undulates between 30 and 60m), and scale it so it's represented by the range 30-60 in the raw file, you'll get bad stairstepping/banding in the final geometry, since smooth parts from the input will have been converted into large gaps in the values.

For instance, say you have some height values in part of that example that go (0.2, 0.6, 1.2, 1.4, 1.45, 1.4, 1.2, 0.6, 0.2) - a nice, smooth bell curve. If you run them through the pipe as described, you'll end up with (0, 0, 1, 1, 1, 1, 0, 0) - a much less appealing piece of terrain, resembling a parking lot more than a gentle hill. But if you had used a broader scale, you'd have had more precision. For instance, say you had taken your curving landscape (with a bandwidth, to abuse a term, of 30 meters, from 30m to 60m) and converted it to a raw file with a range of 30,000 to 60,000 - all of a sudden every meter has one thousand fine differentiations in height available to it. So the height values in our example would pass through just fine; in essence, we have accuracy to the nearest millimeter.

The following diagram gives an overview of the steps in the pipeline, as well as two possible ways the same terrain height range could be encoded. Take a moment to ponder this diagram:

Ok, welcome back.

So, what is going on here?

The diagram is divided into three columns, representing the three steps from editor, to raw file, to chunk file. It branches in the middle, to demonstrate the mutiple ways that a single source heightfield might be encoded in raw integers, and the slightly varied chunked geometry you'll end up with as a result.

Let us consider the first possibilty, A. The editor application simply rounds meters to ints, dropping the fractional portion, and biasing to fit in the unsigned range of the raw file. This has the side effect of probably clobbering a lot of detail in the terrain, as well, as described earlier. To convert back to our original heights, we only have to scale by 1.f. We'll get to error in a moment.

The second possibility, B. The editor application in this case adds 30m to the heights, and scales by a factor of 200 to preserve fractional detail. (In practice, a factor of 256 is more likely.) To scale back, we need only divide the raw integers by 200.

Notice how the two possibilities can result in slightly different height ranges coming out (with the same delta, just a different offset). This is fine - the terrain block can be moved up and down in world space to compensate. Future releases may include a bias parameter to do this programmatically.

Working With Error

Don't set it too low or the creation process will fail. Too high and you'll get too much geometry. The each chunk is twice as big on a side as the previous level, and has error threshold of level * error. So a 6 deep tree with 0.5m error will have 3.0m of error at the highest level.

Eventually this will get replaced with a more flexible and deterministic system.

Working With Trees

treeDepth for dummies.