BLS

From wowdev
Revision as of 21:05, 2 May 2015 by Rour (talk | contribs)
Jump to navigation Jump to search

BLS is the container format that stores the GPU shaders used to render the world. In WoD, there are now four different shader types under the Shaders\* directory.

  • Vertex
    • (versions: arbvp1, vp40, glvs_150, ps_2_0, ps_3_0, ps_4_0, ps_5_0)
  • Fragment
    • (versions: arbfp1, fp40, glfs_150, ps_2_0, ps_3_0, ps_4_0, ps_5_0)
  • Geometry
    • (versions: glgs_150, gs_4_0, gs_5_0)
  • Hull/Domain (equivalent to Tessellation in OpenGL, except WoW currently only has these shaders for DX)
    • (versions: ds_5_0/hs_50)

In MoP+, the BLS format changed significantly (the version increased from 1.3 to 1.4), a new header has been introduced and all of the shader text inside the BLS files is now contained inside compressed chunks. Very little appears to be known about the structure of the format itself, and the meaning of the various fields. Below is enough information to be able to extract the compressed chunks and read out shader text from the various shader components. Additionally, the Shaders\Effects folder contains WFX files that allow WoW to map shader types from models onto the various shader components (although, there are occasions in the M2 source code where shaders are picked in code).

Header

  • Main header (0xC bytes)

This header is in all files - pixel and vertex shaders in all profiles.

struct BLSHeader {
/*0x00*/	char[4] magix;		// in reverse character order: "SVXG" in case of a vertex shader, "SPXG" in case of a fragment shader
/*0x04*/	uint32 version;		// Always 0x10003 - version 1.3 of format
/*0x08*/	uint32 permutationCount;
/*0x0C*/
};

Blocks

There are permutationCount blocks of the following structure. They are padded to 0x*0, 0x*4, 0x*8 and 0x*C.

struct BLSBlock {
/*0x00*/	DWORD flags0;		// seen: 0x3FE80 in pixel shaders; 0x1A0F in vertex shaders. there may be more ..
/*0x04*/	DWORD flags4;		// seen: 0x200 in pixel shaders; 0x3FEC1 in vertex shaders (there may be more ..)
/*0x08*/	DWORD unk8;		// Never seen anything in here.
/*0x0C*/	uint32 size;		// Tells you how large the block actually is.
/*0x10*/	char data[size];	// In whatever format defined.
/*----*/
};