Saturday, March 17, 2012

Fixing the lighting

While trying to find out what's the problem with ambient lighting on objects, which was making them too dark, I discovered that there's another problem with terrain lighting. Parts of the terrain that are subject to horizontal displacement were having incorrectly computed normals. For some reason the displacement effect was not affecting the terrain normal vector fully, resulting in contrast being lower than appropriate. The reason was probably a forgotten coefficient from an earlier debugging session, because when I derived the Jacobian again, there was this value of 0.5 that didn't belong anywhere.

It wasn't the first time when a surgical tool from a year-old operation was found inside our code. On the other hand, maybe one day we'll discover a hidden sleep() call and get unbelievable speedup by removing it :-)

Here are some comparison screens, old one on the left, fixed on the right side.

Another issue that was solved along the way were the artifacts on ATI cards in the shadowed areas. On ATI cards the floating point values that are output from shader may apparently end up slightly modified when written to a floating point render target, because of the blending unit. It does not matter when these values are supposed to be normal floating point values, but if the exact bit representation is important because these values are actually reinterpreted, a floating point render target cannot be used. Fortunately, the fix was easy once the reason for the artifacts was known.

Here's also the updated ambient lighting:

Adjusted ambient lighting on objects. Previously the downfacing surfaces were almost black.
The ambient lighting isn't finished yet, there will be a better one that will reflect the surrounding environment.

Tuesday, March 6, 2012

Road tool

A short article explaining some of the basic functions of the road editor tool in Anteworld game in sandbox mode. This is the first part that will be extended later as the improvements to the road tool will be made.



Roads in Outerra engine can be created by opening the road tool from sandbox menu. The tool allows you to create new roads or to modify the existing ones. New roads are created by placing way points (ctrl+LMB), both the existing and new roads can be modified by selecting road node and adjusting its attributes or position.

Here are the keys that can be used with the road tool (you can find them in the help tab of the road tool as well):
mmove the way point on the terrain, copying the terrain contours
shift+mmove the way point on the terrain, with the height locked to the original value
vadjust height of the way point
qmove to the next way point
shift+qmove to the previous way point
bappend a new way point

After the nodes are placed or adjusted, you can press the make road button to physically create the road or to rebuild it with adjusted parameters.

You can also select the road type and markings. The selection is limited at the moment; the road system will support much more road types, profiles and markings when it's finished.

Road nodes

Selected node is show with a node selector, drawn as three concentric circles. The circles show the widths of three important road node dimensions: yellow for road width, orange for border extension of the road, and finally the red showing width of transitional area on the road sides.

While the meaning of the first two should be immediately obvious, the transitional width needs some explanation. It specifies the width of the area across which the height of the road surface transitions into the surrounding terrain. If you are creating roads that are roughly at the same level with the terrain, its effect is not that visible. As soon as the road is elevated above or below the terrain, or the terrain is sloped, the effect of the transitional value shows.

The following pictures show the effect of the transitional width value on how the road is blended with the terrain. Just the single selected node has its transitional value changed:
8m transitional width
23m transitional width
1m transitional width


Roads are created from the placed way points using Cubic Hermite splines (for the interested, the algorithm has been briefly described in an earlier blog post). The splines allow for arbitrary selection of tangent (= the direction of the road at given point). Engine supports three ways of computing the tangents:
  • By default it's computed to be parallel with the line between two neighboring way points. This is OK in most cases when you are freely drawing the road.
  • Fit to match the direction of previous segment
  • Fit to match the direction of following segment
Use the latter two if you want to keep the incoming/outgoing road straight up until the turn, so that the nodes behind or before the turn don't affect the tangents:

Tangent computed from two neighbor nodes
Tangent set to match the previous road segment

Connecting roads

Until there's a tool that will snap roads together, you can only try to join them manually. Here are a few tricks how to do it.

Initial state

Move the last node a bit back (using 'm'), and place additional node at the end of the connecting road. Enlarge the road width to get rid of the sharp connection, and move the node so that there's no gap.

The road you are connecting to is usually slightly sloped, and you need to adjust slant of the road node with which you are connecting, together with the height of the node. The height can be changed either using the elevation± slider, or by entering vertical-move mode using key 'v'.

At the moment the width of the road is not yet actually spline-interpolated, but you can select between two modes using the width interpolation flag.
Linear width interpolation