man > pamtris(1)

Pamtris User Manual(1)                 General Commands Manual                Pamtris User Manual(1)

NAME
       pamtris  -  triangle rasterizer featuring perspective-correct interpolation of generic vertex
       attributes and depth buffering


SYNOPSIS
       pamtris

       -width=width

       -height=height

       { -num_attribs=attributes_per_vertex [ -tupletype=tupletype ] | -rgb | -grayscale }

       [ -maxval=maxval ]

       All options can be abbreviated to their shortest unique prefix.  You may use two hyphens  in‐
       stead  of  one  to designate an option.  You may use either white space or an equals sign be‐
       tween an option name and its value.


DESCRIPTION
       This program is part of Netpbm(1).

       pamtris can be used to draw a great variety of 2D and 3D graphics  by  composing  arbitrarily
       complex  pictures  out  of separate triangles, triangle strips and triangle fans. The program
       reads instructions written in a simple command script notation from Standard Input  and  out‐
       puts its results as a (potentially multi-image) PAM stream on Standard Output.

       For example, the following input


             mode fan
             attribs 0 128 0
             vertex 0 0 1
             attribs 0 0 128
             vertex 200 0 1
             attribs 50 20 103
             vertex 190 61 1
             attribs 100 40 78
             vertex 161 117 1
             attribs 150 60 53
             vertex 117 161 1
             attribs 200 80 28
             vertex 61 190 1
             attribs 250 100 3
             vertex 0 200 1
             print




       produces this:

       Example pamtris output for FAN mode


       The input file gives triangle data by setting the appropriate drawing mode, if necessary, and
       then  providing  a  list  of vertices. Each vertex is also associated with a list of up to 20
       "attributes," which are integer values between 0 and a given maxval. In the most  common  us‐
       age,  you  use pamtris to draw a visual image and a vertex has three attributes, which are an
       RGB specification of a color.  Such attribute lists may be provided on a per-vertex basis.

       Prior to effectively writing a PAM image to Standard Output, pamtris first rasterizes it onto
       an internal frame buffer, which consists of an "image buffer" and a "depth buffer." The image
       buffer consists of a sequence of height rows containing a sequence of width tuples. There  is
       one  sample for each vertex attribute in every tuple plus an opacity (alpha) sample. Each tu‐
       ple in the image buffer is also associated with an integer depth in the depth  buffer,  which
       determines  whether  subsequent  drawing operations affect that particular tuple or not. This
       provides a way of depth-sorting graphical objects which is adequate for many purposes  in  2D
       and  3D  computer  graphics.  One prominent shortcoming of such an approach to depth-sorting,
       however, is that it does not automatically work with objects which  are  intended  to  appear
       "translucent," therefore requiring more elaborate strategies to incorporate said objects into
       pictures generated using this technique.

       The  opacity  sample is the last sample of the tuple.  pamtris manipulates opacity internally
       and for any tuple it is always either 0 or the maxval.  The program does not provide the user
       direct control over the alpha image plane.

       pamtris rasterizes triangles by approximating their visible area as a collection of tuples at
       particular positions in the frame buffer, and to each sample of every such tuple it assigns a
       value which is a perspective-correct interpolation between the values  of  the  corresponding
       attribute  for  each  vertex  of  the triangle. Whenever a tuple within the area of the frame
       buffer is produced, it is written to the corresponding position in the frame  buffer  if  and
       only  if it passes a depth test.  This test works as follows: the depth value of every incom‐
       ing tuple (which is itself an interpolation between the Z-coordinates of the vertices of  the
       corresponding  triangle)  is  compared against the value in the corresponding position in the
       depth buffer. If the depth value of the incoming tuple equals or is smaller  than  the  depth
       value already present in said position in the depth buffer, the following happens.



       •      Every sample i, where 0 &#8804; i < num_attribs, of the tuple in the corresponding po‐
              sition  in  the image buffer is set to equal the value of the respective sample of the
              incoming tuple; and the alpha sample (the last one) is updated to the maxval;


       •      The depth value in the corresponding position in the depth  buffer  is  updated  to  a
              depth value directly proportional to that of the incoming tuple.


       Otherwise, that particular tuple effects no change at all in the frame buffer.

       The frame buffer is initially set so that all samples in every tuple of the image buffer con‐
       tain  the  value  0,  and all entries in the depth buffer contain the maximum permitted depth
       value.

       The attributes' values, and therefore the samples in the output PAM images, have no fixed in‐
       terpretation ascribed to them (except for the last image plane, which  is  deliberately  sup‐
       posed  to represent tuple opacity information); one may ascribe any suitable meaning to them,
       such as that of colors, texture coordinates, surface normals, light interaction  characteris‐
       tics, texture influence coefficients for multi-texturing, etc.



EXAMPLES
   Fan Mode
       The  following  command  generates  the image from the fan mode example at the top of the ]8;;#description\DE‐
       SCRIPTION]8;;\  section. If the file fan.tris contains that code, you could process it with:


           $ pamtris -height=200 -width=200 -rgb <fan.tris >fan.pam




   Strip Mode
       The following is an example of strip mode:


             mode strip
             attribs 255 0 0   # red
             vertex   0 200 1
             vertex  50   0 1
             attribs 0 0 0     # black
             vertex 100 200 1
             attribs 0 205 205 # cyan
             vertex 150 0 1
             attribs 0 0 255   # blue
             vertex 200 200 1
             vertex 250   0 1
             print



       Save the above code in a file named strip.tris (for instance) and process it with:


           $ pamtris -height=200 -width=200 -rgb <strip.tris >strip.pam



       to yield:

       Example pamtris output for STRIP mode


   Triangle Mode
       The following is an example of triangle mode:


             # yellow square
             mode strip
             attrib 155 155 0
             vertex 50  50 100
             vertex 50 200 100
             vertex 200 50 100
             vertex 200 200 100

             # blue triangle
             mode triangles
             attrib 0 205 205
             vertex 20 125 70
             attrib 0 0 140
             vertex 230  70 120 # Change "120" and see what happens
             vertex 230 180 120 #
             print



       Save the above code in a file named pierce.tris (for instance) and process it with:


           $ pamtris -height=200 -width=200 -rgb <pierce.tris >pierce.pam



       to yield:

       Example pamtris output for TRIANGLES mode



   Meta-programming
       The pamtris command language is much too rudimentary to be  used  directly  for  any  serious
       drawing;  you  will probably want to use a general purpose programming language to generate a
       temporary pamtris command file.

       For example, the draw_polygon procedure in the C program below outputs  pamtris  instructions
       to draw a regular polygon. It does this by generating a number of vertex instructions tracing
       around the perimeter of the corresponding circumscribed circle. (Note: The PAM image produced
       by  piping  the  output of the below program into pamtris was subsequently downscaled through
       pamscale -linear -xscale 0.25 -yscale 0.25 to achieve an ]8;;#antialias\anti-aliased]8;;\  effect.)

       Regular Polygons

       /* ----------------------- *
        * width       = 512       *
        * height      = 512       *
        * num_attribs = 3         *
        * tupletype   = RGB_ALPHA *
        * ----------------------- */

       #include <math.h>
       #include <stdio.h>
       #include <stdlib.h>

       #define PI 3.14159265358979323844

       void draw_polygon
       (int const center_x, int const center_y, int const radius, int const sides)
       {
           printf("mode fan\n"
                  "vertex %d %d 0\n", center_x, center_y);

           for(int i = 0; i <= sides; i++)
           {
               int const x = round(center_x + radius * cos(i*2.0*PI / sides));
               int const y = round(center_y - radius * sin(i*2.0*PI / sides));

               printf("vertex %d %d 0\n", x, y);
           }
       }

       int main(void)
       {
           puts("attribs 0 185 80");       /* color: green   */
           draw_polygon(300, 210, 150, 5); /* draws pentagon */

           puts("attribs 255 15 240");     /* color: magenta */
           draw_polygon(150, 320, 100, 7); /* draws heptagon */

           puts("!");
       }



OPTIONS
       In addition to the options common to all programs based on libnetpbm  (most  notably  -quiet,
       see ]8;;index.html#commonoptions\ Common Options]8;;\ ), pamtris recognizes the following command line options:

       <dl compact="compact">

       -width=width
              Sets  the  width of the internal frame buffer and, by extension, of the output PAM im‐
              ages, given in number of columns. This must be an integer  in  the  closed  range  [1,
              8192].

              This option is mandatory.


       -height=height
              This  is  the height of the internal frame buffer and, by extension, of the output PAM
              images, given in number of rows. This must be an  integer  in  the  closed  range  [1,
              8192].

              This option is mandatory.


       -num_attribs=attributes_per_vertex
              This is the number of attributes per vertex. The depth of the output PAM images equals
              this  value plus one (to accommodate the alpha plane). The argument must be an integer
              in the closed range [1, 20].

              The input instruction stream may override this with a reset command.

              You must specify exactly one of -num_attribs, -rgb, and -grayscale.



       -tupletype=tupletype
              This is the tuple type for the output PAM images. The argument is a string  which  may
              be no longer than 255 characters.

              The input instruction stream may override this with a reset command.

              The default is a null string.

              This option cannot be specified together with  -rgb or -grayscale.




       -rgb   This  is  a convenience option which simply serves as an alias for -num_attribs=3 -tu‐
              pletype=RGB_ALPHA. In other words, this option is a quick way to specify that you  are
              going  to  use pamtris to draw RGB(_ALPHA) color images directly, and the three vertex
              attributes are the red, green and blue levels of the color associated with the vertex,
              in that order.

              The input instruction stream may override this with a reset command.

              You must specify exactly one of -num_attribs, -rgb, and -grayscale.

              This option was new in Netpbm 10.85 (December 2018).


       -grayscale
              Another convenience option, similar to -rgb; except this one is an alias for  -num_at‐
              tribs=1 -tupletype=GRAYSCALE_ALPHA. The one vertex attribute is the gray level associ‐
              ated with the vertex.

              The input instruction stream may override this with a reset command.

              You must specify exactly one of -num_attribs, -rgb, and -grayscale.

              This option was new in Netpbm 10.85 (December 2018).


       -maxval=maxval
              Sets  the  maxval  of the output PAM images, which is also the maximum permitted value
              for each vertex attribute. This must be an integer in the closed range [1, 65535].

              The default value is 255.

              The input instruction stream may override this with a reset command.




INSTRUCTION CODE
       The input for pamtris consists of a stream of text lines read from Standard Input.

       Empty lines or lines that contain only white space characters are called blank lines and  are
       ignored.

       When  a  # occurs anywhere in a line, pamtris ignores it along with every character after it.
       In other words, everything from the # until the end of the line receives the  same  treatment
       as white space.

       Lines  which  are  not  blank must contain a sequence of strings, called tokens, separated by
       white space.  The first such token must be one of the commands recognized by pamtris, and all
       further tokens are interpreted as the arguments for that command, if it takes  any.  When  an
       insufficient  number  of  arguments is provided for a command, the line is considered invalid
       and is given the same treatment as a blank line. The same happens when an out of range  argu‐
       ment  or  one  of a kind different of what is expected is given (for example, when you give a
       string of letters where a numerical value is expected), or when an unrecognized command/argu‐
       ment is found. When a number of arguments greater than that required for a particular command
       is provided, only the portion of the line up to the last required argument is considered  and
       any further tokens are ignored.

       pamtris is case-insensitive. That is, mode, MODE, mODe, etc. are all treated the same way.

       The commands recognized by pamtris are:


       mode

       attribs

       vertex

       print

       clear

       reset

       quit


       You may use a minimum unique abbreviation of a command name.  You may use an exclamation mark
       (!) in place of the print command name and an asterisk (*) in place of clear.

       The functions of the commands are as follows.



       mode { triangles | strip | fan }

              This  makes  pamtris  enter a new drawing mode. The argument is a word which specifies
              the mode to change to. Instead of a full argument name, it is permissible to provide a
              minimum unique abbreviation, which has the same effect. The drawing mode  will  remain
              the same until the next mode command is given.

              This command also resets the current vertex list, which is (re)initialized to an empty
              state  after  the  command  is executed. One may add new vertices to this list through
              successive invocations of the vertex command (see below). You do  not  have  to  worry
              about  providing  "too  many"  vertices, since the vertex list is virtualized: pamtris
              maintains only the state pertaining to three vertices at any  one  time.  The  current
              vertex list is initially empty.

              It is permissible to give pamtris a mode command which instructs it to enter a drawing
              mode it is currently already in. One might use this approach to reset the current ver‐
              tex list without changing the current drawing mode.

              Regardless  of the current drawing mode, the program immediately rasterizes a new tri‐
              angle into the frame buffer as soon as you  provide  the  necessary  vertices  for  it
              through  the  current vertex list. (If you reset the vertex list before giving all the
              vertices necessary to draw a new triangle, the program effectively discards  from  the
              list  any  vertices  that might have been pushed into the vertex list up to that point
              without using them to draw any new triangles.)

              In the following descriptions of each drawing mode, triangles' and  vertices'  indices
              (ordinal numbers) are 0-based.

              The  triangles argument instructs pamtris to enter the "TRIANGLES" drawing mode. While
              in this mode, a series of separate triangles  is  constructed.  Every  three  vertices
              pushed into the current vertex list specify a new triangle.  Formally, this means that
              every Nth triangle is specified by vertices 3*N, 3*N + 1, and 3*N + 2. This is the de‐
              fault  initial  mode and is therefore not required to be set explicitly before drawing
              any triangles.

              The strip argument instructs pamtris to enter the "STRIP" drawing mode.  While in this
              mode, pamtris constructs a "triangle strip." That is, the first three vertices  pushed
              into  the  current vertex list specify the first triangle, and every new vertex pushed
              after that specifies, together with the previous two,  the  next  triangle.  Formally,
              this means that every Nth triangle is specified by vertices N, N + 1, and N + 2.

              The  fan  argument  instructs  pamtris to enter the "FAN" drawing mode.  While in this
              mode, a so-called "triangle fan" is constructed.  That is, the  first  three  vertices
              pushed  into  the current vertex list specify the first triangle, and every new vertex
              pushed after that specifies, together with the previous vertex and the first one,  the
              next  triangle.  Formally, this means that every Nth triangle is specified by vertices
              0, N + 1, and N + 2.



       attribs a<sub>0 a<sub>1
              a<sub>2 ... a<sub>num_attribs - 1

              This updates the current attribute values list. This command takes as arguments a  se‐
              quence  of num_attribs integers which represent the values of the attributes to be as‐
              sociated with the next vertex. This sequence of values is the just mentioned  "current
              attribute values list."

              Each ith argument, where 0 &#8804; i < num_attribs, indicates the value to be assigned
              to the ith attribute of the current attribute values list. All arguments must be inte‐
              ger  values  in  the closed range [0, maxval].  If a number of arguments less than the
              current value of num_attribs is given, the command is considered invalid and is there‐
              fore ignored.

              The current attribute values list remains unchanged until the next  valid  attribs  or
              reset  command  is  given. The attribs command allows one to change the values of each
              attribute individually, while the reset command is not specifically designed for  that
              function,  but  it  has the side effect of setting all values in the current attribute
              values list to the maxval (see below).

              All values in the current attribute values list are initially set to the maxval.

              <dt id="cmd_vertex">vertex x y z [w]

              Adds a new vertex to the current vertex list (see the mode command  above),  assigning
              the  values of the arguments to its respective coordinates, and the values in the cur‐
              rent attribute values list (see the attribs command above) to the  respective  entries
              in the attribute list associated with the vertex.

              x, y and z must be integer values in the closed range [-32767, 32767].  x and y repre‐
              sent,  respectively, the column and row of the tuple which corresponds to the location
              of the vertex. Such values may correspond to tuples outside the limits  of  the  frame
              buffer.  The  origin  of  the  coordinate system is at the top-left tuple of the frame
              buffer. The X-axis goes from left to right, and the Y-axis from top to bottom. A nega‐
              tive value for x indicates a column that many tuples to the left of the leftmost  col‐
              umn  of  the frame buffer.  Likewise, a negative value for y indicates a row that many
              tuples above the uppermost row of the frame buffer.  Observe  that  those  coordinates
              correspond  directly  to a particular point in the coordinate system delineated above,
              regardless of whether you are trying to draw an image which is supposed to look as  if
              viewed  "in  perspective"  or not; pamtris does not "warp" the coordinates you give in
              any way.  Therefore, if you want to draw images in perspective, you must compute  val‐
              ues  for  x and y already projected into pamtris' coordinate system yourself, using an
              external perspective projection method, prior to giving them to the program.

              The z parameter represents the  Z-coordinate of the vertex, which is used  to  compute
              depth values for tuples within the areas of rasterized triangles. Intuitively, smaller
              values  for z mean "closer to the viewer," and larger ones mean "farther away from the
              viewer" (but remember: as said above, the x and y coordinates are not  warped  in  any
              way, which implies that they are not affected by z; neither by the next parameter, for
              that matter).

              Optionally,  you  may provide a w parameter which represents a "perspective correction
              factor" used to properly interpolate vertex attributes across the area of  the  corre‐
              sponding  triangle. This must be an integer value in the closed range [1, 1048575]. If
              you don't provide a value for it, the default value of 1 is used (hence, if  you  want
              to  nullify  the effects of perspective correction on a triangle so the output samples
              are computed as if just linearly interpolated, simply do not provide a value for w for
              any vertex of the triangle). If, however, you intend to draw 3D geometry  in  perspec‐
              tive,  you  must provide an appropriate value for this parameter, otherwise the output
              images might look very wrong.  w was new in Netpbm 10.85 (December 2018).

              Consider the ]8;;https://en.wikipedia.org/wiki/Viewing_frustum\ typical model]8;;\  of the so-called "viewing frustum" used to  project  ver‐
              tices in 3D "world space" onto a planar "image space." If we adopt the convention that
              a  "z-plane"  means any plane parallel to the view-plane (a.k.a. picture plane, a.k.a.
              near plane), the value of w for a vertex should then  be  the  (smallest/euclidean/or‐
              thogonal)  distance  in  pixels between the projection reference point (PRP, or "eye")
              and the z-plane containing the vertex. One way to compute this value amounts to simply
              taking the dot product between the 3D vector r and the 3D unit vector n,  where  r  is
              the  vector which goes from the projection reference point (PRP, or "eye") to the ver‐
              tex, and n is a view-plane normal (VPN) of unit length which points away from the PRP.
              In other words, this is equal to the length of the orthogonal projection of r  on  the
              line "determined" by n.

              (Note: For any two 3D vectors a and b, with respective real scalar components a<sub>x,
              a<sub>y,  a<sub>z  and  b<sub>x,  b<sub>y, b<sub>z, the dot product between a and b is
              simply a<sub>x*b<sub>x + a<sub>y*b<sub>y + a<sub>z*b<sub>z.)



       print

              This writes a PAM image to Standard Output whose raster is a copy of the current  con‐
              tents  of  the image buffer. The values of the WIDTH and HEIGHT fields are the same as
              the width and height, respectively, of the frame buffer, which were given on the  com‐
              mand  line during program invocation. The MAXVAL field is equal to the current maxval;
              the DEPTH field is equal to the current value of num_attribs +  1;  and  the  TUPLTYPE
              field is equal to the current tupletype.

              This  command  has  no effect upon the current drawing state. E. g. it does not modify
              the current drawing mode, the current vertex list, etc.

              One may issue an arbitrary number of print commands at different positions in the  in‐
              put instruction sequence to produce a multi-image PAM stream.


       clear [ image | depth ]

              Clears  the  frame buffer. That is, all samples in the image buffer are once again set
              to 0, and all entries in the depth buffer are once again set to the maximum  permitted
              depth value.

              Optionally,  one  may provide an argument to only clear either the image buffer or the
              depth buffer individually, while leaving the other intact. With  the  image  argument,
              only  the  image  buffer is cleared; with the depth argument, only the depth buffer is
              cleared. Instead of full argument names, one may provide a  minimum  unique  abbrevia‐
              tion,  which  has the same effect. The single character z is also accepted as an alias
              for depth.

              Like the print command, this command has no effect upon the current drawing state  ei‐
              ther.



       reset maxval num_attribs [tupletype]

              This updates the current maxval and number of attributes per vertex (num_attribs), re‐
              setting  the  <u>image</u>  buffer  with  a new maxval and number of samples per tuple
              while at it. The parameter maxval must be an integer in the closed range  [1,  65535],
              and num_attribs must be an integer in the closed range [1, 20].

              Optionally,  after the second argument, one may provide a string to be assigned to the
              current tupletype. The string goes from the first character after the second  argument
              which is not white space and continues until (and including) the last character before
              the  end of the line which is not white space.  If a new tupletype is not provided, or
              the provided string is longer than 255 characters, the empty string is assigned to the
              current tupletype.

              The side effects of running this command are



       •

              The new image buffer is completely cleared once the command is executed.


       •

              All values in the current attribute values list are set to the new maxval.


       •

              The current vertex list is reset.



              However, it does not touch the depth buffer: it is left the same way as it  was  found
              before  the  command.  Also the drawing mode remains the same (e. g. if pamtris was in
              FAN mode, it will continue in that same mode, etc.).

              If this command is given with an invalid value for maxval or num_attribs,  it  is  ig‐
              nored  and  therefore none of the above side effects apply, nor do the current maxval,
              num_attribs or tupletype change at all.

              It is permissible to give a value for maxval and num_attribs equal to the current max‐
              val and num_attribs, respectively, although the above side effects  will  still  apply
              even in such cases.

              Since  this command deals with memory allocation, it may fail to execute successfully.
              If that happens, no lines of input will be read anymore and pamtris will be terminated
              as if the quit command was given.

       quit

              This terminates pamtris. It will not read any more lines of input after this command.





TIPS
   Texturing
       It is possible to apply so-called "textures" to images produced with pamtris by using a  pair
       of vertex attributes as texture coordinates, then using pamchannel(1) to select the appropri‐
       ate  channels in the output image(s), and finally processing the result through pamlookup(1),
       providing the desired texture file as a "lookup table."  If you are drawing pictures in  per‐
       spective,  make sure to provide adequate values for the w parameter to your vertex commands (
       ]8;;#cmd_vertex\see above]8;;\ ) so that the resulting samples in the images produced by pamtris are  perspective-
       correct. You might want to consider using pnmtile(1) to make textures which are inteded to be
       "repeated" along triangle meshes.

        The  animated  GIF below is an example of what can be achieved using the technique described
       above (Earth texture from ]8;;https://visibleearth.nasa.gov/view.php?id=73580\nasa.gov]8;;\ ).

       Rotating Earth


   Anti-aliased edges
       pamtris performs no anti-aliasing on triangle edges by itself.  However, it  is  possible  to
       obtain  anti-aliased images through a "super-sampling" approach: draw your image(s) at a size
       larger than the desired final size, and then, when all postprocessing is done, downscale  the
       final  image(s)  to the desired size. Drawing images with twice the desired width and height,
       then downscaling them to the intended size while disregarding gamma (i.e. what pamscale -lin‐
       ear does) often produces good enough results; but the larger the ratio  "size of original im‐
       age" / "size of downscaled  image" , the better the quality of the anti-aliasing effect.


SEE ALSO
       pampick(1)   pamchannel(1)   pamstack(1)  pamlookup(1)  pamarith(1)  pamscale(1)  pamdepth(1)
       pamexec(1) pam(1)


HISTORY
       pamtris was new in Netpbm 10.84 (September 2018).

DOCUMENT SOURCE
       This manual page was generated by the Netpbm tool 'makeman' from  HTML  source.   The  master
       documentation is at

              http://netpbm.sourceforge.net/doc/pamtris.html

netpbm documentation                        15 April 2021                     Pamtris User Manual(1)
pamtris(1)
NAME SYNOPSIS
pamtris -width=width -height=height
DESCRIPTION
Example pamtris output for FAN mode
EXAMPLES
Fan Mode Strip Mode Example pamtris output for STRIP mode Triangle Mode Example pamtris output for TRIANGLES mode Meta-programming Regular Polygons
OPTIONS
-width=width -height=height -num_attribs=attributes_per_vertex -tupletype=tupletype -rgb This is a convenience option which simply serves as an alias for -num_attribs=3 -tu‐ -grayscale -maxval=maxval
INSTRUCTION CODE
mode attribs vertex print clear reset quit print quit
TIPS
Texturing Rotating Earth Anti-aliased edges
SEE ALSO HISTORY DOCUMENT SOURCE

Generated by phpman v4.10.0-7-g98e9fd5 · Markdown · JSON · MCP Author: Che Dong Under GNU General Public License
2026-09-04 10:41 @216.73.217.16
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
Valid XHTML 1.0 Transitional!Valid CSS!

^_top_^