Table of Contents
News for September 2008September 18The 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:
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Share Alike 3.0 Unported
|