SFF.TXT


Remove Frame

----- SFF -----

The SFF ray-tracing format
 
Version 8

Anto'nio Costa, 1993
[email protected]


Table of Contents

Table of Contents 2
1. Introduction 3
2. Overview and Motivations 3
3. Main Sections 3
3.1. Viewing 3
3.2. Ambient and Background 4
3.3. Lights 4
3.4. Surfaces 4
3.5. Objects, Textures and Transformations 5
4. Compatibility 11
5. Examples 12
6. Conclusions 1 3
7. References 13
8. Annexes 14
8.1. Annex 1 - Font formats PPF and PPE 14
8.2. Annex 2 - CSG Example 17
8.3. Annex 3 - Textured Spheres Examples 18
8.4. Annex 4 - Striped Spheres Example 20


1. Introduction

The SFF (Simple File Format) is a simple way of describing geometry 
(3D objects), colors, surfaces and so on. It is mainly used to describe 
environments that are processed by programs called ray-tracers, 
which simulate, at least to a certain extent, the physics of optical
processes and interactions between light and matter.

The ray-tracing algorithm produces images of 3D objects by shooting 
rays from a point in space (called eye point) through a grid of 
points (centered in the look point) and then computing, for each of 
these directions (which correspond basically to a screen pixel), the 
color of the nearest object in that particular direction. For the 
color calculation, the object's surface perpendicular vector (also called 
normal vector) in the point of intersection with the ray is used to 
determine the directions of auxiliary rays such as reflected and 
transmitted rays, along with the light sources contributions. Each of these 
contributions is scaled according to the object's surface characteristics 
and then the pixel color is finally obtained and stored.

2. Overview and Motivations

The first version of the SFF format was defined in late 1988, when 
the first running version of the RTRACE ray-tracer was operational. 
As this program was first written in Pascal, one major goal of SFF 
was simplicity. As the Pascal language is not very good in I/O 
support, the objective was to define it simple enough so that it 
would not be too complicated to parse.

Another simple scene format is NFF (Neutral File Format), invented 
by Eric Haines for his SPD package (Standard Procedural Database - 
a collection of C programs that generates test scenes for any type 
of rendering programs, including ray-tracers). It is widely used, 
but does not support many advanced features. Within the RTRACE package
there is a program to translate NFF scenes to SFF (it runs on UNIX 
and DOS machines).

3. Main Sections

Any SFF file is divided into 5 sections (or 6, for compatibility 
purposes). In each one there are definitions, which can be of several types.

3.1. Viewing

This section is the first one to appear. It has 5 lines, in which 
the first is reserved for comments, and then come eye point, look 
point, up vector and finally horizontal/vertical view angles. Each of 
these items must be in a line. After each one, anything can follow 
up to the end of line.
 
Example:

viewr
8 0 0- Eye<EOL>
0 0 0- Look<EOL>
0 1 0- Up<EOL>
20 20- View angles (horizontal and vertical)<EOL>

3.2. Ambient and Background

After the viewing section comes the Ambient/Background section. It 
has 3 lines, in which the first one is reserved for comments, the 
second defines the background color and the last defines the ambient 
color (in RGB format, both). After each item there may be comments 
up to the end of line. 

Example:

colors<EOL>
0.1 0.5 0.7- Sky blue(red=0.1 green=0.5 blue=0.7)<EOL>
0.2 0.2 0.2- Dark gray(red=0.2 green=0.2 blue=0.2)<EOL>

3.3. Lights

The Lights section defines lights, which can be of 3 types. Normally,
the illumination decreases with distance; to make it distance-
independent, the brightness should be negative (at least one component).
The first line is for comments, and then each line defines a light. 
To end the section, there must be an empty line.
The point light is defined by code 1, a position and RGB brightness.
The directional light is defined by code 2, position, RGB brightness, 
direction, angle and attenuation factor. This kind of light irradiates 
from a point in the specified direction inside the solid 
angle, and the transition may be sharp (factor ~= 1) or soft 
(factor >> 1). A truly directional light may be simulated by 
positioning it far away from the objects and defining its brightness 
negative.  The extended light is defined by code 3, position, 
RGB brightness, radius and samples. This 
kind of light is simulated by a sphere of specified radius, which 
is sampled to calculate the actual illumination (a low value for samples 
produces undesirable effects).

Example:

lights<EOL>  
1  4 5 1  0.9 0.9 0.9- White point light<EOL>
2  0 10 0  0 0 1  0 -1 0  15 5- Blue spot light<EOL>
3  8 1 -3  0 1 0  0.3 8- Green extended light<EOL>
1  1000 1000 1000  -1 -1 -1- Directional light<EOL>
<EOL>

3.4. Surfaces

In this section all the surfaces used must be defined. It starts with a 
line reserved for comments and then a line for each surface, ending in 
an empty line. There are 2 types of surface definitions.

The code 1 defines a surface by body RGB color, diffuse RGB factor, 
specular RGB factor, specular exponent factor, metalness factor and 
transmission RGB factor. The RGB's colors and factors must be in the 
[0,1] range. The diffuse RGB factor defines the quantity of light coming 
from all directions. The specular RGB factor defines the quantity of 
light coming from the ideal reflection direction. The exponent factor 
controls the shininess of the surface (the surface is very shiny with factors 
bigger than 10; if near zero, it appears dull). The metalness factor makes 
the reflected light appear white if it is small (like in plastic) 
or metallic if it is near 1. The transmission RGB factor defines the 
transparency. The sum of diffuse, specular and transparency RGB factors 
should be equal or approximately 1.

The code 2 surface has body RGB color, smoothness RGB factor, metalness 
RGB factor and transmission RGB factor. This is an alternative for 
defining surfaces, but this method is more intuitive. The smoothness 
RGB factor controls the shininess of the surface. 

Example:

surfaces<EOL>
1  1 0 0  1 1 1  0 0 0  0 0  0 0 0    - Matte<EOL>
1  0 1 0  0.5 0.5 0.5  0.5 0.5 0.5  10 0.5   0 0 0<EOL>
1  0 0 1  0.7 0.8 0.9  0.3 0.2 0.1  100 1    0 0 0   - Metallic<EOL>
1  1 1 1  0.1 0.1 0.1  0.1 0.1 0.1  200 0.8  0.8 0.8 0.8<EOL>
2  1 1 0  0 0 0  0 0 0  0 0 0   - Matte<EOL>
2  1 0 1  1 1 1  1 1 1  0 0 0   - Mirror<EOL>
<EOL>

3.5. Objects, Textures and Transformations

This next section defines the 3D objects, and optionally, textures and 
transformations. It starts with a line reserved for comments and then by 
object definitions. All objects are defined by a code, a surface index 
(which specifies one of the previously defined surfaces, starting in 1), 
a refraction index and then specific data.

The object with code 1 is a sphere and has a center point and radius. 

Example:

1  3  1.0  4 3 2  0.5- Sphere centered at (4,3,2) radius=0.5<EOL>

The object with code 2 is a parallelipiped aligned with the XYZ axis. 
It requires a center point and 3 dimensions for X, Y and Z directions. 

Example:

2  2  1.0  1 0 0  10 1 3- Box at (1,0,0) with sizes (+-10,+-1,+-3)<EOL>

The object with code 3 is a bicubic patch or a group of bicubic patches. 
It is followed by a translation vector, 3 scale factors for X, Y and Z, 
and by a filename or "-". If there is a filename, then the patch's 
geometry is read from that file, else it is read from the following lines 
in the SFF file ending with an empty line. 

Example:

3  1  1.0  0 0 0  1 1 1  example.pat- Read from file example.pat<EOL>
3  2  1.0  0 0 0  2 1 1  -  Read from the next lines<EOL>
...

A bicubic patch is defined by 12 points, arranged like in the figure:
 
Points P4, P5, P8 and P9 define the patch corners. The other points are 
used in the definition of the frontiers and curvature of the patch. The 
patch normal points outwards the screen (in P4-P8-P9-P5 counterclockwise 
order, similar to the Right Hand rule). A file with patches is composed 
of 2 parts. In the first come the patch's definitions using indices 
into the vertex list, which is separated by a line and comes next 
(and terminates by another empty line). 

Example:

1 2 4 5 6 7 9 10 11 12 14 15- Patch 1<EOL>
2 3 5 6 7 8 10 11 12 13 15 16- Patch 2<EOL>
<EOL>
0 -0.5 -1- Vertex 1<EOL>
0 0 -2- Vertex 2<EOL>
0 -0.5 -3<EOL>
1 0 0<EOL>
1 0 -1<EOL>
1 0.5 -2<EOL>
1 0 -3<EOL>
1 0 -4<EOL>
2 0 0<EOL>
2 0 -1<EOL>
2 0.5 -2<EOL>
2 0 -3<EOL>
2 0 -4<EOL>
0 -0.25 -1<EOL>
0 0 -2<EOL>
0 0 -3<EOL>
<EOL>

Please note that the vertex list starts in index 1. Using these 2 lists, 
it is possible to save a lot of space by avoiding redundant vertex 
specification, and at the same time with only one definition create 
many of these bicubic patch objects. Next figure is a picture of the 
patch data of the above example.
 
Another example is in the next figure. The vase has 72 vertices and 64 
patches. The main disadvantage of the patch primitive is the complexity 
of finding intersections of rays with its surface. As it uses an 
iterative algorithm with lots of floating-point operations, it takes 
much more time to produce a picture, when compared to spheres and boxes.

The code 4 object is a cone or cylinder. It has an apex center point and 
radius, followed by base center point and radius. The apex radius must 
be less (in this case the object is a cone) or equal (cylinder) to the 
base radius. The cone/cylinder are opened objects, ie, they do not have 
any circular surfaces in the apex or base.

4  1  1.0  0 1 0  0  0 0 0  1- Cone<EOL>
4  1  1.0  0 1 0  1  0 0 0  1- Cylinder<EOL>

The code 5 object is a polygon or a group of polygons, similar to 
patches. It is followed by a translation vector, 3 scale factors for X, 
Y and Z, and by a filename or "-". If there is a filename, then 
the polygon's geometry is read from that file, else it is read from 
the following lines in the SFF file, ending with an empty line. 

Example:

5  1  1.0  0 0 0  1 1 1  example.pol- Read from file example.pol<EOL>
5  2  1.0  0 0 0  1 1 1- Read from the next lines<EOL>
...

A polygon is defined by its vertices in counterclockwise order. A file with 
polygons is composed of 2 parts. In the first come the number of polygons 
and the polygon's definitions using indices into the vertex list, which 
is separated by a line and comes next (and terminates by another empty 
line). 

Example:

5  1 2 3 4 5- polygon 1<EOL>
3  1 6 2- polygon 2<EOL>
<EOL>
0 0 -2- vertex 1<EOL>
1 0 0- vertex 2<EOL>
2 0 -1- vertex 3<EOL>
2 0 -3- vertex 4<EOL>
1 0 -4- vertex 5<EOL>
0.5 2 -1- vertex 6<EOL>
<EOL>

The next figure is an image of the previous 2 polygons. Please note again 
that it is possible to save a lot of disk space with the specification 
of the polygon's list and vertices list in separate. The polygon's 
normal is computed using the first 3 vertices in the following way: 
vector from polygon's vertex #2 to polygon's vertex #1 *  vector from 
polygon's vertex #3 to polygon's vertex #1. In the figure, the normal 
of polygon #2 points to the right and out of the screen (its first 3 
vertices are shown, along with the auxiliary vectors). Polygon's #1 
normal points vertically up.
 
The code 6 object is a triangle or a group of triangles, similar to 
polygons, but specifying also each vertex normal vector (these triangles 
are also known as Phong triangles). It is followed by a translation vector, 
3 scale factors for X, Y and Z, and by a filename or "-". If there is 
a filename, then the triangle's geometry is read from that file, else 
it is read from the following lines in the SFF file, ending with 
an empty line. 

Example:

6  1  1.0  0 0 0  1 1 1  example.tri- Read from file example.tri<EOL>
6  2  1.0  0 0 0  1 1 1- Read from the next lines<EOL>
...

A triangle is defined by its vertices (data and normal) in counterclockwise 
order. A file with triangles is composed of the triangle's definitions 
in each line with first vertex data and normal, followed by the second 
vertex data and normal and finally the third vertex data and normal 
(and terminates by another empty line). 

Example:

0 0 0 0 1 0  1 0 0 0 1 0  1 0 -1 0 1 0- Triangle 1<EOL>
0 0 0 1 1 0  0 1 0 1 0 0  0 1 -1 1 0 1- Triangle 2<EOL>
...

In this example, the first triangle has vertices (0,0,0) (1,0,0) 
and (1,0,-1). The normals at these vertices are (0,1,0) (0,1,0) and 
(0,1,0), ie, they all have the same direction. The second triangle has 
vertices (0,0,0) (0,1,0) and (0,1,-1). Its normals are (1,1,0) 
(1,0,0) and (1,0,1).

The code 7 object is an extruded primitive derived from closed segments 
composed by lines and splines. This object is very well suited to trace 
high quality text, although it may be used for many other purposes. It 
is followed by a filename or "-". If there is a filename, then the 
character's geometry is read from that file, else it is read from 
the following lines in the SFF file, ending with an empty line.

Example:

spacing     0.1<EOL>
orientation 0 0 -1  0 1 0  1 0 0<EOL>
encoding    ascii.ppe<EOL>
font        roman.ppf<EOL>
scale       0.4 0.4 0.2<EOL>
at          1 1 2  "RTrace /copyright/ Antonio Costa 1993"<EOL>
font        times.ppf<EOL>
scale       0.5 0.6 0.3<EOL>
at          0 3 0  "Etc"<EOL>
...

The spacing keyword defines the separation between characters. Most 
of the supplied fonts have its characters enclosed in a 1 unit square. 
The orientation keyword defines how the text appears in the 3D space; 
the first vector defines the text direction, the second the up 
direction and the third the extrusion direction. As these are 
independent, it is possible to slant the text or create more complex 
effects. The encoding keyword specifies a file which contains 
translations from character names to character codes, which are 
used to access the character data. The font keyword specifies a 
file which contains the character's data (number of closed 
segments - lines and splines - and other data for each character). 
The scale keyword defines the scaling for the characters, using the 
directions specified with the orientation keyword. Finally, the at 
keyword specifies the starting baseline position and which 
characters to trace. With the supplied font files, it is possible 
to use POSTSCRIPT names for the characters in almost all languages; in 
this case, the character name must be enclosed in / /.

The next figure is an example of high quality text with textures. Please 
note the use of international characters like c and g, because they 
are supported in the font files. The second line is similar to the first 
except in the scale, which is wider. The fourth line uses a different 
font file. As the characters use a very precise mathematical description 
which is used to trace them, they result much better than approximating 
them with small polygons (which do not produce the same quality and 
increase the tracing time). A description of font files is in Annex 1.
 
The next codes are not used to define primitive objects, but rather 
to associate, transform or texture objects. The code 64 defines a 
texture to be applied to an object, usually the previous none. It is 
followed by a type, an object id, a transformation matrix and local 
data. The supported types are:



Type	Name		Parameters

0	Null

1	Checker		surface

2	Blotch		scale   surface   [file(colormap)]

3	Bump		scale

4	Marble		[file(colormap)]

5	FBM		offset   scale   omega   lambda   threshold   octaves

6	FBM Bump	offset   scale   lambda   octaves

7	Wood		color(red)   color(green)   color(blue)

8	Round		scale

9	Bozo		turbulence   [file(colormap)]

10	Ripples		frequency   phase   scale

11	Waves		frequency   phase   scale

12	Spotted		[file(colormap)]

13	Dents		scale

14	Agate		[file(colormap)]

15	Wrinkles	scale

16	Granite		[file(colormap)]

17	Gradient	turbulence   direction(x)   direction(y)   
			direction(z)   [file(colormap)]

18	Imagemap	turbulence   mode   axis(horizontal)   
			axis(vertical)   file(image)

19	Gloss		scale

20	Bump 3D		scale   size


The object id is a number that identifies a previously defined object 
(the first object has number 1; 0 means the previous object). The 
transformation matrix is a group of 16 real numbers that defines a 
4x4 matrix - the first 4 numbers specify the first column of the 
matrix and so on (the last column usually is 0 0 0 1, but may be different!).

The code 65 defines a transformation to be applied to an object, usually 
the previous none. It is followed by an object id and transformation 
matrix data. The order is X1 Y1 Z1 W1 ... X4 Y4 Z4 
W4. The matrix is like:

X1X2X3X4
Y1Y2Y3Y4
Z1Z2Z3Z4
W1W2W3W4
SUM Wi != 0

The code 66 is used to apply CSG (Computer Solid Geometry) operations to 
the previously defined objects. A CSG operation has always two components 
which are combined into an higher level object. This CSG object can be 
the union, the subtraction or the intersection of two objects. Any CSG 
object can have CSG objects as its components. The main restriction 
is that the components must always define a closed volume in 3D space. 
It is followed by type and type-dependent data like in the table:




Type	Explanation			Parameters

0	Start of left components	surface refraction operation

1	Start of right components

2	End

The CSG operations are union (0), subtraction (1) and intersection (2). 
The surface id may be zero; in this case the color of the CSG object 
is the result of the colors of the its components. 

Example:

66 0 1 1 1 - CSG subtraction<EOL>
1    2 1  0 0 0 1- Sphere at (0,0,0) radius=1<EOL>
66 1- Right component of CSG<EOL>
1    3 1  0 1 0 0.6- Sphere at (0,1,0) radius=0.6<EOL>
2    3 1  1 0 0 0.5 0.5 0.5- Box at (1,0,0) sizes=0.5,0.5,0.5<EOL>
66 2- End of CSG<EOL>

The resulting object is in the next figure. Its SFF description is in 
Annex 2.
 
It is very important not to have aligned faces in the CSG objects (or 
aligned edges too), because the CSG operations are very sensitive to 
numerical inaccuracies.

The code 67 is used to group objects so that the whole set of objects is 
treated like a primitive object. This is mainly used with CSG operations 
so that there are no non-closed objects in the CSG object. It is 
followed by a surface id and refraction. If the surface id is non-zero 
then the list object has a color, which supersedes the individual colors. 

Example:

67 0 0 1- Start of list<EOL>
4 1 1  0 1      0 1     0 0 0 1- Cylinder (opened)<EOL>
4 1 1  0 1.001  0 0.001 0 1 0 1- Cone (very flat)<EOL>
4 1 1  0 -0.001 0 0.001 0 0 0 1- Cone (very flat)<EOL>
67 1- End of list<EOL>

This object (closed cylinder) can be safely used inside any CSG operation; 
otherwise, some errors would appear in the ray traced image.  


4. Compatibility

For compatibility with old SFF files, the textures can be specified 
completely after the objects. In this case, there must be an empty line 
after the objects section and then the textures may be defined. The 
code 64 should not appear in the line. 

Example:

objects<EOL>
1 1 1  0 0 0 1- Sphere<EOL>
2 2 1  0 2 0 1 1 1- Box<EOL>
<EOL>
textures<EOL>
3 1  1 0 0 0  0 1 0 0  0 0 1 0  0 0 0 1  0.4- Bump<EOL>
9 2  2 0 0 0  0 1 0 0  0 0 1 0  0 0 0 1  0.5 bozo.map- Bozo+colormap<EOL>
<EOL>


5. Examples

The supported textures allow for an immense variation of colors, patterns, 
etc. Next there are some examples. The SFF descriptions of these spheres 
is in Annex 3.

  Agate.     Blotch.     Bozo.

Also it is possible to modify the primitive objects using transformations 
like in the next examples.

Sphere stretched in one direction and squashed in another direction. The 
description of the two spheres with textures is like:

1 2 1 0 1 0 1- Top sphere<EOL>
64 0 0 1 0 0 500 0 1 0 500 0 0 1 0 0 0 0 1- Translate texture<EOL>
64 1 0 1000 0 0 0 0 1000 0 0 0 0 0.25 0 0 0 0 1 3 - Scale texture<EOL>
1 2 1 0 -1 0 1- Bottom sphere<EOL>
65 0 0.5 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1- Stretch and squash<EOL>
64 0 0 0.5 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1- Texture on normal sphere<EOL>
64 0 0 1 0 0 500 0 1 0 500 0 0 1 0 0 0 0 1<EOL>
64 1 0 1000 0 0 0 0 1000 0 0 0 0 0.25 0 0 0 0 1 3<EOL>

In this example, a new type of object is created by scaling a sphere 
differently in the 3 axis directions. To apply a texture to an object 
independently of its object transformations (invariant texture), all 
you have to do is to list the transformations as texture transformations 
in reverse order. The full description of this scene is in Annex 3.

Box with shear in one direction. The description of the two boxes is like:

2 2 1 0 1 0 1 0.95 1<EOL>
22 2 1 0 -1 0 1 0.95 <EOL>
65 0 1 0 0 0 0 1 0 0 0 -1 1 0 0 0 0 1- Shear matrix<EOL>

The shear is achieved by making the Z axis information dependent of the 
Y coordinate (the -1 creates that effect).


6. Conclusions

This simple format has proved suitable for use in many environments. Even 
so, it is very complicated to use interactively, so a better format (in 
the sense of abstraction and ease of writing) has been developed to 
replace it. It is called SCN (scene format) and makes things much 
more easy to do. The converter from SCN to SFF is called SCN2SFF 
and runs on the same platforms as RTRACE.

To fully understand this format, it is recommended that you read first 
the program's manual so that you have a minimal idea of the options of 
RTRACE and so on.


7. References

Reid Judd, Anto'nio Costa and Greg Ferrar - RTRACE 1.0 for the Macintosh User 
Manual

Pedro Borges, Paulo Almeida, Anto'nio Costa - Extrusion Objects for 3D Text


8. Annexes

8.1. Annex 1 - Font formats PPF and PPE

The PPF files describe objects made from the extrusion of closed lines. 
These closed lines can be straight line segments or cubic Bizier segments. 
The restriction of being closed allows these lines to be specified by 
only 3 points for Bizier and just 1 point for straight segments. The 
last point of one segment is always the starting point of the next.

In the next figure all the control points are showed, and it could be 
used to generate a 'D' letter:
 
The lower left corner is (0,0) and the upper left is (0,23). Its description 
could be something like:

letter 'D'  name
2  number of closed lines
4  number of segments of the 1st line
line0 0  straight line
line0 23
cubic8 23   25 21   23 0  Bezier; starts in (8,23)
line8 0
1  number of segments of the 2nd line
cubic6 15   4 -6   23 17  one Bezier curve only

The actual PPF description is:

/D# name (the slash is mandatory)<EOL>
2# number of closed lines<EOL>
4# number of segments of 1st line<EOL>
l 0 0# start<EOL>
l 0 23# line<EOL>
c 8 23 25 21 23 0# cubic<EOL>
l 8 0# line<EOL>
1# number of segments of 2nd line<EOL>
c 6 15 4 -6 23 17# cubic<EOL>

Any PPF file may contain any number of definitions like the last one 
(the supplied files usually have about 96 character definitions each). 
Any character must have a unique name inside a PPF file (it is a good 
idea to use the names that appear in the Postscript Language Reference 
Manual). To avoid remembering all those names, it is possible to define 
a mapping between character codes and names. 

Characters that do not appear in the mapping file (PPE) may only be 
accessed by its original name. 

Example:

...
64/at# code 64(@) represents 'at'<EOL>
65/A# code 65(A) represents 'A'<EOL>
66/backslash# code 66(B) represents 'backslash'<EOL>
67/copyright# code 67(C) represents 'copyright'<EOL>
68/D# code 68(D) represents 'D'<EOL>
...

A complete example of a tank created with this type of objects follows. 
First, it was necessary to create a specific PPF file (tank.ppf) that 
contains all the tank extruded parts:

# tank<EOL>
/wheels<EOL>
1<EOL>
6<EOL>
l 4 0<EOL>
c 16 0 18 0 20 2<EOL>
c 20 3 20 4 18 4<EOL>
l 16 4<EOL>
c 4 4 2 4 0 3<EOL>
c 0 2 0 1 2 0<EOL>
/body<EOL>
1<EOL>
6<EOL>
l 5 1<EOL>
c 15 1 18 1 18 2<EOL>
c 18 3 18 4 13 5<EOL>
l 12 5<EOL>
c 8 5 5 5 2 4<EOL>
c 2 3 2 2 4 1<EOL>
/tower<EOL>
1<EOL>
4<EOL>
c 10 -10 14 -10 20 -4<EOL>
c 20 0 20 4 14 10<EOL>
c 10 10 6 10 0 10<EOL>
c 0 0 0 -10 6 -10<EOL>
/cannon<EOL>
1<EOL>
2<EOL>
c 1 0 1 1 -1 1<EOL>
c -1 0 -1 -1 1 -1<EOL>

The SFF file for this example is:

view<EOL>
28 -9 9<EOL>
12.5 5 2<EOL>
0 0 1<EOL>
30 30<EOL>
colors<EOL>
0.1 0.4 0.7<EOL>
0.6 0.6 0.6<EOL>
lights<EOL>
1 20 20 40 1 1 1<EOL>
1 30 -10 10 2 2 2<EOL>
1 -30 -60 10 4 4 4<EOL>
2 -300 400 10 0 0 -1 -1 -1 -1 89.8<EOL>
<EOL>
surfaces<EOL>
1 0.5 0.7 0.5 0.3 0.3 0.3 0.7 0.7 0.7 70 0.7 0 0 0<EOL>
1 0.6 0.4 0.3 1 1 1 0 0 0 0 0 0 0 0<EOL>
<EOL>
objects<EOL>
7 1 1 tank.t3d<EOL>
2 2 1 0 0 0 1000 1000 0.01<EOL>
<EOL>
end<EOL>

Finally, the tank is described in tank.t3d like:

spacing0.1<EOL>
orientation1 0 0 0 0 1 0 1 0<EOL>
fonttank.ppf<EOL>
encodingascii.ppe<EOL>
scale1 1 2<EOL>
at0 0 0 "/wheels/"<EOL>
at0 8 0 "/wheels/"<EOL>
scale1 1 6<EOL>
at0 2 0 "/body/"<EOL>
scale0.4 0.28 2<EOL>
orientation1 0 0 0 1 0 0 0 1<EOL>
at6 5 5 "/tower/"<EOL>
scale0.5 0.5 8<EOL>
orientation0 1 0 0 0 1 1 0 0<EOL>
at10 5 6 "/cannon/"<EOL>

The resulting picture is in the next figure:
 

8.2. Annex 2 - CSG Example

The full description of the CSG scene is:

view<EOL>
3 1 1<EOL>
0 0 0<EOL>
0 1 0<EOL>
20 20<EOL>
colors<EOL>
1 1 1<EOL>
0.2 0.2 0.2<EOL>
lights<EOL>
1 3 2 2 1 1 1<EOL>
<EOL>
surfaces<EOL>
1 0 1 0 1 1 1 0 0 0 0 0 0 0 0<EOL>
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0<EOL>
1 1 1 0 1 1 1 0 0 0 0 0 0 0 0<EOL>
<EOL>
objects<EOL>
66 0 1 1 1 - CSG subtraction<EOL>
1    2 1  0 0 0 1- sphere at (0,0,0) radius=1<EOL>
66 1- right component of CSG<EOL>
1    3 1  0 1 0 0.6- sphere at (0,1,0) radius=0.3<EOL>
2    3 1  1 0 0 0.5 0.5 0.5- box at (1,0,0) sizes=0.5,0.1,0.1<EOL>
66 2- end of CSG<EOL>
<EOL>
end<EOL>


8.3. Annex 3 - Textured Spheres Examples

Agate example:

view<EOL>
1.6 1.6 1.6<EOL>
0 0 0<EOL>
0 1 0<EOL>
22.5 22.5<EOL>
colors<EOL>
0.2 0.5 0.7<EOL>
0.1 0.1 0.1<EOL>
lights<EOL>
1 57735.03 57735.03 -57735.03 -1 -1 -1<EOL>
<EOL>
surfaces<EOL>
1 0.9 0.9 0.9 0.9 0.9 0.9 0.1 0.1 0.1 4 0 0 0 0<EOL>
<EOL>
objects<EOL>
1 1 1 0 0 0 1<EOL>
64 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 earthtones.map<EOL>
<EOL>
end<EOL>

Blotch example:

view<EOL>
1.6 1.6 1.6<EOL>
0 0 0<EOL>
0 1 0<EOL>
22.5 22.5<EOL>
colors<EOL>
0.2 0.5 0.7<EOL>
0.1 0.1 0.1<EOL>
lights<EOL>
1 57735.03 57735.03 -57735.03 -1 -1 -1<EOL>
<EOL>
surfaces<EOL>
1 1 0 0 0.999 0.999 0.999 0 0 0 0 0 0 0 0<EOL>
1 1 1 0 0.999 0.999 0.999 0 0 0 0 0 0 0 0<EOL>
<EOL>
objects<EOL>
1 1 1 0 0 0 1<EOL>
64 2 0 0.1 0 0 0 0 0.1 0 0 0 0 0.1 0 0 0 0 1 0.4 2 -<EOL>
<EOL>
end<EOL>

Bozo example:

view<EOL>
1.6 1.6 1.6<EOL>
0 0 0<EOL>
0 1 0<EOL>
22.5 22.5<EOL>
colors<EOL>
0.2 0.5 0.7<EOL>
0.1 0.1 0.1<EOL>
lights<EOL>
1 57735.03 57735.03 -57735.03 -1 -1 -1<EOL>
<EOL>
surfaces<EOL>
1 0.9 0.9 0.9 0.9 0.9 0.9 0.1 0.1 0.1 4 0 0 0 0<EOL>
<EOL>
objects<EOL>
1 1 1 0 0 0 1<EOL>
64 9 0 2 0 0 0 0 2 0 0 0 0 2 0 0 0 0 1 1 earthtones.map<EOL>
<EOL>
end<EOL>

The color map file used (earthones.map) is:

40 128 200<EOL>
40 128 200<EOL>
41 129 201<EOL>
... + 250 colors ...
254 255 253<EOL>
254 255 253<EOL>
254 255 253<EOL>
<EOL>
Earth Tones<EOL>


8.4. Annex 4 - Striped Spheres Example

This is the full description for the two striped spheres of chapter 5:

view<EOL>
7 3 2<EOL>
0 0 0<EOL>
0 1 0<EOL>
22.5 22.5<EOL>
colors<EOL>
1 1 1<EOL>
0.1 0.1 0.1<EOL>
lights<EOL>
1 6 2 2 1 1 1<EOL>
<EOL>
surfaces<EOL>
1 0.7 0.7 0.7 0.999 0.999 0.999 0 0 0 0 0 0 0 0<EOL>
1 0 1 0 0.999 0.999 0.999 0 0 0 0 0 0 0 0<EOL>
1 1 1 1 0.999 0.999 0.999 0 0 0 0 0 0 0 0<EOL>
<EOL>
objects<EOL>
4 1 1 1.5 1 0 0.05 0 1 0 0.05<EOL>
4 1 1 1.5 1 0 0.1 1.8 1 0 1e-07<EOL>
4 1 1 0 1 1.5 0.05 0 1 0 0.05<EOL>
4 1 1 0 1 1.5 0.1 0 1 1.8 1e-07<EOL>
4 1 1 1.5 -1 0 0.05 0 -1 0 0.05<EOL>
4 1 1 1.5 -1 0 0.1 1.8 -1 0 1e-07<EOL>
4 1 1 0 -1 2.5 0.05 0 -1 0 0.05<EOL>
4 1 1 0 -1 2.5 0.1 0 -1 2.8 1e-07<EOL>
1 2 1 0 1 0 1<EOL>
64 0 0 1 0 0 500 0 1 0 500 0 0 1 0 0 0 0 1<EOL>
64 1 0 1000 0 0 0 0 1000 0 0 0 0 0.25 0 0 0 0 1 3<EOL>
1 2 1 0 -1 0 1<EOL>
65 0 0.5 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1<EOL>
64 0 0 0.5 0 0 0 0 1 0 0 0 0 2 0 0 0 0 1<EOL>
64 0 0 1 0 0 500 0 1 0 500 0 0 1 0 0 0 0 1<EOL>
64 1 0 1000 0 0 0 0 1000 0 0 0 0 0.25 0 0 0 0 1 3<EOL>
<EOL>
end<EOL>

To ray trace these examples and produce the pictures (fast and with low 
quality), assuming the SFF file was called spheres.sff, the ray tracer 
should be executed like:

rtrace t1 O1 m0 spheres.sff spheres.ppm

For an high quality rendering, use instead:

rtrace t1 O1 p2 A0.075 spheres.sff spheres.ppm

 * represents cross-product of two vectors.



----- end of SFF -----