A Beginner's Introduction to U3D file format

30 Dec 2017

This post will serve as a simple introduction to the U3D file format specificaton for any person who needs to write an output or input stream for U3D objects or is genuinely interested in 3D formats. The goal of this post is to provide the details, DOs and DONTs for everything required to write a U3D writer.

This post will also contain an annotated U3D file and other important things which are needed to understand the file format and implement a basic U3D writer which will help in writing a mesh with textures, with vertex colors, with both textures and image colors and without both textures and vertex colors.

If after reading this post, you would still like to read the official file format specification then it be found here

What is U3D?

Before we start looking at the U3D file format, for those who don’t know what U3D is, this is an introduction section for U3D. U3D is a compressed file format standard for 3D omputer graphics data. The goal of U3D is to provide a format to write 3D mesh data so as to embed it into PDF file. U3D along with PRC are the two file formats aimed at providing people a way to embed 3D mesh data into PDF files.

Personally, for my job, I have only used 3D data to write meshes with corresponding textures to a U3D object. Although, you can write a lot more cool stuff with U3D like animation data which I won’t be covering in this post.

Supported Elements

If you plan to embed, your U3D objects in a PDF, then you should read this document first as Adobe Acrobat only supports a subset of the elements that U3D provides. Additionaly, Adobe also doesn’t support some of the texture modes like those of texture generation but I will talk about them later when I get into the details.

External Library

As part of the consortium, Intel released a library which is available on sourceforge.

File Format Essentials

This part contains all the essential things you need to know about the U3D file format.

Data Types in U3D files

Strings in U3D

Strings in a U3D file are written a bit differently than other ata types like uint32,float32,float64 amongst other data types.

All data types except strings are directly written to the file in little-endian order. But strings are not written this way.

The structure for writing a string is as follows:

From now on, the term STRING will act as a placeholder for the aforementioned structure of writing a string.

Other Notes

The bytes in the file are written in Little-Endian order. If you don’t know what endianness is, here is a link.

U3D File Structure

The U3D file is made up of 3 different types of blocks.

Each block must be 32-bit or 4-byte aligned with each other. This basically means a new block must ONLY start at an address which is divisible by 4. For more on aligned addresses and alignment, please read this.

Here is an image describing the structure of the blocks in U3D file which has been successful for me.

file_structure

What is a Block?

All Blocks in U3D have the same structure.

NOTE: Any padding byte must have the value 0x00.

File Header Block

This is the first block in the U3D file and it contains information describing the total size of the file, the total size of the declaration blocks, the character encoding of all the strings in the file and an optional scaling factor which provides the scaling factor by which values must be multiplied to be converted into meters.

Structure of the File Header Block

The options are as follows:

0x00000000 : No optional features used

0x00000002 : Uses extensibility features. This indicates that the file may use New Object Type blocks.

0x00000004 : No compression mode. This means that file doesn't contain any compressed values.

0x00000008 : Defined units. This indicates that the objects in the file are defined with units.

Modifier Chain Block

Modifier Chain Blocks are used to contain the declaration blocks for an object and its modifiers.

If an object does not have any modifiers, then the declaration block for that object is not required to be contained in a modifier chain block. But it is safe to always have the object declared inside a modifier chain block.

If an object has modifiers then the declaration blocks for the objects and its modifiers shall be contained in the data section of a modifier chain block.

Structure of the Modifier Chain Block

Node Blocks

Nodes are the entities that populate the scene graph. Each node type contains a name, the number of aprents it has, the name of each parent, and a transform for each parent specifying the position and orientation of the node relative to the parent.

For this report, I will only be covering the Model Node.

Model Node Block

The Model Node contains: a name, the number of parents, the parents’ names and a transform relative to each parent. The Model Node also contains the name of a resource modifier chain. A model node is the first modifier in a node modifier chain.

Structure of the Model Node Block

CLOD Mesh Generator Blocks

This contains the data needed to create a continuous level of detail mesh. This data includes vertices, normal vectors, faces, shader lists and level of detail information of the base mesh and updates.

For the purpose of this report, all the mesh information is contained inside the base mesh and there are no updates. Essentially there is only 1 level of detail containing all the information.

CLOD Mesh Declaration Block

This block contains the declaration information for a continuous level of detail mesh generator. The declaration information is sufficient to allocate space for the mesh data and create the mesh generator object. The actual mesh data is contained in the following continuation blocks.

This block must be a part of a resource modifier chain.

Structure of the CLOD Mesh Declaration Block

Max Mesh Description

This is a sub-part of the CLOD Mesh Declaration block and it describes the size of the mesh at full resolution ( highest level of detail ). For this report, the highest level of detail is 1 as all the information is present in a single level.

Structure of this part is as follows:

The available flags are:

0x00000000 - Default: The faces in the mesh have a normal index at each corner.

0x00000001 - Exclude Normals: The faces in the mesh do not have a normal index at each corner.

Shading Description

This is a sub-part of the Max Mesh Descriptions and it indicates which per vertex attributes, in addition to position and normal, are used by each shader list.

Structure of each Shading Description is as follows:

Options are as follows:

0x00000000 - The shader list uses neither diffuse colors nor specular colors.

0x00000001 - The shader list uses per vertex diffuse colors.

0x00000002 - The shader list uses per vertex specular colors.

0x00000003 - The shader list uses both diffuse and specular colors, per vertex

CLOD Description

It is a sub-part of the CLOD Mesh Declaration Block and it describes the range of resolutions available for the continuous level of detail mesh.

Structure of the CLOD Description is as follows:

Resource Description

This is a sub-part of the CLOD Mesh Declaration Block and contains information about Quality factors, Inverse Quantization and Resource Parameters.

Structure of the Resource Description is as follows:

CLOD Base Mesh Continuation Block

This block contains the base information for a continuous level of detail mesh generator. For the purpose of this report, the base mesh contains all the mesh as there is only one level of detail.

Structure of CLOD Base Mesh Continuation Block

Base Mesh Data

This is a subpart of the CLOD Base Mesh Continuation Block and it contains the data stored in the base mesh.

The structure is as follows :

Base Face

This is a subpart of the Base Mesh Data. Base Face is a face in the base mesh. the face contains an index into the shader list description array and indices into the various mesh arrays for each corner.

Base Corner Info

This is a sub-part of Base Face and it contains the indices into the various mesh arrays for a corner of a face on the

Structure of the Base Corner is as follows:

Shading Modifier Block

This describes the shading group that is used in the drawing of a mesh. This block must have a Model Node declared prior to it. This must be a part of the node modifier chain.

Structure of a Shading Modifier Block

The options are as follows:

0x00000001 - Mesh: the shading group is applied to the renderable mesh group.

0x00000002 - Line: The shading group is applied to the renderable line group.

0x00000004 - Point: The shading group is applied to the renderable point group.

0x00000008 - Glyph: The shading group is applied to the glyph string.

Lit Texture Shader Block

This contains information needed to determine the appearance of a surface during rendering. It includes references to Material Resources and Texture resources and how to combine those resources when rendering.

Structure of the Lit Texture Shader Block

The options are:

0x00000001: Lighting Enabled

0x00000002: Alpha Test Enabled

0x00000004: Use Vertex Color

The options are:

0x00000610: NEVER: The test never passes. No pixels are drawn.

0x00000611: LESS: The rendered alpha value must be less than the reference value.

0x00000612: GREATER: The rendered alpha value must be greater than the reference value.

0x00000613: EQUAL: The rendered alpha value must be equal to the reference value.

0x00000614: NOT_EQUAL: The rendered alpha value must not be equal to the reference value.

0x00000615: LEQUAL: The rendered alpha value must be less than or equal to the reference value.

0x00000616: GEQUAL: The rendered alpha value must be greater than or equal to the reference value.

0x00000617: ALWAYS: The test always passes. No pixels are rejected.

The options are:

0x00000604: FB_ADD: Add the RGB components into the framebuffer.

0x00000605: FB_MULTIPLY: Multiply the RGB components into the framebuffer.

0x00000606: FB_ALPHA_BLEND: Linear blend the RGB components into the framebuffer based on the rendered alpha value.

0x00000607: FB_INV_ALPHA_BLEND: Linear blend the RGB components into the framebuffer based on the inverse of the rendered alpha.

Texture Information

This is a sub-part of the Lit Texture Shader and it identifies the texture used by a particular shader channel. it also describes how the textures are blended and which texture coordinates to use for that shader channel.

The options are:

0 - Multiply: blended = current * previous

1 - Add: blended = current + preious

2 - Replace : blended  = current

3 - Blend : blended = current * currentAlpha + previous * ( 1 - currentAlpha )

The options are:

0 - Alpha value of each pixel

1 - Blending constant

The options are:

0x00: TM_NONE - The shader does not generate texture coordinates

0x01: TM_PLANAR - This is not supported by Adobe and hence isn't covered here.

0x02: TM_CYLINDRICAL - This is not supported by Adobe and hence isn't covered here.

0x03: TM_SPHERICAL - This is not supported by Adobe and hence isn't covered here.

0x04: TM_REFLECTION - The shader performs a spherical reflection mapping. This is used to generate texture coordinates for reflection mapping when using a specially designed spherical reflection texture. This is not supported by the software renderer and may not be supported by older or built-in graphics cards.

The options are:

0x01 - Repeat in the direction of the first texture coordinate dimension.

0x02 - Repeat in the direction of the second texture coordinate dimension.

Material Resource Block

This block contains information defining how a material interacts with light in a scene.

Structure of a Material Resource Block

The options are:

0x00000001 - Ambient

0x00000002 - Diffuse

0x00000004 - Specular

0x00000008 - Emissive

0x00000010 - Reflectivity

0x00000020 - Opacity

Texture Resource Blocks

These blocks contain information for creating a texture iage to be applie to geometry. The 2 blocks are the Texture Declaration Block and Texture Continuation Block

Texture Declaration Block

This block describes the texture image and the continuation images. This block must be a modifier in the texture modifier chain block.

Structure of the Texture Declaration Block

The valid values are:

0x01 - alpha component

0x0E - color RGB

0x0F - color RGBA

0x10 - luminance (greyscale)

0x11 - luminance and alpha

The options are:

0x01 - JPEG-24

0x02 - PNG 

0x03 - JPEG-8

0x04 -TIFF. This option is not supported in Adobe

The options are:

0x01: alpha channel

0x02: blue channel

0x04: green channel

0x08: red channel

0x10: luminance ( red, blue and greent channels )

The valid values are:

0x0000: default attributes

0x0001: external continuation image file reference.

Texture Continuation Block

This block contains image data for a continuation image previously desrcibed in the texture declaration.

Example

The example is a complete U3D file containing a texture-less mesh with no vertex colors of a standard cube.

;; File Header Block
; Blocktype 0x00443355
55 33 44 00 
; Data Size: 32 bytes
20 00 00 00 
; Metadata Size: 0 bytes
00 00 00 00
; Major Version: 0 
00 00
; Minor Version: 0 
00 00
; Profile Identifier Value: 0x0000000C - No compression mode and Units are defined
0C 00 00 00 
; Declaration Size: 297 bytes
29 01 00 00 
; File Size: 639 bytes
7F 02 00 00 00 00 00 00 
; Character Encoding: 106. This coresponds to UTF8
6A 00 00 00
; Units scaling Factor: 1.0
00 00 00 00 00 00 F0 3F 

;; Node Modifier Chain Block
; BlockType: 0xFFFFFF14
14 FF FF FF
; Data Size: 68 bytes
44 00 00 00 
; Metadata Size: 0 bytes
00 00 00 00
; Size of the Name of the Modifier Chain: 8 bytes  
08 00 
; Name of the Modifier Chain: MeshNode
4D 65 73 68 4E 6F 64 65
; Modifier Chain Type: 0. Node Modifier Chain 
00 00 00 00
; Modifier Chain Attributes 
00 00 00 00
; Padding or 32-bit alignment 
00 00
; Modifier Count: 1 
01 00 00 00
;; Model Node Block
; Blocktype: 0xFFFFFF22 
22 FF FF FF
; Data Size: 32 bytes 
20 00 00 00 
; MetaData Size: 0 bytes
00 00 00 00
; Size of the model node name: 8 bytes 
08 00
; Model Node name : MeshNode 
4D 65 73 68 4E 6F 64 65
; Parent Node Count: 0 
00 00 00 00
; Size of the name of the resource modifier chain : 12 bytes 
0C 00
; Name of the resource modifier chain: MeshResource 
4D 65 73 68 52 65 73 6F 75 72 63 65
; Visibility : 3 - Both front and back visible 
03 00 00 00

;; Resource Modifier Chain Block
; Blocktype 0xFFFFFF14 
14 FF FF FF
; Data Size: 160 bytes 
A0 00 00 00
; MetaData Size: 0 bytes 
00 00 00 00 
; Size of the name of the modifier chain : 12 bytes
0C 00
; Name of the modifier chain: MeshResource 
4D 65 73 68 52 65 73 6F 75 72 63 65
; Modifier Chain Type: 1 - Resource Modifier Chain 
01 00 00 00
; Modifier Chain Attributes : 0
00 00 00 00
; Padding for 32-bit alignment 
00 00
; Modifier Count : 1 
01 00 00 00
;; CLOD Mesh Declaration
; Blocktype : 0xFFFFFF31 
31 FF FF FF
; Data Size: 142 bytes 
8E 00 00 00
; MetaData Size: 0 bytes 
00 00 00 00
; Size of the name of Mesh Declaration : 12 bytes 
0C 00 
; Name of the Mesh Declaration: MeshResource
4D 65 73 68 52 65 73 6F 75 72 63 65 
; Chain Index : 0
00 00 00 00 
;; Max Mesh Description
; Mesh Attributes: 0x00000001 - Exclude Normals
01 00 00 00
; Face Count: 12 
0C 00 00 00 
; Positon Count : 8
08 00 00 00
; Normal Count : 0 
00 00 00 00 
; Diffuse Color Count: 0
00 00 00 00 
; Specular Color Count: 0
00 00 00 00 
; Texture Coord Count: 0
00 00 00 00 
; Shading Count: 1
01 00 00 00 
;; Shading Description
; Shading Attributes : 0x00000000 - Shader doesn't use diffuse or specular colors
00 00 00 00
; Texture Layer Count: 0
00 00 00 00 
; Original Shading ID: 0
00 00 00 00
;; CLOD Description 
; Minimum Resolution: 8
08 00 00 00 
; Final Maximum Resolution: 8
08 00 00 00
;; Resource Description
; Position Quality Factor : 0 
00 00 00 00 
; Normal Quality Factor : 0
00 00 00 00
; Texture Coord Quality Factor 
00 00 00 00 
; Position Inverse Quant : 1.0
00 00 80 3F 
; Normal Inverse Quant : 1.0
00 00 80 3F 
; Texture Coord Inverse Quant : 1.0
00 00 80 3F 
; Diffuse Color Inverse Quant : 1.0
00 00 80 3F 
; Specular Inverse Quant : 1.0
00 00 80 3F 
; Normal Crease Parameter : 0.0
00 00 00 00 
; Normal Update Parameter : 0.0
00 00 00 00
; Normal Tolerance Parameter : 0.0 
00 00 00 00 
; Bone Count : 0
00 00 00 00 
; Padding for 32-bit alignment
00 00 

;; CLOD Mesh Continuation
; Blocktype: 0xFFFFFF3B
3B FF FF FF 
; Data Size: 330 bytes
4A 01 00 00 
; Metadata Size: 0 bytes
00 00 00 00 
; Size of the name of the Mesh Declaration: 12 bytes
0C 00 
; Name of the mesh declaration : MeshResource
4D 65 73 68 52 65 73 6F 75 72 63 65 
; Chain Index: 0
00 00 00 00 
; Base Face Count : 12
0C 00 00 00 
; Base Position Count : 8
08 00 00 00
; Base Normal Count : 0 
00 00 00 00 
; Base Diffuse Color Count : 0
00 00 00 00 
; Base Specular Color Count : 0
00 00 00 00 
; Base Texture Coord Count : 0
00 00 00 00 
;; Positons Array
; Position 1: ( 0, 0, 0 )
00 00 00 00 00 00 00 00 00 00 00 00 
; Position 2: ( 1.0, 0, 0 )
00 00 80 3F 00 00 00 00 00 00 00 00
; Position 3: ( 0, 1.0, 0 ) 
00 00 00 00 00 00 80 3F 00 00 00 00 
; Position 4: ( 0, 0, 1.0 )
00 00 00 00 00 00 00 00 00 00 80 3F 
; Position 5: ( 1.0, 1.0, 0 )
00 00 80 3F 00 00 80 3F 00 00 00 00 
; Position 6: ( 1.0, 0, 1.0 ) 
00 00 80 3F 00 00 00 00 00 00 80 3F 
; Position 7: ( 0, 1.0, 1.0 )
00 00 00 00 00 00 80 3F 00 00 80 3F
; Position 8 : ( 1.0, 1.0, 1.0 ) 
00 00 80 3F 00 00 80 3F 00 00 80 3F 
;; Face Array
; Face 1 Original Shading Index: 0
00 00 00 00 
; Face 1 Position Indices ( 0, 1, 2 )
00 00 00 00 
01 00 00 00 
02 00 00 00 
; Face 2 Original Shading Index: 0
00 00 00 00 
; Face 2 Position Indices ( 1, 2, 4 )
01 00 00 00 
02 00 00 00 
04 00 00 00 
; Face 3 Original Shading Index: 0
00 00 00 00
; Face 3 Position Indices ( 0, 2, 3 ) 
00 00 00 00 
02 00 00 00 
03 00 00 00 
; Face 4 Original Shading Index: 0
00 00 00 00 
; Face 4 Position Indices ( 2, 3, 6 )
02 00 00 00 
03 00 00 00 
06 00 00 00 
; Face 5 Original Shading Index: 0
00 00 00 00 
; Face 5 Position Indices ( 0, 1, 3 )
00 00 00 00 
01 00 00 00 
03 00 00 00 
; Face 6 Original Shading Index: 0
00 00 00 00 
; Face 6 Position Indices ( 1, 3, 5 )
01 00 00 00 
03 00 00 00 
05 00 00 00 
; Face 7 Original Shading Index: 0
00 00 00 00 
; Face 7 Position Indices ( 1, 4, 5 )
01 00 00 00 
04 00 00 00 
05 00 00 00 
; Face 8 Original Shading Index: 0
00 00 00 00 
; Face 8 Position Indices ( 4, 5, 7 )
04 00 00 00 
05 00 00 00 
07 00 00 00 
; Face 9 Original Shading Index: 0
00 00 00 00 
; Face 9 Position Indices ( 4, 6, 7 )
04 00 00 00 
06 00 00 00 
07 00 00 00 
; Face 10 Original Shading Index: 0
00 00 00 00 
; Face 10 Position Indices ( 2, 4, 6 )
02 00 00 00 
04 00 00 00 
06 00 00 00 
; Face 11 Original Shading Index: 0
00 00 00 00 
; Face 11 Position Indices ( 3, 5, 6 )
03 00 00 00 
05 00 00 00 
06 00 00 00 
; Face 12 Original Shading Index: 0
00 00 00 00 
; Face 3 Position Indices ( 5, 6, 7 )
05 00 00 00 
06 00 00 00 
07 00 00 00 
; Padding for 32-bit alignment
00 00