blob: e6ef5357961948363c9defd5388a5ce723b3128e [file] [log] [blame]
Name
NV_fragment_program4
Name Strings
(none)
Contact
Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com)
Status
Shipping for GeForce 8 Series (November 2006)
Version
Last Modified Date: 05/26/09
NVIDIA Revision: 6
Number
335
Dependencies
OpenGL 1.1 is required.
NV_gpu_program4 is required. This extension is supported if
"GL_NV_gpu_program4" is found in the extension string.
ATI_draw_buffers and ARB_draw_buffers trivially affects the definition of
this specification.
ARB_fragment_program_shadow trivially affects the definition of this
specification.
NV_primitive_restart trivially affects the definition of this extension.
This extension is written against the OpenGL 2.0 specification.
Overview
This extension builds on the common assembly instruction set
infrastructure provided by NV_gpu_program4, adding fragment
program-specific features.
This extension provides interpolation modifiers to fragment program
attributes allowing programs to specify that specified attributes be
flat-shaded (constant over a primitive), centroid-sampled (multisample
rendering), or interpolated linearly in screen space. The set of input
and output bindings provided includes all bindings supported by
ARB_fragment_program. Additional input bindings are provided to determine
whether fragments were generated by front- or back-facing primitives
("fragment.facing"), to identify the individual primitive used to generate
the fragment ("primitive.id"), and to determine distances to user clip
planes ("fragment.clip[n]"). Additionally generic input attributes allow
a fragment program to receive a greater number of attributes from previous
pipeline stages than possible using only the pre-defined fixed-function
attributes.
By and large, programs written to ARB_fragment_program can be ported
directly by simply changing the program header from "!!ARBfp1.0" to
"!!NVfp4.0", and then modifying instructions to take advantage of the
expanded feature set. There are a small number of areas where this
extension is not a functional superset of previous fragment program
extensions, which are documented in the NV_gpu_program4 specification.
New Procedures and Functions
None.
New Tokens
None.
Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
Modify Section 2.X, GPU Programs
(insert after second paragraph)
Fragment Programs
Fragment programs are used to compute the transformed attributes of a
fragment, in lieu of the set of fixed-function operations described in
sections 3.8 through 3.10. Fragment programs are run on a single fragment
at a time, and the state of neighboring fragments is not explicitly
available. (In practice, fragment programs may be run on a block of
fragments, and neighboring fragments' attributes may be used for texture
LOD calculations or partial derivative approximation.) The inputs
available to a fragment program are the interpolated attributes of a
fragment, which include (among other things) window-space position,
primary and secondary colors, and texture coordinates. The results of the
program are one (or more) colors and possibly a new window Z coordinate.
A fragment program can not modify the (X,Y) location of the fragment.
Modify Section 2.X.2, Program Grammar
(replace third paragraph)
Fragment programs are required to begin with the header string
"!!NVfp4.0". This header string identifies the subsequent program body as
being a fragment program and indicates that it should be parsed according
to the base NV_gpu_program4 grammar plus the additions below. Program
string parsing begins with the character immediately following the header
string.
(add the following grammar rules to the NV_gpu_program4 base grammar)
<instruction> ::= <SpecialInstruction>
<varModifier> ::= <interpModifier>
<SpecialInstruction> ::= "KIL" <opModifiers> <killCond>
| "DDX" <opModifiers> <instResult> ","
<instOperandV>
| "DDY" <opModifiers> <instResult> ","
<instOperandV>
<killCond> ::= <instOperandV>
<interpModifier> ::= "FLAT"
| "CENTROID"
| "NOPERSPECTIVE"
<attribBasic> ::= <fragPrefix> "fogcoord"
| <fragPrefix> "position"
| <fragPrefix> "facing"
| <attribTexCoord> <optArrayMemAbs>
| <attribClip> <arrayMemAbs>
| <attribGeneric> <arrayMemAbs>
| "primitive" "." "id"
<attribColor> ::= <fragPrefix> "color"
<attribMulti> ::= <attribTexCoord> <arrayRange>
| <attribClip> <arrayRange>
| <attribGeneric> <arrayRange>
<attribTexCoord> ::= <fragPrefix> "texcoord"
<attribClip> ::= <fragPrefix> "clip"
<attribGeneric> ::= <fragPrefix> "attrib"
<fragPrefix> ::= "fragment" "."
<resultBasic> ::= <resPrefix> "color" <resultOptColorNum>
| <resPrefix> "depth"
<resultOptColorNum> ::= /* empty */
<resPrefix> ::= "result" "."
(add the following subsection to section 2.X.3.1, Program Variable Types)
Explicitly declared fragment program attribute variables may have one or
more interpolation modifiers that control how per-fragment values are
computed.
An attribute variable declared as "FLAT" will be flat-shaded. For such
variables, the value of the attribute will be constant over an entire
primitive and will taken from the provoking vertex of the primitive, as
described in Section 2.14.7. If "FLAT" is not specified, attributes will
be interpolated as described in Chapter 3, with the exception that
attribute variables bound to colors will still be flat-shaded if the shade
model (section 2.14.7) is FLAT. If an attribute variable declared as
"FLAT" corresponds to a texture coordinate replaced by a point sprite
(s,t) value (section 3.3.1), the value of the attribute is undefined.
An attribute variable declared as "CENTROID" will be interpolated using a
point on or inside the primitive, if possible, when doing multisample line
or polygon rasterization (sections 3.4.4 and 3.5.6). This method can
avoid artifacts during multisample rasterization when some samples of a
pixel are covered, but the sample location used is outside the primitive.
Note that when centroid sampling, the sample points used to generate
attribute values for adjacent pixels may not be evenly spaced, which can
lead to artifacts when evaluating partial derivatives or performing
texture LOD calculations needed for mipmapping. If "CENTROID" is not
specified, attributes may be sampled anywhere inside the pixel as
permitted by the specification, including at points outside the primitive.
An attribute variable declared as "NOPERSPECTIVE" will be interpolated
using a method that is linear in screen space, as described in equation
3.7 and the appoximation that follows equation 3.8. If "NOPERSPECTIVE" is
not specified, attributes must be interpolated with perspective
correction, as described in equations 3.6 and 3.8. When clipping lines or
polygons, an alternate method is used to compute the attributes of
vertices introduced by clipping when they are specified as "NOPERSPECTIVE"
(section 2.14.8).
Implicitly declared attribute variables (bindings used directly in a
program instruction) will inherit the interpolation modifiers of any
explicitly declared attribute variable using the same binding. If no such
variable exists, default interpolation modes will be used.
For fragments generated by point primitives, DrawPixels, and Bitmap,
interpolation modifiers have no effect.
Implementations are not required to support arithmetic interpolation of
integer values written by a previous pipeline stage. Integer fragment
program attribute variables must be flat-shaded; a program will fail to
load if it declares a variable with the "INT" or "UINT" data type
modifiers without the "FLAT" interpolation modifier.
There are several additional limitations on the use of interpolation
modifiers. A fragment program will fail to load:
* if an interpolation modifier is specified when declaring a
non-attribute variable,
* if the same interpolation modifier is specified more than once in a
single declaration (e.g., "CENTROID CENTROID ATTRIB"),
* if the "FLAT" modifier is used together with either "CENTROID" or
"NOPERSPECTIVE" in a single declaration,
* if any interpolation modifier is specified when declaring a variable
bound to a fragment's position, face direction, fog coordinate, or any
interpolated clip distance,
* if multiple attribute variables with different interpolation modifiers
are bound to the same fragment attribute, or
* if one variable is bound to the fragment's primary color and a second
variable with different interpolation modifiers is bound the the
fragment's secondary color.
(add the following subsection to section 2.X.3.2, Program Attribute
Variables)
Fragment program attribute variables describe the attributes of a fragment
produced during rasterization. The set of available bindings is
enumerated in Table X.X.
Most attributes correspond to per-vertex attributes that are interpolated
over a primitive; such attributes are subject to the interpolation
modifiers described in section 2.X.3.1. The fragment's position, facing,
and primitive IDs are the exceptions, and are generated specially during
rasterization. Since two-sided color selection occurs prior to
rasterization, there are no distinct "front" or "back" colors available to
fragment programs. A single set of colors is available, which corresponds
to interpolated front or back vertex colors.
If geometry programs are enabled, attributes will be obtained by
interpolating per-vertex outputs written by the geometry program. If
geometry programs are disabled, but vertex programs are enabled,
attributes will be obtained by interpolating per-vertex outputs written by
the vertex program. In either case, the fragment program attributes
should be read using the same component data type used to write the vertex
output attributes in the geometry or vertex program. The value of any
attribute corresponding to a vertex output not written by the geometry or
vertex program is undefined.
If neither geometry nor vertex programs are used, attributes will be
obtained by interpolating per-vertex values computed by fixed-function
vertex processing. All interpolated fragment attributes should be read as
floating-point values.
Fragment Attribute Binding Components Underlying State
-------------------------- ---------- ----------------------------
fragment.color (r,g,b,a) primary color
fragment.color.primary (r,g,b,a) primary color
fragment.color.secondary (r,g,b,a) secondary color
fragment.texcoord (s,t,r,q) texture coordinate, unit 0
fragment.texcoord[n] (s,t,r,q) texture coordinate, unit n
fragment.fogcoord (f,-,-,-) fog distance/coordinate
* fragment.clip[n] (c,-,-,-) interpolated clip distance n
fragment.attrib[n] (x,y,z,w) generic interpolant n
fragment.texcoord[n..o] (s,t,r,q) texture coordinates n thru o
* fragment.clip[n..o] (c,-,-,-) clip distances n thru o
fragment.attrib[n..o] (x,y,z,w) generic interpolants n thru o
* fragment.position (x,y,z,1/w) window position
* fragment.facing (f,-,-,-) fragment facing
* primitive.id (id,-,-,-) primitive number
Table X.X: Fragment Attribute Bindings. The "Components" column
indicates the mapping of the state in the "Underlying State" column.
Bindings containing "[n]" require an integer value of <n> to select an
individual item. Interpolation modifiers are not supported on variables
that use bindings labeled with "*".
If a fragment attribute binding matches "fragment.color" or
"fragment.color.primary", the "x", "y", "z", and "w" components of the
fragment attribute variable are filled with the "r", "g", "b", and "a"
components, respectively, of the fragment's primary color.
If a fragment attribute binding matches "fragment.color.secondary", the
"x", "y", "z", and "w" components of the fragment attribute variable are
filled with the "r", "g", "b", and "a" components, respectively, of the
fragment's secondary color.
If a fragment attribute binding matches "fragment.texcoord" or
"fragment.texcoord[n]", the "x", "y", "z", and "w" components of the
fragment attribute variable are filled with the "s", "t", "r", and "q"
components, respectively, of the fragment texture coordinates for texture
unit <n>. If "[n]" is omitted, texture unit zero is used.
If a fragment attribute binding matches "fragment.fogcoord", the "x"
component of the fragment attribute variable is filled with either the
fragment eye distance or the fog coordinate, depending on whether the fog
source is set to FRAGMENT_DEPTH_EXT or FOG_COORDINATE_EXT, respectively.
The "y", "z", and "w" coordinates are undefined.
If a fragment attribute binding matches "fragment.clip[n]", the "x"
component of the fragment attribute variable is filled with the
interpolated value of clip distance <n>, as written by the vertex or
geometry program. The "y", "z", and "w" components of the variable are
undefined. If fixed-function vertex processing or position-invariant
vertex programs are used with geometry programs disabled, clip distances
are obtained by interpolating the per-clip plane dot product:
(p_1' p_2' p_3' p_4') dot (x_e y_e z_e w_e),
for clip plane <n> as described in section 2.12. The clip distance for
clip plane <n> is undefined if clip plane <n> is disabled.
If a fragment attribute binding matches "fragment.attrib[n]", the "x",
"y", "z", and "w" components of the fragment attribute variable are filled
with the "x", "y", "z", and "w" components of generic interpolant <n>.
All generic interpolants will be undefined when used with fixed-function
vertex processing with no geometry program enabled.
If a fragment attribute binding matches "fragment.texcoord[n..o]",
"fragment.clip[n..o]", or "fragment.attrib[n..o]", a sequence of 1+<o>-<n>
bindings is created. For texture coordinate bindings, it is as though the
sequence "fragment.texcoord[n], fragment.texcoord[n+1],
... fragment.texcoord[o]" were specfied. These bindings are available
only in explicit declarations of array variables. A program will fail to
load if <n> is greater than <o>.
If a fragment attribute binding matches "fragment.position", the "x" and
"y" components of the fragment attribute variable are filled with the
floating-point (x,y) window coordinates of the fragment center, relative
to the lower left corner of the window. The "z" component is filled with
the fragment's z window coordinate. If z window coordinates are
represented internally by the GL as fixed-point values, the z window
coordinate undergoes an implied conversion to floating point. This
conversion must leave the values 0 and 1 invariant. The "w" component is
filled with the reciprocal of the fragment's clip w coordinate.
If a fragment attribute binding matches "fragment.facing", the "x"
component of the fragment attribute variable is filled with +1.0 or -1.0,
depending on the orientation of the primitive producing the fragment. If
the fragment is generated by a back-facing polygon (including point- and
line-mode polygons), the facing is -1.0; otherwise, the facing is +1.0.
The "y", "z", and "w" coordinates are undefined.
If a fragment attribute binding matches "primitive.id", the "x" component
of the fragment attribute variable is filled with a single integer. If a
geometry program is active, this value is obtained by taking the primitive
ID value emitted by the geometry program for the provoking vertex. If no
geometry program is active, the value is the number of primitives
processed by the rasterizer since the last time Begin was called (directly
or indirectly via vertex array functions). The first primitive generated
after a Begin is numbered zero, and the primitive ID counter is
incremented after every individual point, line, or polygon primitive is
processed. For polygons drawn in point or line mode, the primitive ID
counter is incremented only once, even though multiple points or lines may
be drawn. For QUADS and QUAD_STRIP primitives that are decomposed into
triangles, the primitive ID is incremented after each complete quad is
processed. For POLYGON primitives, the primitive ID counter is zero. The
primitive ID is zero for fragments generated by DrawPixels or Bitmap.
Restarting a primitive topology using the primitive restart index has no
effect on the primitive ID counter. The "y", "z", and "w" components of
the variable are always undefined.
(add the following subsection to section 2.X.3.5, Program Results.)
Fragment programs produce final fragment values, and the set of result
variables available to such programs correspond to the final attributes of
a fragment. Fragment program result variables may not be declared as
arrays.
The set of allowable result variable bindings is given in Table X.X.
Binding Components Description
----------------------------- ---------- ----------------------------
result.color (r,g,b,a) color
result.color[n] (r,g,b,a) color output n
result.depth (*,*,d,*) depth coordinate
Table X.X: Fragment Result Variable Bindings.
Components labeled "*" are unused.
If a result variable binding matches "result.color", updates to the "x",
"y", "z", and "w" components of the result variable modify the "r", "g",
"b", and "a" components, respectively, of the fragment's output color.
If a result variable binding matches "result.color[n]" and the
ARB_draw_buffers program option is specified, updates to the "x", "y",
"z", and "w" components of the color result variable modify the "r", "g",
"b", and "a" components, respectively, of the fragment output color
numbered <n>. If the ARB_draw_buffers program option is not specified,
the "result.color[n]" binding is unavailable.
If a result variable binding matches "result.depth", updates to the "z"
component of the result variable modify the fragment's output depth value.
If the "result.depth" binding is not in used in a variable written to by
any instruction in the fragment program, the interpolated depth value
produced by rasterization is used as if fragment program mode is not
enabled. Otherwise, the value written by the fragment program is used,
and the fragment's final depth value is undefined if the program did not
end up writing a depth value due to flow control or write masks. Writes
to any component of depth other than the "z" component have no effect.
(modify Table X.13 in section 2.X.4, Program Instructions, to include the
following.)
Modifiers
Instruction F I C S H D Inputs Out Description
----------- - - - - - - ---------- --- --------------------------------
DDX X - X X X F v v partial derivative relative to X
DDY X - X X X F v v partial derivative relative to Y
KIL X X - - X F vc - kill fragment
(add the following subsection to section 2.X.6, Program Options.)
Section 2.X.6.Y, Fragment Program Options
+ Fixed-Function Fog Emulation (ARB_fog_exp, ARB_fog_exp2, ARB_fog_linear)
If a fragment program specifies one of the options "ARB_fog_exp",
"ARB_fog_exp2", or "ARB_fog_linear", the program will apply fog to the
program's final color using a fog mode of EXP, EXP2, or LINEAR,
respectively, as described in section 3.10.
When a fog option is specified in a fragment program, semantic
restrictions are added to indicate that a fragment program will fail to
load if the number of temporaries it contains exceeds the
implementation-dependent limit minus 1, if the number of attributes it
contains exceeds the implementation-dependent limit minus 1, or if the
number of parameters it contains exceeds the implementation-dependent
limit minus 2.
Additionally, when the ARB_fog_exp option is specified in a fragment
program, a semantic restriction is added to indicate that a fragment
program will fail to load if the number of instructions or ALU
instructions it contains exceeds the implementation-dependent limit minus
3. When the ARB_fog_exp2 option is specified in a fragment program, a
semantic restriction is added to indicate that a fragment program will
fail to load if the number of instructions or ALU instructions it contains
exceeds the implementation-dependent limit minus 4. When the
ARB_fog_linear option is specified in a fragment program, a semantic
restriction is added to indicate that a fragment program will fail to load
if the number of instructions or ALU instructions it contains exceeds the
implementation-dependent limit minus 2.
Only one fog application option may be specified by any given fragment
program. A fragment program that specifies more than one of the program
options "ARB_fog_exp", "ARB_fog_exp2", and "ARB_fog_linear", will fail to
load.
+ Precision Hints (ARB_precision_hint_fastest, ARB_precision_hint_nicest)
Fragment program computations are carried out at an implementation-
dependent precision. However, some implementations may be able to perform
fragment program computations at more than one precision, and may be able
to trade off computation precision for performance.
If a fragment program specifies the "ARB_precision_hint_fastest" program
option, implementations should select precision to minimize program
execution time, with possibly reduced precision. If a fragment program
specifies the "ARB_precision_hint_nicest" program option, implementations
should maximize the precision, with possibly increased execution time.
Only one precision control option may be specified by any given fragment
program. A fragment program that specifies both the
"ARB_precision_hint_fastest" and "ARB_precision_hint_nicest" program
options will fail to load.
+ Multiple Color Outputs (ARB_draw_buffers, ATI_draw_buffers)
If a fragment program specifies the "ARB_draw_buffers" or
"ATI_draw_buffers" option, it will generate multiple output colors, and
the result binding "result.color[n]" is allowed, as described in section
2.X.3.5. If this option is not specified, a fragment program that
attempts to bind "result.color[n]" will fail to load, and only
"result.color" will be allowed.
The multiple color outputs will typically be written to an ordered list of
draw buffers in the manner described in the ARB_draw_buffers extension
specification.
+ Fragment Program Shadows (ARB_fragment_program_shadow)
The ARB_fragment_program_shadow option introduced a set of "SHADOW"
texture targets and made the results of depth texture lookups undefined
unless the texture format and compare mode were consistent with the target
provided in the fragment program instruction. This behavior is enabled by
default in NV_gpu_program4; specifying the option is not illegal but has
no additional effect.
(add the following subsection to section 2.X.7, Program Declarations.)
Section 2.X.7.Y, Fragment Program Declarations
No declarations are supported at present for fragment programs.
(add the following subsection to section 2.X.8, Program Instruction Set.)
Section 2.X.8.Z, DDX: Partial Derivative Relative to X
The DDX instruction computes approximate partial derivatives of the four
components of the single floating-point vector operand with respect to the
X window coordinate to yield a result vector. The partial derivatives are
evaluated at the sample location of the pixel.
f = VectorLoad(op0);
result = ComputePartialX(f);
Note that the partial derivates obtained by this instruction are
approximate, and derivative-of-derivate instruction sequences may not
yield accurate second derivatives. Note also that the sample locations
for attributes declared with the CENTROID interpolation modifier may not
be evenly spaced, which can lead to artifacts in derivative calculations.
DDX supports only floating-point data type modifiers and is available only
to fragment programs.
Section 2.X.8.Z, DDY: Partial Derivative Relative to Y
The DDY instruction computes approximate partial derivatives of the four
components of the single operand with respect to the Y window coordinate
to yield a result vector. The partial derivatives are evaluated at the
center of the pixel.
f = VectorLoad(op0);
result = ComputePartialY(f);
Note that the partial derivates obtained by this instruction are
approximate, and derivative-of-derivate instruction sequences may not
yield accurate second derivatives. Note also that the sample locations
for attributes declared with the CENTROID interpolation modifier may not
be evenly spaced, which can lead to artifacts in derivative calculations.
DDY supports only floating-point data type modifiers and is available only
to fragment programs.
Section 2.X.8.Z, KIL: Kill Fragment
The KIL instruction evaluates a condition and kills a fragment if the test
passes. A fragment killed by the KIL instruction is discarded, and will
not be seen by subsequent stages of the pipeline.
A KIL instruction may be specified using either a floating-point or
integer vector operand or a condition code test.
If a floating-point or integer vector is provided, the fragment is
discarded if any of its components are negative:
tmp = VectorLoad(op0);
if ((tmp.x < 0) || (tmp.y < 0) ||
(tmp.z < 0) || (tmp.w < 0))
{
exit;
}
Unsigned integer vector operands are permitted; however, KIL.U will have
no effect as no component is negative by definition.
If a condition code test is provided, the fragment is discarded if any
component of the test passes:
if (TestCC(rc.c***) || TestCC(rc.*c**) ||
TestCC(rc.**c*) || TestCC(rc.***c))
{
exit;
}
KIL supports all three data type modifiers.
KIL is available only to fragment programs.
Replace Section 2.14.8, and rename it to "Vertex Attribute Clipping"
(p. 70).
After lighting, clamping or masking and possible flatshading, vertex
attributes, including colors, texture and fog coordinates, shader varying
variables, and point sizes computed on a per vertex basis, are clipped.
Those attributes associated with a vertex that lies within the clip volume
are unaffected by clipping. If a primitive is clipped, however, the
attributes assigned to vertices produced by clipping are produced by
interpolating attributes along the clipped edge.
Let the attributes assigned to the two vertices P_1 and P_2 of an
unclipped edge be a_1 and a_2. The value of t (section 2.12) for a
clipped point P is used to obtain the attribute associated with P as
a = t * a_1 + (1-t) * a_2
unless the attribute is specified to be interpolated without perspective
correction in a fragment program. In that case, the attribute associated
with P is
a = t' * a_1 + (1-t') * a_2
where
t' = (t * w_1) / (t * w_1 + (1-t) * w_2)
and w_1 and w_2 are the w clip coordinates of P_1 and P_2,
respectively. If w_1 or w_2 is either zero or negative, the value of the
associated attribute is undefined.
Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
None
Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
None
Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
None
Additions to Chapter 6 of the OpenGL 2.0 Specification (State and
State Requests)
None
Additions to the AGL/GLX/WGL Specifications
None
Dependencies on ARB_draw_buffers and ATI_draw_buffers
If neither ARB_draw_buffers nor ATI_draw_buffers is supported, then the
discussion of the ARB_draw_buffers option in section 2.X.6.Y should be
removed, as well as the result bindings of the form "result.color[n]" and
"result.color[n..o]".
Dependencies on ARB_fragment_program_shadow
If ARB_fragment_program_shadow is not supported, then the discussion of
the ARB_fragment_program_shadow option in section 2.X.6.Y should be
removed.
Dependencies on NV_primitive_restart
The spec describes the behavior that primitive restart does not affect the
primitive ID counter, including for POLYGON primitives (where one could
argue that the restart index starts a new primitive without a new Begin to
reset the count. If NV_primitive_restart is not supported, references to
that extension in the discussion of the "primitive.id" attribute should be
removed.
Errors
None
New State
None
New Implementation Dependent State
None
Issues
(1) How should special interpolation controls be specified?
RESOLVED: As a special modifier to fragment program attribute variable
declarations. It was decided that the fragment program was the most
natural place to put the control. This wouldn't require making a large
number of related state changes controlling interpolation whenever the
fragment program used. The final mechanism using special interpolation
modifiers was chosen because it fit well with the other variable
modifiers (for data storage size and data type) provided by
NV_gpu_program4. Examples:
FLAT ATTRIB texcoords[4] = { fragment.texcoord[0..3] };
CENTROID ATTRIB texcoord4 = fragment.texcoord[4];
CENTROID NOPERSPECTIVE ATTRIB
attribs[3] = { fragment.attrib[0..2] };
There were a variety of options considered, including:
* special declarations in vertex or geometry programs to specify the
interpolation type,
* special declarations in the fragment program to specify one or more
interpolation type modifiers per binding, such as:
INTERPOLATE fragment.texcoord[0..3], FLAT;
INTERPOLATE fragment.texcoord[4], CENTROID;
INTERPOLATE fragment.attrib[0..2], CENTROID, NOPERSPECTIVE;
* fixed-function state specifying the interpolation mode
glInterpolateAttribNV(GL_TEXTURE0, GL_FLAT);
glInterpolateAttribNV(GL_GENERIC_ATTRIB0, GL_CENTROID_NV);
Recent updates to GLSL provide similar functionality (for centroid) with
a similar approach, using a modifier on varying variable declarations.
(2) How should perspective-incorrect interpolation (linear in screen
space) and clipping interact?
RESOLVED: Primitives with attributes specified to be
perspective-incorrect should be clipped so that the vertices introduced
by clipping should have attribute values consistent with the
interpolation mode. We do not want to have large color shifts
introduced by clipping a perspective-incorrect attribute. For example,
a primitive that approaches, but doesn't cross, a frustum clip plane
should look pretty much identical to a similar primitive that just
barely crosses the clip plane.
Clipping perspective-incorrect interpolants that cross the W==0 plane is
very challenging. The attribute clipping equation provided in the spec
effectively projects all the original vertices to screen space while
ignoring the X and Y frustum clip plane. As W approaches zero, the
projected X/Y window coordinates become extremely large. When clipping
an edge with one vertex inside the frustum and the other out near
infinity (after projection, due to W approaching zero), the interpolated
attribute for the entire visible portion of the edge should almost
exactly match the attribute value of the visible vertex.
If an outlying vertex approaches and then goes past W==0, it can be said
to go "to infinity and beyond" in screen space. The correct answer for
screen-linear interpolation is no longer obvious, at least to the author
of this specification. Rather than trying to figure out what the
"right" answer is or if one even exists, the results of clipping such
edges is specified as undefined.
(3) If a shader wants to use interpolation modifiers without using
declared variables, is that possible?
RESOLVED: Yes. If "dummy" variables are declared, all interpolants
bound to that variable will get the variable's interpolation modifiers.
In the following program:
FLAT ATTRIB tc02[3] = { fragment.texcoord[0..2] };
MOV R0, fragment.texcoord[1];
MOV R1, fragment.texcoord[3];
The variable R0 will get texture coordinate set 1, which will be
flat-shaded due to the declaration of "tc02". The variable R1 will get
texture coordinate set 3, which will be smooth shaded (default).
(4) Is it possible to read the same attribute with different interpolation
modifiers?
RESOLVED: No. A program that tries to do that will fail to compile.
(5) Why can't fragment program results be declared as arrays?
RESOLVED: This is a limitation of the programming model. If an
implementation needs to do run-time indexing of fragment program result
variables (effectively writing to "result.color[A0.x]"), code such as
the following can be used:
TEMP colors[4];
...
MOV colors[A0.x], R1;
MOV colors[3], 12.3;
...
# end of the program
MOV result.color[0], colors[0];
MOV result.color[1], colors[1];
MOV result.color[2], colors[2];
MOV result.color[3], colors[3];
(6) Do clip distances require that the corresponding clip planes be
enabled to be read by a fragment program?
RESOLVED: No.
(7) How do primitive IDs work with fragment programs?
RESOLVED: If a geometry program is enabled, the primitive ID is
consumed by the geometry program and is not automatically available to
the fragment program. If the fragment program needs a primitive ID in
this case, the geometry program can write out a primitive ID using the
"result.primid" binding, and the fragment program will see the primitive
ID written for the provoking vertex.
If no geometry program is enabled, the primitive ID is automatically
available, and specifies the number of primitives (points, lines, or
triangles) processed by since the last explicit or implicit Begin call.
(8) What is the primitive ID for non-geometry commands that generate
fragments, such as DrawPixels, Bitmap, and CopyPixels.
RESOLVED: Zero.
(9) How does the FLAT interpolation modifier interact with point sprite
coordinate replacement?
RESOLVED: The value of such attributes are undefined. Specifying these
two operations together is self-contradictory -- FLAT asks for an
interpolant that is constant over a primitive, and point sprite
coordinate interpolation asks for an interpolant that is non-constant
over a point sprite.
Revision History
Rev. Date Author Changes
---- -------- -------- --------------------------------------------
6 05/26/09 pbrown Fix documentation of KIL to support integer
operands, as indicated in the opcodes table
in NV_gpu_program4.
5 03/11/09 pbrown Fix section numbers for option/declaration
sections.
4 11/06/07 pbrown Documented interaction between the FLAT
interpolation modifier and point sprite
coordinate replacement.
1-3 pbrown Internal spec development.