This page describes custom BluffTitler file formats and extensions to standard file formats.
This info is only meant for software engineers. You do not have to understand anything on this page in order to use BluffTitler.
BluffTitler stores its effects in CFX files. The format has been introduced by Outerspace Software at the release of BluffTitler version 12 as replacement for the deprecated DirectX 9 FX format.
This info is only meant for software engineers. You do not have to understand anything on this page in order to use effects. Click here to learn how to use effects
Effects come in 2 formats:
BFX | a text format containing the HLSL source code |
CFX | a binary format containing the compiled shaders (bytecode) |
The consumer editions of BluffTitler can only load CFX files. You can compile BFX to CFX with the developer edition. The developer edition is currently not for sale.
A BFX file header looks like this:
BFX 6
DESCRIPTION "This effect does this and that and also..."
PBR 1
PBR sets the lighting model. It can be 0 (Blinn-Phong) or 1 (Physically Based Rendering)
Up to 10 textures can be used:
0, 1, 2, 3 | defined by the effect and editable in the GUI |
4 | glow map, added by the compiler, editable in the GUI |
5 | depth buffer |
6 | stencil buffer |
7, 8, 9, 10 | cascading shadow maps, added by the compiler |
Textures are defined like this:
TEXTURE 0 COLOUR MIP * *
TEXTURE 1 NORMAL MIP * *
TEXTURE 2 CUBE MIP * *
TEXTURE 3 ORM MIP * *
1st string is always TEXTURE
2nd string is the texture index [0, 5]
3rd string is the texture type {COLOUR, REFLECTION, CUBE, NORMAL, DEPTH, STENCIL, VOXEL, SKETCH, CARTOON, ALPHA, TONALART, DISPLACEMENT, FUR, ORM, GLOW}
4th string sets mipmapping {*, MIP, LIN}. * means that the effect must not make adjustments.
5th string sets horizontal texture mode {*, CLAMP, WRAP, MIRROR}
6th string sets vertical texture mode {*, CLAMP, WRAP, MIRROR}
Textures can be accessed like this:
float4 c=MyTexture0.Sample(MySampler0, input.tex);
float4 c=MyTexture0.SampleLevel(MySampler0, input.tex, 0);
static const float cPI=3.141593;
static const float cNearClippingPlane=1;
static const float cFarClippingPlane=2000;
static const int cTextureIndex_Glow=4;
static const int cTextureIndex_Depth=5;
static const int cTextureIndex_Stencil=6;
static const int cTextureIndex_Shadow0=7;
static const int cTextureIndex_Shadow1=8;
static const int cTextureIndex_Shadow2=9;
static const int cTextureIndex_Shadow3=10;
An effect file can add 16 extra properties to a layer by using the following annotations:
UIName | The property name as it must appear in the GUI |
UIMin | The minimum value |
UIMax | The maximum value |
UIDefault | The default value |
UISliders | Number of sliders {1,2,3} |
UIScale | Scale to GUI factor |
UIInteger | Set to true for integer variables |
UIWidget | Widget |
The 16 extra properties can be defined this way:
float4 Prop0
<
string UIName="My very own variable";
float UIMin=0;
float UIMax=10;
float3 UIDefault=float3(2,0,0);
int UISliders=1;
float UIScale=1;
bool UIInteger=true;
int UIWidget=0;
>
Every property has a widget:
0 | default |
1 | angle |
2 | colour |
A pass contains render states, links to HLSL code and other properties. A pass is defined like this:
PASS
BLENDING ADDITIVE
ZREAD Y
ZWRITE Y
RGBAWRITE 7
CULL BACK
SOLID Y
CLEARTARGET Y
VS vs_4_0 VS1
HS hs_4_0 HS1
DS ds_4_0 DS1
GS gs_4_0 GS1
PS ps_4_0 PS1
All render states are booleans {Y, N} except the following:
BLENDING can be {NONE, ALPHA, ADDITIVE, SUBTRACTIVE, MAX}
RGBAWRITE can be [0, 15]. Y is accepted as 15 and N as 0.
CULL can be {FRONT, BACK, NONE}
The next pass in the same effect takes over the renderstates of the previous pass. The next effect resets the renderstates.
Every pass must have a vertex (VS) and pixel shader (PS). Hull (HS), domain (DS) and geometry shaders (GS) are optional.
The CLEARTARGET state is only used in the 2nd pass of a postprocessing effect.
When only a single light layer is using shadow maps, 4 cascading shadow maps (CSM) are created. In this situation, textures 6 (near), 7, 8 and 9 (far) are used for the 4 sub frusta.
If an effect is applied to the camera layer, the 1st texture contains the render output. This way it can be used as a post processing effect.
When the effect has 2 passes, the output of the 1st pass is used as the input for the 2nd pass. This can be used to optimize effects, like for example a bilinear blur. Note that this convention makes normal 2 pass effects useless for the camera layer.
When the effect has 4, 6, 8,... passes, the chain is repeated.
The render target is cleared by default. For some effects, like for example a bloom, you don't want this. It can be prevented by setting the CLEARTARGET pass property to N:
CLEARTARGET N
BluffTitler uses the following vertex format:
struct | VS_INPUT{ | |
float4 | pos: | POSITION; |
float4 | normal: | NORMAL; |
float4 | col: | COLOR; |
float2 | tex: | TEXCOORD0; |
float4 | tangent: | TANGENT; |
}; |
Meshes generated with the Tubular square, Tubular round, Wireframe, Light discs, Light bulbs and Comb text layer styles abuse the tangent field to store special info: (bulb/bulbs, contour, contours)
All matrices are 4x4 homogeneous transformation matrices in row major format.
World | model to world space |
WorldA | text layer: model (char) to text space |
WorldB | text layer: text to world space. (World = WorldA * WorldB) |
WorldC | text layer: same as WorldA, but without character rotation, twist and explosions. Used for UV mapping. |
View | world to view space |
Projection | view to projection(screen) space |
WorldView | world * View |
ViewProjection | view * projection |
WorldViewProjection | world * view * projection |
WorldNormal | normals to world space |
WorldNormalA | text layer: normals from model to text space. |
WorldNormalB | text layer: normals from text to world space. (WorldNormal = WorldNormalA * WorldNormalB) |
ShadowmapMatrix[4] | world to shadow map space |
InverseMirror | mirrored to non mirrored world space |
InverseMirrorNormal | mirrored reflection to non mirrored world space |
InverseView | inverse view matrix |
InverseProjection | inverse projection matrix |
InverseViewProjection | inverse projection * inverse view |
All vectors are 4D floats. The coordinate system is left-handed.
EyePos | X | Y | Z | W |
TextureResolution[11] | width | height | depth | aspect ratio (width/height) |
Material | R | G | B | A |
Power | specular power | alpha test mirror | fog range start | fog range full |
AmbientCol | R | G | B | 1 |
Lights | number of lights (-1 means the shadow map is being rendered) | fog R | fog G | fog B |
DiffuseCol[4] | R | G | B | 1 |
SpecularCol[4] | R | G | B | 1 |
LightPos[4] | X (point light) or XN (directional light) | Y (point light) or YN (directional light) | Z (point light) or ZN (directional light) | shadow intensity |
LightType[4] | light type: 0 directional 1 point | shadow algorithm: 0 projected shadows 1 shadow volumes 2 shadow maps | cast shadow softness | self shadow softness |
Shadowmap[4] | K directional light plane (N*P=K) | fixed depth bias | slope depth bias | - |
Time | show time in seconds | particle time in seconds | particle lifetime in seconds | alpha test |
LocalTime | hours | minutes | seconds | milliseconds |
ModelRepeat | picture layer: model repeat property X text and scroller layer: word index voxel layer: tissue density property X | picture layer: model repeat property Y text and scroller layer: words voxel layer: tissue density property Y | picture layer: model repeat property Z | quality {0,1,2,3} |
TextureRepeat | picture and mirror layers: texture repeat property X | picture and mirror layers: texture repeat property Y | CSM (1 means yes) | submodels |
CharacterIndex | text and scroller layer: character index picture layer when using model repeat prop: tile | text and scroller layer: characters picture layer when using model repeat prop: tiles | text and scroller layer: Unicode value | submodel |
PivotPoint | X | Y | Z | 1 |
MirrorSpecularity | mirror exists (1 means yes) | mirror specularity | mirror gradient (Fresnel effect) | clip (1 means yes) |
MirrorPlane | XN | YN | ZN | K (N*P=K) |
Glow | 0: normal rendering, normal material 1: normal rendering, emissive material 2: glow map rendering, normal material 3: glow map rendering, emissive material | roughness factor | metalness factor | double sided (1 means yes) |
Amplitude[5] | audio amplitudes are stored in 20 floats: [0] contains all, [1] contains lowest frequency, [19] contains highest frequency. | |||
Prop[16] | the effect specific variables. The w component is always 1. | |||
WaterHeader | waves | steepness | - | - |
WaterData[120] | frequency | amplitude | heading | phase |
The HLSL source code (vertex, hull, domain, geometry and pixel shaders) follows after the HLSL tag:
HLSL
The compiled bytecode follows after the COMPILED tag:
COMPILED VS 0 2708
2nd string is the shader type {VS,HS,DS,GS,PS}
3rd string is the pass
4th string is the size in bytes
Shaders can be shared between passes like this:
COMPILED VS 0,1,2,3,4 2708
The sketch layer of BluffTitler uses the EPS format to import line drawings. The EPS format however is limited to 2D positions. BluffTitler adds a few extensions to make 3D positions possible to store, for example, roller coaster paths. Those extensions are introduced at the release of BluffTitler 7.5. They are BluffTitler specific and not compatible with any other software supporting the EPS format.
This info is only meant for software engineers. You do not have to understand anything on this page in order to use 3D sketches. Click here to learn how to use 3D sketches
By default, BluffTitler centres and scales all EPS files to fit in the same box. This can be overruled with the following commands:
%%BluffTitler Scale N
%%BluffTitler Centre N
Other BluffTitler commands:
%%BluffTitler MaxLinesPerCurve x
XYZ are positions, abc are tangents.
X Y moveto
X Y Z moveto
X Y Z a b c moveto
XYZ are positions, abc are tangents.
X Y lineto
X Y Z lineto
X Y Z a b c lineto
XYZ are positions, abc are tangents.
X Y X Y X Y curveto
X Y Z X Y Z X Y Z curveto
X Y Z X Y Z X Y Z a b c curveto
The BO file format has been introduced by Outerspace Software at the release of Bixelangelo version 4. I was meant for debugging only but turned out to be an excellent way to design roller coasters.
The text format does the same as you do in the GUI by adding elements in the WINDOW > Element dialog. The element names and parameters are the same as in the GUI. Here's an example:
Bixelangelo 1.0
Move 0 0 0 0
Element "Straight line" 20
Element "Lift hill" 75 110
Element Dive 50 100
Element "Circular loop" 40 20 0
Element Turn 180 20 00 45
Element "Straight line" 145
Element Turn 180 30 0 45
Close
To open a BO file, start Bixelangelo and choose FILE > Open.... Examples can be found in the Bixelangelo\Media\Sketches folder.
Always start with the header:
Bixelangelo 1.0
The Move command starts a new curve:
Move X Y Z Angle
Element names with a space require quotation marks:
Element "Circular loop" 40 20 0
The Close command is used to connect the last point to the first.
Close
The robotic arm layer of BluffTitler uses 3D models in the OBJ format. BluffTitler extends this format to store robotic arm info.
This info is only meant for software engineers. You do not have to understand anything on this page in order to use robotic arms. Click here to learn how to use robotic arms
Type | Limbs (submodels) | Joints | Mirrored | Hinges (DOF) | Hinge orientations |
1 | 4 | 5 | Y | 4 | Shoulder (heading, roll, pitch), Elbow (pitch) |
2 | 8 | 9 | N | 7 | Shoulder (heading, roll, pitch), Elbow (pitch), Wrist (pitch, roll, heading) |
3 | 3 | 4 | N | 2 | Shoulder (heading, pitch) |
#BluffTitlerRoboticArmType 3
#BluffTitlerRoboticArmJoint 0 0 0
#BluffTitlerRoboticArmJoint 0 120 0
#BluffTitlerRoboticArmJoint 0 320 0
#BluffTitlerRoboticArmJoint 0 490 0
The following texture URLs have special meaning:
Empty URL | When the active layer is a model layer, this uses the texture as defined by the 3D model. Learn more |
X | When the active layer is a model layer, this uses no texture, even when the 3D models offers one. Learn more |
Empty URL in the 1st texture slot | When the active layer is a camera layer, this means that the render output must be used as the texture. Learn more |
Empty URL in the 1st texture slot | When the active layer is a plasma layer, this means that the generated plasma texture must be used as the texture. Learn more |
URL starts with colourmap | This uses the texture generated by a colour map layer. Click on the Select colour map layer... button to generate the URL. |
URL starts with cubemap | This uses the texture generated by a cube map layer. Click on the Select cube map layer... button to generate the URL. |
URL starts with QR | This generates a texture of a QR code. Click on the QR... button to generate the URL. |
URL starts with xml: | This loads the URL from an XML file. Learn more |
URL starts with dir: | This collects all textures from a folder. Learn more |
glowmap | The glowmap. Learn more |
prevframe | The previous frame. This only works when the camera layer uses an effect, like for example NotLightened. |