meta data for this page
This is an old revision of the document!
Vertex Packing
In export formats that support it (currently only STSDK, used with the SpeedTree SDK), vertex packing lets you have complete control over the data stored in each vertex in the exported file, which allows the file data to be loaded directly into render buffers at runtime.
An XML file describes the vertex attribute setup, while a small script written in the Lua language allows you full control over packing data into each vertex however you wish.
Description XML
You define a vertex packer by placing an XML file describing it in the <app install>/vertex_packing directory.
Vertex streams represent separate buffers of data that can be bound to the vertex shader separately (though most common use is to just use one). Each stream can contain multiple vertex attributes. A description of the format is shown below.
<?xml version="1.0" encoding="UTF-8"?> <SpeedTreeVertexPacker Program=[filename of the lua script to run for this packer, often named the same but with the .lua extension] Force32bitIndices=[true/false to always use 32bit indices, or allow the indices to fall back to 16bit if there are fewer than 65k vertices] > <Stream Name=[name of this stream] > <Attribute Type=[type of variable used for this attribute: byte, byte, short, short, int, uint, half, float, or double] Count=[integer for how many elements in this attribute, 1-4] Normalize=[doesn't affect the packing, but does tell the runtime to normalize this attribute, for instance a 0-255 ubyte will come into the shader as 0.0-1.0] Description=[description of this stream, if wanted] > ... </Stream> ... </SpeedTreeVertexPacker>
Showcasing the above format description, this is the vertex packer file for the Standard packer used with the SpeedTree SDK.
<?xml version="1.0" encoding="UTF-8"?> <SpeedTreeVertexPacker Program="Standard.lua" Force32bitIndices="false" > <Stream Name="Main"> <Attribute Type="half" Count="4" Description="position(3) / texcoord_u(1)" /> <Attribute Type="half" Count="4" Description="lod_position(3) / texcoord_v(1)" /> <Attribute Type="ubyte" Count="4" Normalize="false" Description="normal(1) / binormal(1) / tangent(1) / wind_branch_dir(1)" /> <Attribute Type="ubyte" Count="4" Normalize="true" Description="wind_weight(1) / wind_ripple(1) / wind_branch_offset(1) / ao_blend_and_2sided_packed(1)" /> </Stream> </SpeedTreeVertexPacker>
Packing Script
During vertex packing, the packing script specified in the description XML file is run for each vertex. This script is written in Lua. While this documentation cannot cover every aspect of the Lua language, you can find additional info at www.lua.org and Lua Tutorials.
in_anchor | (3 float array) - anchor position for node |
in_offset | (3 float array) - offset from anchor |
in_lod_offset | (3 float array) - lod offset from anchor |
in_texcoord | (2 float array) - main UV |
in_lightmap_texcoord | (2 float array) - lightmap UV, if available |
in_normal | (3 float array) - vertex normal |
in_binormal | (3 float array) - vertex binormal |
in_tangent | (3 float array) - vertex tangent |
in_vertex_color | (3 float array) - vertex color |
in_vertex_alpha | (float) - vertex blend value |
in_ambient_occlusion | (float) - ambient occlusion value |
in_wind_branch_position | (3 float array) - position used for branch position in wind |
in_wind_branch_direction | (3 float array) - growth direction for the branch in wind |
in_wind_branch_weight | (float) - weight/amount for branch wind motion |
in_wind_ripple | (float) - wind ripple scalar |
in_bone_id | (integer) - id of the bone attached to this vertex |
in_two_sided | (boolean) - represents the two-sided flag on the material used on this vertex |
in_geometry_type | (integer) - Geometry type: Branch=0, Frond, Leaf, FacingLeaf, Billboard |
in_original_geometry_type | (integer) - Original geometry type before batching: Branch=0, SubDivBranch, Cap, Frond, Leaf, FacingLeaf, Mesh |
in_tree_extents | (6 float array) - Tree extents: min xyz, max xyz |