BSP (Source)
Lighting
The lighting lump (Lump 8) is used to store the static lightmap samples of map faces. Each lightmap sample is a colour tint that multiplies the colours of the underlying texture pixels, to produce lighting of varying intensity. These lightmaps are created during the VRAD phase of map compilation and are referenced from the dface_t
structure. The current lighting lump version is 1.
Each dface_t
may have a up to four lightstyles defined in its styles[]
array (which contains 255 to represent no lightstyle). The number of luxels in each direction of the face is given by the two LightmapTextureSizeInLuxels[]
members (plus 1), and the total number of luxels per face is thus (LightmapTextureSizeInLuxels[0]
1) * (LightmapTextureSizeInLuxels[1]
1).
Each face gives a byte offset into the lighting lump in its lightofs
member (if no lighting information is used for this face e.g. faces with skybox, nodraw and invisible textures, lightofs
is -1.) There are (number of lightstyles)*(number of luxels) lightmap samples for each face, where each sample is a 4-byte ColorRGBExp32 structure:
struct ColorRGBExp32
{
byte r, g, b;
signed char exponent;
};
Standard RGB format can be obtained from this by multiplying each colour component by 2^(exponent). For faces with bumpmapped textures, there are four times the usual number of lightmap samples, presumably containing samples used to compute the bumpmapping.
Immediately preceeding the lightofs
-referenced sample group, there are single samples containing the average lighting on the face, one for each lightstyle, in reverse order from that given in the styles[]
array.
Version 20 BSP files contain a second, identically sized lighting lump (Lump 53). This is presumed to store more accurate (higher-precision) HDR data for each lightmap sample. The format is currently unknown, but is also 32 bits per sample.
The maximum size of the lighting lump is 0x1000000 bytes, i.e. 16 Mb (MAX_MAP_LIGHTING).
Occlusion
The occlusion lump (Lump 9) the polygon geometry and some flags used by func_occluder entities. Unlike other brush entities, func_occluders don't use the 'model' key in the entity lump. Instead, the brushes are split from the entities during the compile process and numeric occluder keys are assigned as 'occludernum'. Brush sides textured with tools/toolsoccluder
or tools/toolstrigger
are then stored together with the occluder keys and some additional info in this lump.
The lump is divided into three parts and begins with a integer value with the total number of occluders, followed by an array of doccluderdata_t
fields of the same size.
The next part begins with another integer value, this time for the total number of occluder polygons, as well as an array of doccluderpolydata_t
fields of equal size. Part three begins with another integer value for the amount of occluder polygon vertices, followed by an array of integer values for the vertex indices, again of the same size.
struct doccluder_t
{
int count;
doccluderdata_t data[occluderCount];
int polyDataCount;
doccluderpolydata_t polyData[occluderPolyDataCount];
int vertexIndexCount;
int vertexIndices[occluderVertexIndexCount];
};
The doccluderdata_t
structure contains flags and dimensions of the occluder, as well as the area where it remains.
firstpoly
is the first index into the doccluderpolydata_t
with a total of polycount
entries.
struct doccluderdata_t
{
int flags;
int firstpoly; // index into doccluderpolys
int polycount; // amount of polygons
Vector mins; // minima of all vertices
Vector maxs; // maxima of all vertices
// since v1
int area;
};
Occluder polygons are stored in the doccluderpolydata_t
structure and contain the firstvertexindex
field, which is the first index into the vertex array of the occluder, which are again indices for the vertex array of the vertex lump (Lump 3). The total number of vertex indices is stored in vertexcount
.
struct doccluderpolydata_t
{
int firstvertexindex; // index into doccludervertindices
int vertexcount; // amount of vertex indices
int planenum;
};