Home / Alt manpages / pamtris(1)

  • pamtris(1)
  • User command
  • linux

Rasterise Depth-Tested Triangles with pamtris

pamtris reads a plain-text triangle script and rasterises it into a PAM image, complete with RGB attributes and proper depth-tested overlap. The same workflow scales up to triangle strips, fans and non-colour attributes. Allow about fifteen minutes if Netpbm is already installed; nothing here needs elevated privileges.

1. Check the installed command

This guide uses the pamtris shipped by Netpbm 11.5.2 on the reference system. Check the binary and package on your own machine before relying on version-specific behaviour:

$ command -v pamtris
/usr/bin/pamtris
$ pamtris --version
pamtris: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1

Your package version and the wording of diagnostic output may differ. The command reads its instruction script from standard input and writes one or more PAM images to standard output.

2. Choose the image contract

  • Always needed: -width, -height, and exactly one attribute declaration, -rgb, -grayscale, or -num_attribs. Width and height must each fall between 1 and 8192.
  • -rgb is the convenient choice for an ordinary image: three attributes, the RGB_ALPHA tuple type, and a default maxval of 255.
  • The fourth PAM plane is opacity, managed internally by pamtris. It is not an extra value on an attribs line.
  • Custom data? Use -num_attribs=2 or another value from 1 to 20, and name the tuple with -tupletype if useful. Do not combine -tupletype with -rgb or -grayscale.

3. Write one triangle script

Create a text file in your working directory. Each attribs line supplies the values attached to the next vertices. Coordinates use a top-left origin: x increases to the right, y increases downwards, and the z value controls depth, with smaller values nearer the viewer.

$ cat > triangle.tris <<'EOF'
attribs 255 0 0
vertex 1 1 1
attribs 0 255 0
vertex 6 1 1
attribs 0 0 255
vertex 1 6 1
print
EOF

This uses the initial triangles mode, where every three vertices make a separate triangle. A mode command is still useful when changing shape: mode strip reuses the previous two vertices for each new triangle, while mode fan keeps the first vertex and pairs it with each successive edge. Changing mode also clears the pending vertex list, so issue it before adding the next shape.

Comments start with # and run to the end of the line. Commands are case-insensitive, but full command names make scripts easier to review later. Invalid or incomplete lines are simply ignored, which can otherwise make a typo look like a missing triangle.

4. Rasterise to a new PAM file

Run the ordinary, unprivileged conversion. Redirection creates or truncates the destination, so choose a new filename while testing:

$ pamtris -width=8 -height=8 -rgb < triangle.tris > triangle.pam
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sed -n '1,7p' triangle.pam
P7
WIDTH 8
HEIGHT 8
DEPTH 4
MAXVAL 255
TUPLTYPE RGB_ALPHA
ENDHDR

Checkpoint

The header confirms the requested dimensions, four planes (three attributes plus alpha), and the RGB tuple type. The raster data after ENDHDR is binary, so do not inspect the whole file with a terminal or text editor.

5. Verify the image without guessing

Use an installed Netpbm inspection tool if available. pamfile reads the PAM header and is safe for this output:

$ pamfile triangle.pam
triangle.pam: PAM, 8 by 8 pixels, 4 channels, maxval 255

The exact sentence can vary between Netpbm builds. Confirm the useful facts: 8 by 8 pixels, four channels and maxval 255. No pamfile? Inspect the first seven header lines as above and check the file is non-empty with test -s triangle.pam.

For a grayscale image, swap -rgb for -grayscale and give one value per attribs line. For a different sample range, pass -maxval=1023; every attribute must then be between 0 and 1023, and the output maxval changes to match.

6. Use depth and perspective deliberately

When triangles overlap, an incoming sample replaces the existing one when its interpolated depth is equal to or smaller than the stored depth. The frame starts with zero image samples and the maximum permitted depth, which makes smaller z values appear nearer, but it does not turn x and y into projected 3D coordinates on its own.

The optional fourth value on vertex is w, a perspective correction factor from 1 to 1048575. It defaults to 1 when omitted, giving ordinary linear interpolation for that triangle. If your coordinates came from a perspective projection, supply the appropriate positive integer w for every vertex of the triangle: do not invent it from z alone, calculate it as part of the projection that produced your screen coordinates.

For a quick depth check, put two overlapping triangles in the script and give the intended foreground triangle the smaller z. Keep the first result until you have inspected the replacement.

  • clear resets image and depth buffers, or accepts image or depth to clear only one.
  • reset also clears the image and pending vertices but deliberately leaves the depth buffer, so use clear when you need a genuinely fresh depth test.

7. Recover from common mistakes

  • Invocation rejected? Check that width and height are present and that exactly one of the three attribute choices is supplied. RGB needs three integers after every valid attribs command, grayscale needs one, and values outside the current maxval are invalid.
  • Output empty? Check that the script reached print and supplied three complete vertices; a mode switch discards incomplete pending vertices.
  • Colours attached to the wrong corners? Remember that attributes stay current until another valid attribs command changes them.
  • Redirection failed partway? Do not overwrite a known-good PAM file during diagnosis. Write to triangle.pam.new, verify it, then replace the old file with mv triangle.pam.new triangle.pam. To undo that, restore your backup or rename the previous file back; do not delete the only copy.

Done means

  • Checked pamtris and its Netpbm version.
  • Matching dimensions, attribute counts and maxval throughout the script.
  • Output header confirmed the expected PAM dimensions and planes.
  • Depth ordering and any w values were intentional, not guessed.
  • Any replacement output verified before an existing file was changed.