1Pamtris User Manual(0) Pamtris User Manual(0)
2
3
4
6 pamtris - triangle rasterizer featuring perspective-correct interpola‐
7 tion of generic vertex attributes and depth buffering
8
9
11 pamtris
12
13 -width=width
14
15 -height=height
16
17 { -num_attribs=attributes_per_vertex [ -tupletype=tupletype ] | -rgb |
18 -grayscale }
19
20 [ -maxval=maxval ]
21
22 All options can be abbreviated to their shortest unique prefix. You
23 may use two hyphens instead of one to designate an option. You may use
24 either white space or an equals sign between an option name and its
25 value.
26
27
29 This program is part of Netpbm(1).
30
31 pamtris can be used to draw a great variety of 2D and 3D graphics by
32 composing arbitrarily complex pictures out of separate triangles, tri‐
33 angle strips and triangle fans. The program reads instructions written
34 in a simple command script notation from Standard Input and outputs its
35 results as a (potentially multi-image) PAM stream on Standard Output.
36
37 For example, the following input
38
39
40 mode fan
41 attribs 0 128 0
42 vertex 0 0 1
43 attribs 0 0 128
44 vertex 200 0 1
45 attribs 50 20 103
46 vertex 190 61 1
47 attribs 100 40 78
48 vertex 161 117 1
49 attribs 150 60 53
50 vertex 117 161 1
51 attribs 200 80 28
52 vertex 61 190 1
53 attribs 250 100 3
54 vertex 0 200 1
55 print
56
57
58
59 produces this:
60
61 Example pamtris output for FAN mode
62
63
64 The input file gives triangle data by setting the appropriate drawing
65 mode, if necessary, and then providing a list of vertices. Each vertex
66 is also associated with a list of up to 20 "attributes," which are in‐
67 teger values between 0 and a given maxval. In the most common usage,
68 you use pamtris to draw a visual image and a vertex has three at‐
69 tributes, which are an RGB specification of a color. Such attribute
70 lists may be provided on a per-vertex basis.
71
72 Prior to effectively writing a PAM image to Standard Output, pamtris
73 first rasterizes it onto an internal frame buffer, which consists of an
74 "image buffer" and a "depth buffer." The image buffer consists of a se‐
75 quence of height rows containing a sequence of width tuples. There is
76 one sample for each vertex attribute in every tuple plus an opacity
77 (alpha) sample. Each tuple in the image buffer is also associated with
78 an integer depth in the depth buffer, which determines whether subse‐
79 quent drawing operations affect that particular tuple or not. This pro‐
80 vides a way of depth-sorting graphical objects which is adequate for
81 many purposes in 2D and 3D computer graphics. One prominent shortcoming
82 of such an approach to depth-sorting, however, is that it does not au‐
83 tomatically work with objects which are intended to appear "translu‐
84 cent," therefore requiring more elaborate strategies to incorporate
85 said objects into pictures generated using this technique.
86
87 The opacity sample is the last sample of the tuple. pamtris manipu‐
88 lates opacity internally and for any tuple it is always either 0 or the
89 maxval. The program does not provide the user direct control over the
90 alpha image plane.
91
92 pamtris rasterizes triangles by approximating their visible area as a
93 collection of tuples at particular positions in the frame buffer, and
94 to each sample of every such tuple it assigns a value which is a per‐
95 spective-correct interpolation between the values of the corresponding
96 attribute for each vertex of the triangle. Whenever a tuple within the
97 area of the frame buffer is produced, it is written to the correspond‐
98 ing position in the frame buffer if and only if it passes a depth test.
99 This test works as follows: the depth value of every incoming tuple
100 (which is itself an interpolation between the Z-coordinates of the ver‐
101 tices of the corresponding triangle) is compared against the value in
102 the corresponding position in the depth buffer. If the depth value of
103 the incoming tuple equals or is smaller than the depth value already
104 present in said position in the depth buffer, the following happens.
105
106
107
108 • Every sample i, where 0 ≤ i < num_attribs, of the tuple in
109 the corresponding position in the image buffer is set to equal
110 the value of the respective sample of the incoming tuple; and
111 the alpha sample (the last one) is updated to the maxval;
112
113
114 • The depth value in the corresponding position in the depth buf‐
115 fer is updated to a depth value directly proportional to that of
116 the incoming tuple.
117
118
119 Otherwise, that particular tuple effects no change at all in the frame
120 buffer.
121
122 The frame buffer is initially set so that all samples in every tuple of
123 the image buffer contain the value 0, and all entries in the depth buf‐
124 fer contain the maximum permitted depth value.
125
126 The attributes' values, and therefore the samples in the output PAM im‐
127 ages, have no fixed interpretation ascribed to them (except for the
128 last image plane, which is deliberately supposed to represent tuple
129 opacity information); one may ascribe any suitable meaning to them,
130 such as that of colors, texture coordinates, surface normals, light in‐
131 teraction characteristics, texture influence coefficients for multi-
132 texturing, etc.
133
134
135
137 Fan Mode
138 The following command generates the image from the fan mode example at
139 the top of the DESCRIPTION ⟨#description⟩ section. If the file
140 fan.tris contains that code, you could process it with:
141
142
143 $ pamtris -height=200 -width=200 -rgb <fan.tris >fan.pam
144
145
146
147 Strip Mode
148 The following is an example of strip mode:
149
150
151 mode strip
152 attribs 255 0 0 # red
153 vertex 0 200 1
154 vertex 50 0 1
155 attribs 0 0 0 # black
156 vertex 100 200 1
157 attribs 0 205 205 # cyan
158 vertex 150 0 1
159 attribs 0 0 255 # blue
160 vertex 200 200 1
161 vertex 250 0 1
162 print
163
164
165 Save the above code in a file named strip.tris (for instance) and
166 process it with:
167
168
169 $ pamtris -height=200 -width=200 -rgb <strip.tris >strip.pam
170
171
172 to yield:
173
174 Example pamtris output for STRIP mode
175
176
177 Triangle Mode
178 The following is an example of triangle mode:
179
180
181 # yellow square
182 mode strip
183 attrib 155 155 0
184 vertex 50 50 100
185 vertex 50 200 100
186 vertex 200 50 100
187 vertex 200 200 100
188
189 # blue triangle
190 mode triangles
191 attrib 0 205 205
192 vertex 20 125 70
193 attrib 0 0 140
194 vertex 230 70 120 # Change "120" and see what happens
195 vertex 230 180 120 #
196 print
197
198
199 Save the above code in a file named pierce.tris (for instance) and
200 process it with:
201
202
203 $ pamtris -height=200 -width=200 -rgb <pierce.tris >pierce.pam
204
205
206 to yield:
207
208 Example pamtris output for TRIANGLES mode
209
210
211
212 Meta-programming
213 The pamtris command language is much too rudimentary to be used di‐
214 rectly for any serious drawing; you will probably want to use a general
215 purpose programming language to generate a temporary pamtris command
216 file.
217
218 For example, the draw_polygon procedure in the C program below outputs
219 pamtris instructions to draw a regular polygon. It does this by gener‐
220 ating a number of vertex instructions tracing around the perimeter of
221 the corresponding circumscribed circle. (Note: The PAM image produced
222 by piping the output of the below program into pamtris was subsequently
223 downscaled through pamscale -linear -xscale 0.25 -yscale 0.25 to
224 achieve an anti-aliased ⟨#antialias⟩ effect.)
225
226 Regular Polygons
227
228 /* ----------------------- *
229 * width = 512 *
230 * height = 512 *
231 * num_attribs = 3 *
232 * tupletype = RGB_ALPHA *
233 * ----------------------- */
234
235 #include <math.h>
236 #include <stdio.h>
237 #include <stdlib.h>
238
239 #define PI 3.14159265358979323844
240
241 void draw_polygon
242 (int const center_x, int const center_y, int const radius, int const sides)
243 {
244 printf("mode fan\n"
245 "vertex %d %d 0\n", center_x, center_y);
246
247 for(int i = 0; i <= sides; i++)
248 {
249 int const x = round(center_x + radius * cos(i*2.0*PI / sides));
250 int const y = round(center_y - radius * sin(i*2.0*PI / sides));
251
252 printf("vertex %d %d 0\n", x, y);
253 }
254 }
255
256 int main(void)
257 {
258 puts("attribs 0 185 80"); /* color: green */
259 draw_polygon(300, 210, 150, 5); /* draws pentagon */
260
261 puts("attribs 255 15 240"); /* color: magenta */
262 draw_polygon(150, 320, 100, 7); /* draws heptagon */
263
264 puts("!");
265 }
266
267
269 In addition to the options common to all programs based on libnetpbm
270 (most notably -quiet, see
271 Common Options ⟨index.html#commonoptions⟩ ), pamtris recognizes the
272 following command line options:
273
274 <dl compact="compact">
275
276 -width=width
277 Sets the width of the internal frame buffer and, by extension,
278 of the output PAM images, given in number of columns. This must
279 be an integer in the closed range [1, 8192].
280
281 This option is mandatory.
282
283
284 -height=height
285 This is the height of the internal frame buffer and, by exten‐
286 sion, of the output PAM images, given in number of rows. This
287 must be an integer in the closed range [1, 8192].
288
289 This option is mandatory.
290
291
292 -num_attribs=attributes_per_vertex
293 This is the number of attributes per vertex. The depth of the
294 output PAM images equals this value plus one (to accomodate the
295 alpha plane). The argument must be an integer in the closed
296 range [1, 20].
297
298 The input instruction stream may override this with a reset com‐
299 mand.
300
301 You must specify exactly one of -num_attribs, -rgb, and
302 -grayscale.
303
304
305
306 -tupletype=tupletype
307 This is the tuple type for the output PAM images. The argument
308 is a string which may be no longer than 255 characters.
309
310 The input instruction stream may override this with a reset com‐
311 mand.
312
313 The default is a null string.
314
315 This option cannot be specified together with -rgb or
316 -grayscale.
317
318
319
320
321 -rgb This is a convenience option which simply serves as an alias for
322 -num_attribs=3 -tupletype=RGB_ALPHA. In other words, this option
323 is a quick way to specify that you are going to use pamtris to
324 draw RGB(_ALPHA) color images directly, and the three vertex at‐
325 tributes are the red, green and blue levels of the color associ‐
326 ated with the vertex, in that order.
327
328 The input instruction stream may override this with a reset com‐
329 mand.
330
331 You must specify exactly one of -num_attribs, -rgb, and
332 -grayscale.
333
334 This option was new in Netpbm 10.85 (December 2018).
335
336
337 -grayscale
338 Another convenience option, similar to -rgb; except this one is
339 an alias for -num_attribs=1 -tupletype=GRAYSCALE_ALPHA. The one
340 vertex attribute is the gray level associated with the vertex.
341
342 The input instruction stream may override this with a reset com‐
343 mand.
344
345 You must specify exactly one of -num_attribs, -rgb, and
346 -grayscale.
347
348 This option was new in Netpbm 10.85 (December 2018).
349
350
351 -maxval=maxval
352 Sets the maxval of the output PAM images, which is also the max‐
353 imum permitted value for each vertex attribute. This must be an
354 integer in the closed range [1, 65535].
355
356 The default value is 255.
357
358 The input instruction stream may override this with a reset com‐
359 mand.
360
361
362
363
365 The input for pamtris consists of a stream of text lines read from
366 Standard Input.
367
368 Empty lines or lines that contain only white space characters are
369 called blank lines and are ignored.
370
371 When a # occurs anywhere in a line, pamtris ignores it along with every
372 character after it. In other words, everything from the # until the end
373 of the line receives the same treatment as white space.
374
375 Lines which are not blank must contain a sequence of strings, called
376 tokens, separated by white space. The first such token must be one of
377 the commands recognized by pamtris, and all further tokens are inter‐
378 preted as the arguments for that command, if it takes any. When an in‐
379 sufficient number of arguments is provided for a command, the line is
380 considered invalid and is given the same treatment as a blank line. The
381 same happens when an out of range argument or one of a kind different
382 of what is expected is given (for example, when you give a string of
383 letters where a numerical value is expected), or when an unrecognized
384 command/argument is found. When a number of arguments greater than that
385 required for a particular command is provided, only the portion of the
386 line up to the last required argument is considered and any further to‐
387 kens are ignored.
388
389 pamtris is case-insensitive. That is, mode, MODE, mODe, etc. are all
390 treated the same way.
391
392 The commands recognized by pamtris are:
393
394
395 mode
396
397 attribs
398
399 vertex
400
401 print
402
403 clear
404
405 reset
406
407 quit
408
409
410 You may use a minimum unique abbreviation of a command name. You may
411 use an exclamation mark (!) in place of the print command name and an
412 asterisk (*) in place of clear.
413
414 The functions of the commands are as follows.
415
416
417
418 mode { triangles | strip | fan }
419
420 This makes pamtris enter a new drawing mode. The argument is a
421 word which specifies the mode to change to. Instead of a full
422 argument name, it is permissible to provide a minimum unique ab‐
423 breviation, which has the same effect. The drawing mode will re‐
424 main the same until the next mode command is given.
425
426 This command also resets the current vertex list, which is
427 (re)initialized to an empty state after the command is executed.
428 One may add new vertices to this list through successive invoca‐
429 tions of the vertex command (see below). You do not have to
430 worry about providing "too many" vertices, since the vertex list
431 is virtualized: pamtris maintains only the state pertaining to
432 three vertices at any one time. The current vertex list is ini‐
433 tially empty.
434
435 It is permissible to give pamtris a mode command which instructs
436 it to enter a drawing mode it is currently already in. One might
437 use this approach to reset the current vertex list without
438 changing the current drawing mode.
439
440 Regardless of the current drawing mode, the program immediately
441 rasterizes a new triangle into the frame buffer as soon as you
442 provide the necessary vertices for it through the current vertex
443 list. (If you reset the vertex list before giving all the ver‐
444 tices necessary to draw a new triangle, the program effectively
445 discards from the list any vertices that might have been pushed
446 into the vertex list up to that point without using them to draw
447 any new triangles.)
448
449 In the following descriptions of each drawing mode, triangles'
450 and vertices' indices (ordinal numbers) are 0-based.
451
452 The triangles argument instructs pamtris to enter the "TRIAN‐
453 GLES" drawing mode. While in this mode, a series of separate
454 triangles is constructed. Every three vertices pushed into the
455 current vertex list specify a new triangle. Formally, this
456 means that every Nth triangle is specified by vertices 3*N,
457 3*N + 1, and 3*N + 2. This is the default initial mode and is
458 therefore not required to be set explicitly before drawing any
459 triangles.
460
461 The strip argument instructs pamtris to enter the "STRIP" draw‐
462 ing mode. While in this mode, pamtris constructs a "triangle
463 strip." That is, the first three vertices pushed into the cur‐
464 rent vertex list specify the first triangle, and every new ver‐
465 tex pushed after that specifies, together with the previous two,
466 the next triangle. Formally, this means that every Nth triangle
467 is specified by vertices N, N + 1, and N + 2.
468
469 The fan argument instructs pamtris to enter the "FAN" drawing
470 mode. While in this mode, a so-called "triangle fan" is con‐
471 structed. That is, the first three vertices pushed into the
472 current vertex list specify the first triangle, and every new
473 vertex pushed after that specifies, together with the previous
474 vertex and the first one, the next triangle. Formally, this
475 means that every Nth triangle is specified by vertices 0, N + 1,
476 and N + 2.
477
478
479
480
481 attribs a<sub>0</sub> a<sub>1</sub>
482 a<sub>2</sub> ... a<sub>num_attribs - 1</sub>
483
484 This updates the current attribute values list. This command
485 takes as arguments a sequence of num_attribs integers which rep‐
486 resent the values of the attributes to be associated with the
487 next vertex. This sequence of values is the just mentioned "cur‐
488 rent attribute values list."
489
490 Each ith argument, where 0 ≤ i < num_attribs, indicates
491 the value to be assigned to the ith attribute of the current at‐
492 tribute values list. All arguments must be integer values in the
493 closed range [0, maxval]. If a number of arguments less than
494 the current value of num_attribs is given, the command is con‐
495 sidered invalid and is therefore ignored.
496
497 The current attribute values list remains unchanged until the
498 next valid attribs or reset command is given. The attribs com‐
499 mand allows one to change the values of each attribute individu‐
500 ally, while the reset command is not specifically designed for
501 that function, but it has the side effect of setting all values
502 in the current attribute values list to the maxval (see below).
503
504 All values in the current attribute values list are initially
505 set to the maxval.
506
507 <dt id="cmd_vertex">vertex x y z [w]
508
509 Adds a new vertex to the current vertex list (see the mode com‐
510 mand above), assigning the values of the arguments to its re‐
511 spective coordinates, and the values in the current attribute
512 values list (see the attribs command above) to the respective
513 entries in the attribute list associated with the vertex.
514
515 x, y and z must be integer values in the closed range [-32767,
516 32767]. x and y represent, respectively, the column and row of
517 the tuple which corresponds to the location of the vertex. Such
518 values may correspond to tuples outside the limits of the frame
519 buffer. The origin of the coordinate system is at the top-left
520 tuple of the frame buffer. The X-axis goes from left to right,
521 and the Y-axis from top to bottom. A negative value for x indi‐
522 cates a column that many tuples to the left of the leftmost col‐
523 umn of the frame buffer. Likewise, a negative value for y indi‐
524 cates a row that many tuples above the uppermost row of the
525 frame buffer. Observe that those coordinates correspond directly
526 to a particular point in the coordinate system delineated above,
527 regardless of whether you are trying to draw an image which is
528 supposed to look as if viewed "in perspective" or not; pamtris
529 does not "warp" the coordinates you give in any way. Therefore,
530 if you want to draw images in perspective, you must compute val‐
531 ues for x and y already projected into pamtris' coordinate sys‐
532 tem yourself, using an external perspective projection method,
533 prior to giving them to the program.
534
535 The z parameter represents the Z-coordinate of the vertex,
536 which is used to compute depth values for tuples within the ar‐
537 eas of rasterized triangles. Intuitively, smaller values for z
538 mean "closer to the viewer," and larger ones mean "farther away
539 from the viewer" (but remember: as said above, the x and y coor‐
540 dinates are not warped in any way, which implies that they are
541 not affected by z; neither by the next parameter, for that mat‐
542 ter).
543
544 Optionally, you may provide a w parameter which represents a
545 "perspective correction factor" used to properly interpolate
546 vertex attributes across the area of the corresponding triangle.
547 This must be an integer value in the closed range [1, 1048575].
548 If you don't provide a value for it, the default value of 1 is
549 used (hence, if you want to nullify the effects of perspective
550 correction on a triangle so the output samples are computed as
551 if just linearly interpolated, simply do not provide a value for
552 w for any vertex of the triangle). If, however, you intend to
553 draw 3D geometry in perspective, you must provide an appropriate
554 value for this parameter, otherwise the output images might look
555 very wrong. w was new in Netpbm 10.85 (December 2018).
556
557 Consider the
558 typical model ⟨https://en.wikipedia.org/wiki/Viewing_frustum⟩
559 of the so-called "viewing frustum" used to project vertices in
560 3D "world space" onto a planar "image space." If we adopt the
561 convention that a "z-plane" means any plane parallel to the
562 view-plane (a.k.a. picture plane, a.k.a. near plane), the value
563 of w for a vertex should then be the (smallest/euclidean/orthog‐
564 onal) distance in pixels between the projection reference point
565 (PRP, or "eye") and the z-plane containing the vertex. One way
566 to compute this value amounts to simply taking the dot product
567 between the 3D vector r and the 3D unit vector n, where r is the
568 vector which goes from the projection reference point (PRP, or
569 "eye") to the vertex, and n is a view-plane normal (VPN) of unit
570 length which points away from the PRP. In other words, this is
571 equal to the length of the orthogonal projection of r on the
572 line "determined" by n.
573
574 (Note: For any two 3D vectors a and b, with respective real
575 scalar components a<sub>x</sub>, a<sub>y</sub>, a<sub>z</sub>
576 and b<sub>x</sub>, b<sub>y</sub>, b<sub>z</sub>, the dot product
577 between a and b is simply
578 a<sub>x</sub>*b<sub>x</sub> + a<sub>y</sub>*b<sub>y</sub> + a<sub>z</sub>*b<sub>z</sub>.)
579
580
581
582 print
583
584 This writes a PAM image to Standard Output whose raster is a
585 copy of the current contents of the image buffer. The values of
586 the WIDTH and HEIGHT fields are the same as the width and
587 height, respectively, of the frame buffer, which were given on
588 the command line during program invocation. The MAXVAL field is
589 equal to the current maxval; the DEPTH field is equal to the
590 current value of num_attribs + 1; and the TUPLTYPE field is
591 equal to the current tupletype.
592
593 This command has no effect upon the current drawing state. E. g.
594 it does not modify the current drawing mode, the current vertex
595 list, etc.
596
597 One may issue an arbitrary number of print commands at different
598 positions in the input instruction sequence to produce a multi-
599 image PAM stream.
600
601
602 clear [ image | depth ]
603
604 Clears the frame buffer. That is, all samples in the image buf‐
605 fer are once again set to 0, and all entries in the depth buffer
606 are once again set to the maximum permitted depth value.
607
608 Optionally, one may provide an argument to only clear either the
609 image buffer or the depth buffer individually, while leaving the
610 other intact. With the image argument, only the image buffer is
611 cleared; with the depth argument, only the depth buffer is
612 cleared. Instead of full argument names, one may provide a mini‐
613 mum unique abbreviation, which has the same effect. The single
614 character z is also accepted as an alias for depth.
615
616 Like the print command, this command has no effect upon the cur‐
617 rent drawing state either.
618
619
620
621 reset maxval num_attribs [tupletype]
622
623 This updates the current maxval and number of attributes per
624 vertex (num_attribs), resetting the <u>image</u> buffer with a
625 new maxval and number of samples per tuple while at it. The pa‐
626 rameter maxval must be an integer in the closed range [1,
627 65535], and num_attribs must be an integer in the closed range
628 [1, 20].
629
630 Optionally, after the second argument, one may provide a string
631 to be assigned to the current tupletype. The string goes from
632 the first character after the second argument which is not white
633 space and continues until (and including) the last character be‐
634 fore the end of the line which is not white space. If a new tu‐
635 pletype is not provided, or the provided string is longer than
636 255 characters, the empty string is assigned to the current tu‐
637 pletype.
638
639 The side effects of running this command are
640
641
642
643 •
644
645 The new image buffer is completely cleared once the command is
646 executed.
647
648
649 •
650
651 All values in the current attribute values list are set to the
652 new maxval.
653
654
655 •
656
657 The current vertex list is reset.
658
659
660
661 However, it does not touch the depth buffer: it is left the same
662 way as it was found before the command. Also the drawing mode
663 remains the same (e. g. if pamtris was in FAN mode, it will con‐
664 tinue in that same mode, etc.).
665
666 If this command is given with an invalid value for maxval or
667 num_attribs, it is ignored and therefore none of the above side
668 effects apply, nor do the current maxval, num_attribs or tuple‐
669 type change at all.
670
671 It is permissible to give a value for maxval and num_attribs
672 equal to the current maxval and num_attribs, respectively, al‐
673 though the above side effects will still apply even in such
674 cases.
675
676 Since this command deals with memory allocation, it may fail to
677 execute successfully. If that happens, no lines of input will be
678 read anymore and pamtris will be terminated as if the quit com‐
679 mand was given.
680
681 quit
682
683 This terminates pamtris. It will not read any more lines of in‐
684 put after this command.
685
686
687
688
689
691 Texturing
692 It is possible to apply so-called "textures" to images produced with
693 pamtris by using a pair of vertex attributes as texture coordinates,
694 then using pamchannel(1) to select the appropriate channels in the out‐
695 put image(s), and finally processing the result through pamlookup(1),
696 providing the desired texture file as a "lookup table." If you are
697 drawing pictures in perspective, make sure to provide adequate values
698 for the w parameter to your vertex commands ( see above ⟨#cmd_vertex⟩ )
699 so that the resulting samples in the images produced by pamtris are
700 perspective-correct. You might want to consider using pnmtile(1) to
701 make textures which are inteded to be "repeated" along triangle meshes.
702
703 The animated GIF below is an example of what can be achieved using the
704 technique described above (Earth texture from nasa.gov
705 ⟨https://visibleearth.nasa.gov/view.php?id=73580⟩ ).
706
707 Rotating Earth
708
709
710 Anti-aliased edges
711 pamtris performs no anti-aliasing on triangle edges by itself. How‐
712 ever, it is possible to obtain anti-aliased images through a "super-
713 sampling" approach: draw your image(s) at a size larger than the de‐
714 sired final size, and then, when all postprocessing is done, downscale
715 the final image(s) to the desired size. Drawing images with twice the
716 desired width and height, then downscaling them to the intended size
717 while disregarding gamma (i.e. what pamscale -linear does) often pro‐
718 duces good enough results; but the larger the ratio "size of origi‐
719 nal image" / "size of downscaled image" , the better the quality of
720 the anti-aliasing effect.
721
722
724 pampick(1) pamchannel(1) pamstack(1) pamlookup(1) pamarith(1) pam‐
725 scale(1) pamdepth(1) pamexec(1) pam(1)
726
727
729 pamtris was new in Netpbm 10.84 (September 2018).
730
732 This manual page was generated by the Netpbm tool 'makeman' from HTML
733 source. The master documentation is at
734
735 http://netpbm.sourceforge.net/doc/pamtris.html
736
737netpbm documentation 15 April 2021 Pamtris User Manual(0)