BF2 Cull and LOD explained

By Rhino

Here is a basic tutorial on Cull Distances and LOD Switching Distances coding which is something that is often missed in the export/coding process.

LOD Switching and Cull Distances are both very important elements to ensure that graphics cards are working only as hard as they need to be and also to ensure that gameplay isn't negativity affected.

If these settings are set incorrectly, it can affect performance negatively by having the client's graphics card rendering objects in much higher detail than it needs to be, or by rendering an object that is so far away and as a result, so small, the client can't even see it any more as its only one pixel on there screen. It can also affect gameplay negatively if by a key element of an object, or even the entire object itself stops drawing when you still should be able to clearly see it as if a player is taking cover behind part of an object, or even the entire object you can no longer see from a distance, then for starters you will be able to see players you shouldn't be able to, but it will also look like you will be able to shoot them when you can't. This is also not to mention that having objects obviously appearing/disappearing looks really, really bad and brakes the players immersion.

For this tutorial I'm going to be using the Canadian LAV III as my example.

 **Cull Distances**

The first thing we need to do is define our objects Cull Distance. The Cull distance is basically the max distance an object draws to and past that distance, it stops drawing even if the object is still in the players view distance. This is quite important since you don't want to be drawing something that is so far away and as such, so small, you can't even see it, but then on the other hand you don't want to get its cull distance too low and having the model vanishing when the player still should be able to see it quite clearly. This will not only look like sh\*t, but will also have a huge impact on game play, where for a building, a player may think he has a clear shot of another player, but in fact that other player is sitting behind an object that is between you and him but its not drawing because its been culled due to its too low cull distance. For vehicles, you dont want a vehicle to stop drawing too soon as you will basically have invisible vehicles shooting at you from a distance. In terms of handheld weapons, its important gameplay wise for you to be able to see the other players weapon at a distance as not only will it look crap if the guy is holding nothing in his hands, but from a gameplay point of view, you want to know what weapon he has in his hands so you know what action you need to take to counter it.

As such, its very important we get this value just right, so it doesn't have an impact on gameplay but at the same time you don't want your gfx card working on overdrive, drawing objects that are so small in your view since they are so far away, you can't even see them.

The size of the object is the thing that mostly determines how far your object needs to draw for, before being culled, so for a big apartment building, you will want that object drawing for a huge distance, something like 2kms but for a small sack of rice or something you would only want drawing for a few hindered meters or something. For a handheld weapon, you will probably want it only drawing for something around 100m but big handheld weapons like AT, AA, MGs etc will probably need to be drawn for longer ranges, and smaller handheld weapons like pistols, hand grenades etc for much smaller distances. For vehicles, depending on the vehicle size you will most likely want it drawing for around 1km or more. Big tanks and jets you will want drawing for at least 1km, if not more where a dirt bike you probably only want drawing for 500m, possibly less.

First thing we need to do is turn off the Fog so it doesn't obstruct our view, so go to "Render > Toggle Draw Fog" and make sure it hasn't got a tick by it, if it dose, click it and it should take the tick off (turning the fog off).

Next we need to turn off the "Draw Marker" and "Draw Grid" buttons, which are located in the Editor tab to the right and make sure the buttons are not pressed in, if they are, press them to turn them off.

Next thing we need to do is to bring up the "Object Info" Tool Window, by clicking the "[Object Info]" button at the bottom, middle of the screen and the toll window will pop up, giving you lots of very useful information like the current active LOD, The distance you are away from the very centre of the object (in meters), its Triangle Count (Says poly count but it is tri count), its Vertex count etc. This information in here is critical for us to get the cull and lod distances right

One more thing we need to do is select our final lod of our 3rd person meshes (not the wreck model thou if your model has one). This is explained more in the second part of this tutorial on LOD distances but quickly on how to do this, but for a quick crash course scroll down the very bottom of the Recourse window with your object loaded, expand the "Geometry" tab, then expand the sub "geom" tab, in there should be one or more sub objects called "geom\_\*" where the \* is a number, ranging from 0 to 2. Depending on your object type and its coding each geom can mean different things but generally if you have all 3 geoms then "geom\_0" is your 1st person geometries, "geom\_1" is your 3rd person geometries, "geom\_2" is your wreck model geometries. The simplest way to tell which geom is which is just by selecting each one and watching your model in the view port, if it suddenly becomes more detailed with some faces removed then its most likely the 1st person geom, if it stays the same as when you where first viewing it its the 3rd person geom and if your model looks like its been hit by a tank shell then its the wreck model. Expand the geom which is your 3rd person one, most likely "geom\_1" and you should see a bunch of sub objects called "lod\_\*" where \* is a number ranging from 0 and up, and select the very last "lod\_\*" in the list, in my case "lod\_3". You should see your model loosing a lot of detail but still look roughly the same as before, like so:

With all thous settings off, you object info being displayed and your final lod of your 3rd person meshes selected your model should now look something like this:

Now fly back away from your object while still looking at it until it disappears from view. With the default cull radius scale (1), the LAV-III disappears at ~105m away, first pic is 104m away and the 2nd is 108m away.

Now having our APC disappear at 105m away is seriously bad as you can see from the screenshots above so we need to drastically increase our cull distance value. To do this, scroll up a bit in your resources tab and select your parent object then in the tweaker bar expand your default tab and you will see at the very top a setting called "CullRadiusScale" with its default setting of "1" next to it, or if its already been defined before another value but this value will most likely need changing if it was set before so make sure you test the current cull distance fully before moving on!

What we need to do is increase/decrease the value to the point where it draws the object to the distance we want it. Now for a large object like APC we need to increase the cull distance by quite a lot in order for it to have any affect so if we increase the cullradiusscale value up to 5, the APC now draws to 534meters which still isn't quite far enough, so we need to keep on turning it up to a point where its drawing far enough where we can still see it, but culling it when its no longer relevant, so its all about trial and error until we get it right

Next I tried a cull distance of 10 but this drew the object to 1,070m which still isn't quite far enough as its still a few pixels big, and keep in mind on high rez screens it will be even bigger than the small rez we get in the editor.

For this weapon, I found a CullRadiusScale of 12 seems about right, where it then draws for 1,288 meters before it gets culled and at that point, all it is is a little pixel on the screen

Of course your probably thinking that having the object draw over 1km is pointless because we dont have any maps with a view distance over 1km, but its still a good idea to future proof everything just encase we do at some point get a map with a view distance of 2km or something

Now we know our cull distance we need to manually put it into our .tweak file.

Open up your weapon's .tweak file with a text editor again and look for the line: ==

```
ObjectTemplate.cullRadiusScale

```

It should be somewhere near the top of the file, should be under "ObjectTemplate.castsDynamicShadow 1". If you can't find it, insert it into the file in the same place I have my one:

Once you have found that line, insert the value we worked out we needed in the BF2 editor for our cull distance. Since I found my cull distance needed to be "12", I will now put that in its place like so:

Save that up and move onto the section on LOD Switching Distances

## **LOD Switching Distance**

LODs, aka Levels Of Detail are basically clones of them main model, with decreased complexity of a 3D object which are seen as the object moves further away from the viewer. Level of detail techniques increases the efficiency of rendering by decreasing the workload on graphics pipeline stages, usually vertex transformations. The reduced visual quality of the model is often unnoticed because of the small effect on object appearance when viewed at a distant or when moving fast.

Now hopefully you understand the basics about LODs. The first thing is to check out all your LODs of your model and make sure there is no issue with any of them.
First of all in your recourse bar, scroll all the way down and you should see a "Geometry" tab, expand it and you will find a "geom" tab that you need to expand, followed by a series of sub "geom\_\*" tabs where the \* is a number ranging from 0 to 2. Each geom type has its own purpose, where for a vehicle commonly gemo\_0 is the 1st person meshes, geom\_1 is the 3rd person meshes and geom\_2 is the wreck model meshes but depending on the object type, which geom dose what may change but most of the time, it will be in that set up. Your model also may not have a gemo\_1 or gemo\_2 and if it only has a gemo\_0, its most likely a simple mesh like a staticobject.
Now if we expand each of these "geom\_\*" bits you should see a series of sub objects in them, each one being one of the LODs for each type of geom, named from "lod\_0" and up.

As you select each one, you should notice the mesh in your viewport change and it show the LOD you have selected, as well as in your Object Info tool window (which you can bring up at the bottom of your screen by pressing on the "Object Info" tab where it pops up from) it change its active lod to the one you have selected and its tri count goes down to the tris of your lod:

Checking the lav3 lods now and here is how they look:

* gemo\_0 (First Person LODs)
	+ lod\_0 = 4642
	+ lod\_1 = 4260
* gemo\_1 (Third Person LODs)
	+ lod\_0 = 7191
	+ lod\_1 = 3465
	+ lod\_2 = 1815
	+ lod\_3 = 453
* gemo\_2 (Wreck Model LODs)
	+ lod\_0 = 2032
	+ lod\_1 = 1056
	+ lod\_2 = 116

**gemo\_0**

**gemo\_1**

**gemo\_2**

I would also like to note I did check the rest of my lods from all angle to make sure everything was ok and you should too with your model.

Another thing I would also like to explain quickly is that "LODs" for 1st person meshes (gemo\_0 in most cases) are not used as proper LODs that are viewed at different distances like a normal 3rd person lod since players inside the vehicle, seeing the 1st person model are not going to be getting any further away from the vehicle unless they get out of it which would mean they would then see the 3rd person model. As such, the 1st person mesh lods are just used for separating different parts of the 1st person model for different functions, like in the case of the LAV3, lod0 is used for the 1st person mesh for the driver and gunner, while lod1 is the interior mesh the passengers sit in and view. This is done because the driver and gunner are not going to see the interior mesh while driving/shooting and as such, if it was there it would just be wasted polys they would need to render, and the same story for the passengers sitting in the back, they dont need to render the outside polys of the vehicle since they can't see them from the inside of the vehicle.

1st person mesh lods can also be used for other functions, like on a handheld weapon, lod0 will be the normal 1st person view you see of the weapon, while lod1 will be the 3D scope you "zoom into" when you right click.

Anyways back to checking our lods, the main reason for checking all the LODs is to make sure there are no issues with them and to really see what they all look like and what is taken off what LOD which will help you work out at what distance they need to switch at once you get a hang of this. But the most important thing is making sure there are no issues with any of the LODs. If you find any issues, epically major issues, they need to be fixed and if your not in a position to fix them, you need to report them so the exporter knows they need to be fixed and can do something about it.

The main types of issue you should keep your eye out for are:

* Bad/buggy geometry
* obvious difference in the textures between the LODs
* Any large missing parts that are very obvious to see missing in the lod switch, even at a large distance and also might have a negative impact on gameplay
* A final LOD (both for 3p and wreck geoms) that isn't under or close 300 tris, really the final LOD should be under 100 tris.

For the LAV3, I could only find one any real issue on it, which is a rather small issue but there is a tiny bit of floating geometry above the turret, which has no purpose. Although this is a very small issue and hardly worth fixing its still worth reporting.

After you have checked each lod to make sure they all ok and fixed any issues you can, select the "geom\_1" tab in the Resources window (or "geom\_0" if your model has no first person meshes) and if your right up close to your object it should now be showing you LOD0 again. If you also look down to your tweaker bar you will notice that near the bottom you have a bunch of settings called "LodDistance\*" where the \* is the LOD number, ie, if its 1 its lod1. To the right of these bits you will notice a value, these values are in meters and they basically define at what distance the engine switch the model to what lod. So right now with its default values, it switches to LOD1 at 50m, LOD2 at 100m and LOD3 at 150m. These values need to be changed with ones that fit these lods better.

With LODs you want them changing as soon as possible to the next LOD up, but visually you don't want the player to be able to notice the change and you also don't want the LOD change to happen to soon as it could inflict on gameplay negatively. You also don't want the LODs to be changing too late as doing that will put unnecessary strain on the clients GFX card trying to render the object so you want it just at the right distance where your changing the lod as soon as you can, without being able to notice the change nor the change having an impact on gameplay (although if you can't notice the change, its very unlikely there will be any impact on gameplay).
Also one thing to note is these LOD distances don't include when your looking at a object though any optics like binoculars etc. When looking though Optics it will change to the best LOD suited for them based on the distances you define here so lets say if we set the LOD5 to 500m or something and the player was 600m away, if he looked at the apc though optics from 600m away, he would no longer be seeing lod5 but something like lod4 or even lod3 if the optics where very powerful. These distances are only for when the player is looking at a object with no zoom, the engine will do all the work to compensate for optic zoom itself
Like with the Cull distance setting, its all trial and error to get this just right. Basically the way to do it is with one LOD at a time, starting with LOD1 and working your way up to the top until they are all good.
The way to do this is kinda like what we did with the cull distances with flying back and fort to see where it stopped drawing, except here, we are flying back and forth and seeing if we can see any noticeable change between the lods and pushing the distance down as far as we can on each lod.

So make sure your "geom\_1" tab is selected in your resources window (or gemo\_0 if your model doesn't have any 1st person meshes) so your not forcing any LOD to draw and the LODs are only going to draw at there set distances, and then fly back to just before your lod1 change so at the moment for me, lod1 changes at 50m so I'm going to fly back to 49m. Then I'm going to fly back past 50m and see if I can see any change. Also make sure that in your Object Info tool window that it says lod1 is drawing after you fly back past the distance, if it aint then you probably don't have the "geom\_\*" tab selected in your resources window.

As we can see you can't see any change there which signifies the distance is either just right, or more likely that the distance could be lowered some what still so lets change the lod1 switch distance in the tweaker tab to 20m and see if we can see it then. Also when watching for changes, try and watch for bits you know are less detailed in the next lod from the last, like from lod0 to lod1, I know lod1's inner wheel bits are much more 2D than lod0 so I'm going to be keeping my eye on them, as well as other key bits.

With the lod1 switch distance at 20m I can just see quite clearly the change in details on the wheels, as well as a few other bits so I'm going to up the amount to 30m to see how that works.

With the lod1 switch distance at 30m I can just see quite clearly the change in details on the wheels, as well as a few other bits so I'm going to up the amount to 40m to see how that works.

At 40m I can hardly see the lod0 to lod1 transition and after also trying 35m and 45m in the same way to see if they where any better, I found that 40m seemed to be the best value for the LOD1 switching distance.

Now I'm going to do the same for lod2, which I know its main differences is that it generally has less detail, with some little bits missing, lower poly wheels and a few other things. With it at its default switching distance of 100m for lod2 I can't see any changes so going to try 80m and see how that dose. 80m seems good so going to try 60m and see if that's any good. 60m seems a little too soon so I'm going to try 70m and see what that's like. 70m seems good so I'm going to use that for my LOD2 switching distance

Did the others LODs in the same way and ended up with the following, which if your working on an assault rifle is what would be a good base to work off and probably what you should use:
geom\_1
LOD1: 40m
LOD2: 70m
LOD3: 250m

Once you have done all the LODs for your 3rd person meshes (most likely "geom\_1"), if your model also has a wreck mode then you will also need to work out all your LOD distances for your wreck model's LODs in exactly the same way as before, other than this time you will just need to select the "geom\_2" tab (possibly "geom\_1" if your model doesn't have any first person models) and work out the LOD switching distances in exactly the same way as before

For my Wreck model's LODs (geom\_2) I found the following LOD switching distances seemed to work best:
geom\_2
LOD1: 30m
LOD2: 150m

Once you have worked out all your LOD switching distances for all your geoms (other than the 1st person LODs of course), make a note of them and then open up your weapons ".tweak" file again with a text editor and then we can manually put in our LOD switching distances. Your .tweak file will most likely not have its LOD switching distances defined so we need to add the lines of code for them etc. Each LOD switching distance is defined by this line of code:

```
GeometryTemplate.setSubGeometryLodDistance

```

**NOTE:** The ,  and  at the end are representing numbers which define different functions.
"" Stands for the  type, where you can have up to 3 different types of geometry. Geom (Geometry) **0** being the "1st Person Model" in most cases, Geom **1** being the "3rd Person Model" in most cases and Geom **2** being the Wreck Model for vehicles.
If you recall we saw these Geoms in the Editor. Although note that these Germs can mean and do different things depending on the object type and the objects coding.
"" Stands for the  number. Although this setting is a little bit more confusing than it seems since its not the LOD Number that it says it is in the editor. Instead its that number -1. So the distance you defined for LOD2 in the editor, would in this line of code be LOD "1".
"" Stands for the  in meters, which we worked out in the editor and noted down above.

Now we just need to work out our "X, Y & Z" from what we worked out in the editor.
Now for this the "X" values are going to be either "1" or "2" in our case, unless the model doesn't have any 1st person meshes then it might be "0", but since the LAV3 dose have 1st person models, its going to be "1" for "geom\_**1**" and "2" for "geom\_**2**" No need to define lod switching distances for "geom\_0" since as we stated above, 1st person meshes dont use LODs in the same way 3rd person meshes do, it uses them for different functions for people in the vehicle who are not going to be getting any further away from it, without getting out of the vehicle first.
Now for the "Y" values, we know they are the LOD numbers shown in the editor -1. As such, LOD1 = 0, LOD2 = 1, LOD3 = 2.
And for "Z", they are just the values we noted down so for geom\_1, LOD1 = 40, LOD2 = 70, LOD3 = 250 and for geom\_2 LOD1 = 30 and LOD2 = 150.

```
GeometryTemplate.setSubGeometryLodDistance
GeometryTemplate.setSubGeometryLodDistance
GeometryTemplate.setSubGeometryLodDistance
GeometryTemplate.setSubGeometryLodDistance
GeometryTemplate.setSubGeometryLodDistance

```

As such, we just need to paste that code in to the very top of our .tweak file just under the following line:

Code:

```
rem *** Generated with Bf2Editor.exe [created: 2006/5/15 11:52]

```

Like so:

Save that up and your all done