I'm a professional game developer from Wakefield, England, working as a senior programmer for Rebellion North.
I'm a married father of five and I a also sometimes do Retroburn stuff.
Martin 'Bytrix' Caine
Father. C++ Games Programmer. Cyclist. Guitarist.
2013 3d alphalabs amazon apple archivirtual asynchronous battlefield bad company 2 ben 10 bepu beta blackmagic design blog blue marble bootcamp borderlands bsp calibration charity charvel childsplay comments competition content tracker counter-strike crash csgo css3 cycling dear esther deferred deus ex develop conference direct x discipline documentation doom 3 bfg dpi dr bott eidos elite force email deliverability eurogamer expo facebook focus fresnel game development game horizon game republic gamedev games gaming geoip girls make games global offensive grid guitar half-life 2 hawken hd7 hobbyist htc humble indie bundle imac indie indie trials indietrials intensity pro ip-countryside iron man 3 jamulus rift jquery kids kinect launch conference left 4 dead live lost mac mac osx manchester manhacks mass effect 2 matrox maya minecraft mirrors edge montreal morrowind movies museum of the microstar music mxo2 mini mysql nausea network networking nokia normal mapping obj oculus rift omnitrix ouya pedal for pounds php physics playstation suite port25 portal portal 2 positron posters powermta project aedra project euler promotion properties proton pulse ps vita ps4 psn racer reddit rendering retroburn game studios reviews rift racer riftracer roadkill roller coaster sdl2 shadow racers sharks shoct skyrifters snds space cadet spam trap star trek steam stencyl storage super stock sd1 fr superhot team fortress 2 tesselating tesselation texture editor thunderbird thunderclap ticktock games tiga track builder track bulder trials tv twitter uk ultimatrix usergroup vequencer video vireio visual assist visual studio vorpx voucher vr vr cinema war thunder warren web willow windows 8 windows 8.1 windows phone 7 workbench wp7 wp7dev xbla xblig xblig network xbox xbox live indie games xna xnaukug xperia play zombies on the holodeck
Email Deliverability
Thursday, June 17th 2010 / XNA

Optimizing my BSP loader

I've been thinking for a while that I need to go back to my XNA BSP Processor / Importer to optimize the output a little more and my current focus is optimizing the patch meshes in the BSP. We use NetRadiant to create our game levels in BSP format (and for our track builder I export each piece as an individual BSP then convert it into a mesh since I'm not really a modeller but I'm pretty good with level editing tools).

A wide corner using current settings A wide corner using new tesselation

The first screenshot here shows how the current engine tesselates all patch meshes with a fixed LOD at compile time (with a tesselation factor of 9). This means that every patch mesh in the BSP generates 100 new vertices and takes 162 triangles to render the mesh. Now the problem is that some of these meshes do not need to be tesselated so much and can infact be rendered with many less polygons.

The second screenshot shows the optimal tesselation of the main road patch mesh. You can see that the exact same patch mesh can be rendered using only 18 triangles rather than 162! To do this I either need to try and add some fancy code into the tesselation function that can split the patches depending on the curvature of each side or I can try to supply variables with each patch surface that specify the tesselation to be used.

I've decided that the latter method is the easiest and I can add surfaceflags for each patch surface in the BSP which will specify the tesselation to be used on X and Y edges. For the corner piece in the previous screenshots I would specify an X of 9 and Y of 1 so the patch would not be split vertically and the tesselation would create the 18 triangle version of the patch.

A straight road using current settings A straight road using new tesselation

These screenshots show the most extreme example of the problem. A flat piece of road is made with a single patch mesh which would automatically be tesselated 9x9 times resulting in 100 vertices and 162 triangles again. This could be reduced down to only 2 triangles and 4 vertices if we basically do no tesselation with factors of 1 for both X and Y.

Even the curved pieces along the edge of the road only need to be tesselated once in the X direction for a flat piece of road (but still need to tesselate 9 or so times in the Y since they are curved). For that single section of road (and every other section in our track builder) there are 12 patch meshes. Using the current tesselation function this would result in 100 vertices and 162 triangles per mesh, resulting in 1200 vertices and 1944 triangles. (I hadn't quite realised until now just how high that count was!).

For the straight pieces of road we can reduce the tesselation along the X axis to 1 for all patches. This instantly reduces our polygons per patch to 18 and the section of track would then contain 240 vertices and 216 triangles.

Four of the patches are flat and hence only require tesselation once in both the X and Y directions so that brings our triangle count down even further. Some of the patches are also rather small compared to others and the curves do not need to be as smooth as others. After taking all optimizations into account we end up with the following tesselations:

Road surface: 1 x 1 : 4 vertices, 2 triangles
Road underside: 1 x 1 : 4 vertices, 2 triangles

Road edge (left): 1 x 5 : 12 vertices, 10 triangles
Side Light (left): 1 x 1 : 4 vertices, 2 triangles
Side barrier (left) : 1 x 7 : 16 vertices, 14 triangles
Side barrier top (left) : 1 x 3 : 8 vertices, 6 triangles
Outer edge (left) : 1 x 7 : 16 vertices, 14 triangles

Road edge (right): 1 x 5 : 12 vertices, 10 triangles
Side Light (right): 1 x 1 : 4 vertices, 2 triangles
Side barrier (right) : 1 x 7 : 16 vertices, 14 triangles
Side barrier top (right) : 1 x 3 : 8 vertices, 6 triangles
Outer edge (right) : 1 x 7 : 16 vertices, 14 triangles

Our newly optimized section of road has now been reduced from 1200 vertices and 1944 triangles down to 120 vertices and 96 triangles!

I'm going to be working on making these changes to our BSP loader over the next day or two and hope to see from huge gains in performance terms from this track builder game so that the players are able to build much larger and more complex tracks.

If you found this post helpful please leave a comment below: