| 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. |