L3DT development blog
Large 3D terrain generator

News for September 2008

September 18

The worst thing about developing L3DT...

…is - without a doubt - tweaking the design/inflate heightfield algorithm. Every time I touch the code for design/inflate, or even think about touching the code, I instantly lose a week of my life.

Here's why:

OK = zCalcHF_InflateMosaic(zHF, SwapMap1, Name1, NULL, TileSize, hFormat, zDM, 2); // to 1/32 res
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ChannelPass(SwapMap1, zDM, 10, 0, 1, 20, 0.005f, 0.2f, true);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ThermalPass(SwapMap1, zDM, 5, 0, 3, 0.05f, ThermalMaxGrad);
zCalcMan_AdvanceCalcStage();
 
OK = zCalcHF_InflateMosaic(SwapMap1, SwapMap2, Name2, NULL, TileSize, hFormat, zDM, 2); // to 1/8 res
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ChannelPass(SwapMap2, zDM, 10, 0, 1, 10, 0.01f, 0.2f, true);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ThermalPass(SwapMap2, zDM, 5, 0, 3, 0.05f, ThermalMaxGrad);
zCalcMan_AdvanceCalcStage();
if(OK) OK = zCalcHF_PeakPass(SwapMap2, zDM);
zCalcMan_AdvanceCalcStage();
 
if(OK) OK = zCalcHF_InflateMosaic(SwapMap2, SwapMap1, Name1, NULL, TileSize, hFormat, zDM, 1); // to 1/4 res
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ChannelPass(SwapMap1, zDM, 5, -1, 1, 10, 0.02f, 0.2f, true);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK)  OK = zCalcHF_ThermalPass(SwapMap1, zDM, 1, -1, 10, 0.05f, ThermalMaxGrad);
zCalcMan_AdvanceCalcStage();
 
if(OK) OK = zCalcHF_InflateMosaic(SwapMap1, SwapMap2, Name2, NULL, TileSize, hFormat, zDM, 1, 0.75); // to 1/2 res
zCalcMan_AdvanceCalcStage();
if(OK) OK = zCalcHF_VolcanoPass(SwapMap2, zDM);
if(OK) OK = zCalcHF_MountainPass(SwapMap2, zDM);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK)  OK = zCalcHF_ChannelPass(SwapMap2, zDM, 5, -1, 1, 10, 0.02f, 0.2f, true);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK)  OK = zCalcHF_ThermalPass(SwapMap2, zDM, 1, -2, 10, 0.02f, ThermalMaxGrad);
zCalcMan_AdvanceCalcStage();
 
if(OK) OK = zCalcHF_InflateMosaic(SwapMap2, zHF, HFname, "HF", TileSize, hFormat, zDM, 1, 0.5); // to final res
zCalcMan_AdvanceCalcStage();
if(OK) OK = zCalcHF_PlateauPass(zHF, zDM); 
zCalcMan_AdvanceCalcStage();
if(OK) OK = zCalcHF_TerracePass(zHF, zDM);
zCalcMan_AdvanceCalcStage();
if(DoErosion && OK) OK = zCalcHF_ChannelPass(zHF, zDM, 1, -2, 1, 10, 0.1f, 0.2f, false);
zCalcMan_AdvanceCalcStage();
if(OK)	OK = zCalcHF_FileOverlayPass(zHF, zDM);
zCalcMan_AdvanceCalcStage();

The above snippet of code is a small segment of the DesignInflate128M algorithm. It shows the chain of alternating calls to fractal inflation, channelling erosion, thermal erosion, peak overlays, mountain overlays, volcano overlays, terrace/cliff overlays, plateau overlays, and file overlays. Each version of the design/inflate algorithm (i.e. 16x, 32x, 64x and 128x) have similar, but slightly different, chains of subroutine calls like this one. For each one, I have to painstakingly tune and test the parameters to the subroutines, particularly those for the channelling and thermal erosion, and fractal inflation function calls. It is a bear of a job, and normally something best avoided.

Last week - against all reason, logic and experience - I decided that design/inflate needed a little update. Specifically, I thought that the fractal inflation was introducing too much noisy randomness in the 128x and 256x algorithms. A small tweak, I thought. A final spit-and-polish of the parameters before releasing L3DT version 2.6, I thought. What could possibly go wrong? I thought.

On closer inspection, I found that the fractal inflation subroutine (represented above by 'zCalcHF_InflateMosaic') had a dubious noise amplitude calculation that resulted in disproportionately large noise levels for long inflation chains (i.e. 128x, 256x.) Conversely, it produced too little noise for short inflation chains (i.e. 8x, 16x). The solution I took was to change the noise amplitude calculation from a crazy bounded inverse exponential function of the horizontal scale to a simple linear function of the horizontal scale. Easy. After a few short days of parameter tuning, I had all of the design/inflate algorithms working nicely - maybe even better than ever. They all looked great.

…and then I changed the horizontal scale. Disaster. Whilst all the design/inflate algorithms now worked perfectly for 10m/vertex, they looked horrible with 1m/vertex, and worse at 100m/vertex. That's not good.

So, I'm back to the drawing board, with little to show for the last four days or so. Perhaps that crazy bounded inverse exponential function wasn't so bad after all…

Cheerio, Aaron.

Bootnotes:

  1. For the final release of L3DT v2.6, I will remove the 8x and 256x design/inflate algorithms. They're not worth the trouble.
  2. If all goes well, we should see L3DT version 2.6 released in late September. If not, then early October.
2011/01/13 07:35
 
l3dt/2008/sept.txt · Last modified: 2017/08/31 05:49 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Share Alike 3.0 Unported
L3DT Development Blog RSS Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki